Problem:
Score : 800 points

Problem Statement

You are given a polynomial of degree N with integer coefficients: f(x)=a_Nx^N+a_{N-1}x^{N-1}+...+a_0. Find all prime numbers p that divide f(x) for every integer x.

Constraints

0 \leq N \leq 10^4

|a_i| \leq 10^9(0\leq i\leq N)

a_N \neq 0

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
a_N
:
a_0

Output

Print all prime numbers p that divide f(x) for every integer x, in ascending order.

Sample Input 1

2
7
-7
14

Sample Output 1

2
7

2 and 7 divide, for example, f(1)=14 and f(2)=28.

Sample Input 2

3
1
4
1
5

Sample Output 2

There may be no integers that satisfy the condition.

Sample Input 3

0
998244353

Sample Output 3

998244353

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <bits/stdc++.h>
using i64 = long long;

i64 gcd(i64 a, i64 b) {
    if (b > a) std::swap(a, b);
    i64 m = a % b;
    return m ? gcd(b, m) : b;
}

auto sieve(i64 n) {
    std::vector<i64> ps, lp(n + 1);
    for (int i = 2; i <= n; i++) {
        if (!lp[i]) {
            lp[i] = i;
            ps.push_back(i);
        }
        for (int j = 0; j < ps.size() && ps[j] <= lp[i] && i * ps[j] <= n; j++) {
            lp[i * ps[j]] = ps[j];
        }
    }
    return ps;
}

bool poly_div(std::vector<i64> a, const i64 p) {
    int n = (int)a.size() - 1;
    for (int i = n; i - p + 1 >= 0; i--) {
        a[i % (p - 1)] = (a[i % (p - 1)] + a[i]) % p;
        a[i] = 0;
    }
    return std::all_of(a.begin(), a.end(), [](auto i) { return !i; });
}

int main() {
    int n;
    std::cin >> n;
    std::vector<i64> a(n + 1);
    std::set<i64> ret;
    for (int i = 0; i <= n; i++) std::cin >> a[i];
    i64 g = abs(a[0]);
    for (int i = 1; i <= n; i++) if (a[i]) g = gcd(abs(a[i]), g);

    for (i64 i = 2; i * i <= g; i++) {
        if (g % i) continue;
        ret.insert(i);
        while (g % i == 0) g /= i;
    }
    if (g > 1) ret.insert(g);

    auto ps = sieve(n);
    std::reverse(a.begin(), a.end());
    for (auto p : ps) if (poly_div(a, p)) ret.insert(p);

    for (auto p : ret) std::cout << p << std::endl;

    return 0;
}