from tools import number_theory
from functools import reduce
import time

def update_factor(num, p, factor):
    count = 0
    while not num % p:
        num //= p
        count += 1
    if count:
        factor[p] = count
    return num

def calc_factor(num, prime):
    factor = {}
    for p in prime:
        if p ** 2 > num:
            break
        num = update_factor(num, p, factor)
    if num > 1:
        factor[num] = 1
    return factor

def phi(num, prime):
    ret = reduce(lambda x, y: x * (y[0] - 1) * y[0] ** (y[1] - 1), calc_factor(num, prime).items(), 1)
    return ret

def count(limit):
    prime = list(number_theory.make_prime(int(limit ** 0.5) + 1))
    return sum(map(lambda x: phi(x, prime), range(2, limit + 1)))

print(count(1000000))
print(time.process_time())