#!/usr/bin/env python3 from itertools import combinations from operator import mul def candidates(sieve): n = len(sieve) for i in range(4, n, 4): sieve[i] = True for p in range(3, n, 2): if sieve[p]: continue for i in range(p**2, n, 2*p): sieve[i] = p for i in range(2*p**2, n, 2*p**2): sieve[i] = True if not sieve[p-1]: yield p-1 def is_prime(n): return not sieve[n] and n%2 def factors(n): r = [] while not n%2: r.append(2) n //= 2 while sieve[n] != False: r.append(sieve[n]) n //= sieve[n] return r + [n] def test_alt(n): fctrs = [f for f in factors(n)] for i in range(len(fctrs)//2): for c in combinations(fctrs, i+1): d = reduce(mul, c) if not is_prime(d + n//d): return False return True def test(n, fctrs, p=1, i=0, depth=1): if depth > len(fctrs) // 2: return True for j, f in enumerate(fctrs[i:]): if not is_prime(p*f + n//(p*f)) or not test(n, fctrs, p*f, j+1, depth+1): return False return True N = 10**8 + 2 sieve = [False] * N print(sum(c for c in candidates(sieve) if test(c, factors(c))) + 1)