func main() {
	pqrs := make([]int64, 12650) // Products of 4 distinct primes
	pos := 0
	for i := range iterutil.Subsets(25, 4) {
		pqrs[pos] = primes[i[0]] * primes[i[1]] * primes[i[2]] * primes[i[3]]
		pos++
	}
	sliceutil.SortInt64(pqrs)

	t0 := float64(time.Now().UnixNano()) / 1000000.0

	// Loop trough all numbers
	var maxNum int64 = 10000000
	var intervalSize int64 = 10000 // Must divide 10^6
	var numIntervals int64 = maxNum / intervalSize
	isPqrst := make([]bool, intervalSize)

	var intervalStart int64 = 0
	var intervalEnd int64 = intervalSize
	var numPqrst int64 = 0
	for i := int64(0); i < numIntervals; i++ {
		// Clear sieve for this range
		for j := int64(0); j < intervalSize; j++ {
			isPqrst[j] = false
		}

		// Fill sieve with multiples of pqrs
		for j := 0; j < len(pqrs); j++ {
			t0 := intervalStart / pqrs[j]
			t1 := intervalEnd/pqrs[j] + 1

			if t0 == 0 {
				t0 = 1
			}
			for t := t0; t < t1; t++ {
				pqrst := pqrs[j] * t
				if intervalStart <= pqrst && pqrst < intervalEnd {
					isPqrst[pqrst-intervalStart] = true
				}
			}
		}

		// Sum up the results for this interval
		for j := int64(0); j < intervalSize; j++ {
			if isPqrst[j] {
				numPqrst++
			}
		}

		intervalStart += intervalSize
		intervalEnd += intervalSize
	}

	t1 := float64(time.Now().UnixNano()) / 1000000.0
	fmt.Printf("time = %vms\n", t1-t0)
	fmt.Printf("N = %v\n", numPqrst)
}
func main() {
	p := []int64{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53,
		59, 61, 67, 71, 73, 79, 83, 89, 97}
	P := make([]int64, 12650)
	pqrs := make([][]int64, 12650)
	pos := 0
	for i := range iterutil.Subsets(25, 4) {
		P[pos] = p[i[0]] * p[i[1]] * p[i[2]] * p[i[3]]
		pqrs[pos] = make([]int64, 4)
		for j := 0; j < 4; j++ {
			pqrs[pos][j] = p[i[j]]
		}
		pos++
	}

	N := int64(1000)
	num := int64(0)
	for i := 0; i < len(P); i++ {
		fmt.Printf("%v%%\n", float32(i)/12650.0*100.0)
		num += (N - 1) / P[i]
		uniqueFactors := []int64{}
		//LCMoverflow := false
		for j := 0; j < i; j++ {
			fmt.Printf("j=%v\n", j)
			uniqueFactors := sliceutil.Union(uniqueFactors, pqrs[j])
			fmt.Printf("%v\n", uniqueFactors)
			LCM := sliceutil.ProductInt64(uniqueFactors)
			if num < 0 {
				panic("num wtf")
			}
			if LCM > 100000000000000000 || LCM < 0 {
				panic("LCM overflow")
			}
			num = num - ((N - 1) / LCM)
		}
	}
	fmt.Printf("habeeb it %v, %v\n", N, num)

}