from tools import number_theory
from functools import reduce

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):
    return reduce(lambda x, y: x * (y[0] - 1) * y[0] ** (y[1] - 1), calc_factor(num, prime).items(), 1)

def search(limit):
    prime = list(number_theory.make_prime(int(limit ** 0.5) + 1))
    for x in range(2, limit + 1):
        if sorted(str(x)) == sorted(str(phi(x, prime))):
            print(x, calc_factor(x, prime))

print(search(100000))