#include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
#include <unordered_map>
using namespace std;

#define REP(i, s) for (int i = 0; i < s; ++i)
#define ALL(v) (v.begin(), v.end())
#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl
#define EACH(i, s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
template<class T1, class T2> ostream& operator << (ostream &s, pair<T1,T2> P)
{ return s << '<' << P.first << ", " << P.second << '>'; }
template<class T> ostream& operator << (ostream &s, vector<T> P)
{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }
template<class T> ostream& operator << (ostream &s, vector<vector<T> > P)
{ for (int i = 0; i < P.size(); ++i) { s << endl << P[i]; } return s << endl; }
template<class T> ostream& operator << (ostream &s, set<T> P)
{ EACH(it, P) { s << "<" << *it << "> "; } return s << endl; }
template<class T1, class T2> ostream& operator << (ostream &s, map<T1,T2> P)
{ EACH(it, P) { s << "<" << it->first << "->" << it->second << "> "; } return s << endl; }


long long N;
vector<long long> a;

vector<pair<long long, long long> > prime_factorize(long long n) {
    vector<pair<long long, long long> > res;
    for (long long p = 2; p * p <= n; ++p) {
        if (n % p != 0) continue;
        int num = 0;
        while (n % p == 0) { ++num; n /= p; }
        res.push_back(make_pair(p, num));
    }
    if (n != 1) res.push_back(make_pair(n, 1));
    return res;
}

long long func(long long x, long long p) {
    long long res = 0;
    for (int i = N; i >= 0; --i) {
        res *= x; res %= p;
        res += a[i] % p; res %= p;
    }
    if (res < 0) res += p;
    return res;
}



// Fp体上の多項式（MOD = P）
inline long long mod(long long a, long long m) {
    return (a % m + m) % m;
}

long long pow(long long a, long long n, long long m) {
    if (n == 0) return 1 % m;
    long long t = pow(a, n / 2, m);
    t = mod(t * t, m);
    if (n & 1) t = mod(t * a, m);
    return t;
}

long long inv(long long a, long long m) {
    long long b = m, u = 1, v = 0;
    while (b) {
        long long t = a / b;
        a -= t*b; swap(a, b);
        u -= t*v; swap(u, v);
    }
    return mod(u, m);
}

struct ModPolynomial : vector<long long> {
    long long MOD = 1000000007;                                              // to be set
    ModPolynomial() : vector<long long>(1, 0) { }
    ModPolynomial(long long num) : vector<long long>(1, num) { }
    ModPolynomial(int size, long long num) : vector<long long>(size, num) { }
    ModPolynomial(vector<long long> vec) { (*this) = vec; }
    
    void init(long long num) { *this = vector<long long>(1, num); }
    void init(int size, long long num) { *this = vector<long long>(size, num); }
    void init(vector<long long> vec) { *this = vec; }
    ModPolynomial& normalize() {
        for (int i = 0; i < (*this).size(); ++i) (*this)[i] = mod((*this)[i], MOD);
        while ((*this).size() > 1 && (*this).back() == 0) (*this).pop_back();
        return (*this);
    }
    
    inline ModPolynomial operator - () {
        for (int i = 0; i < (*this).size(); ++i) (*this)[i] = (*this)[i] * (-1);
        return (*this).normalize();
    }
    inline const ModPolynomial& operator += (const ModPolynomial &x);
    inline const ModPolynomial& operator -= (const ModPolynomial &x);
    inline const ModPolynomial& operator *= (long long x);
    inline const ModPolynomial& operator *= (const ModPolynomial &x);
    inline const ModPolynomial& operator /= (long long x);
    inline const ModPolynomial& operator /= (const ModPolynomial &x);
    inline const ModPolynomial& operator %= (long long x);
    inline const ModPolynomial& operator %= (const ModPolynomial &x);
};

inline bool operator > (ModPolynomial x, ModPolynomial y) { return x.size() > y.size(); }
inline bool operator < (ModPolynomial x, ModPolynomial y) { return y > x; }
inline bool operator <= (ModPolynomial x, ModPolynomial y) { return !(y < x); }
inline bool operator >= (ModPolynomial x, ModPolynomial y) { return !(x < y); }
inline bool operator != (ModPolynomial x, ModPolynomial y) { return x < y || y < x; }
inline bool operator == (ModPolynomial x, ModPolynomial y) { return !(x < y) && !(y < x); }

ostream &operator << (ostream &os, ModPolynomial x) {
    for (int i = (int)x.size() - 1; i >= 0; --i) {
        if (i != (int)x.size() - 1) os << abs(x[i]); else os << x[i];
        if (i != 0) {
            os << "x"; if (i != 1) os << "^" << i; os << " ";
            if (x[i - 1] < 0) os << "- "; else os << "+ ";
        }
    }
    return os;
}

inline ModPolynomial operator + (ModPolynomial x, ModPolynomial y) {
    x.normalize(); y.normalize();
    while (x.size() > y.size()) y.push_back(0);
    while (y.size() > x.size()) x.push_back(0);
    ModPolynomial z((int)x.size(), 0);
    z.MOD = x.MOD;
    for (int i = 0; i < (int)x.size(); ++i) z[i] = x[i] + y[i];
    return z.normalize();
}
inline ModPolynomial operator - (ModPolynomial x, ModPolynomial y) {
    y = -y;
    return x + y;
}
inline ModPolynomial operator * (ModPolynomial x, long long a) {
    x.normalize();
    ModPolynomial z((int)x.size(), 0);
    z.MOD = x.MOD;
    for (int i = 0; i < (int)x.size(); ++i) z[i] = mod(x[i] * a, x.MOD);
    return z.normalize();
}
inline ModPolynomial operator * (ModPolynomial x, ModPolynomial y) {
    x.normalize(); y.normalize();
    ModPolynomial z((int)x.size() + (int)y.size() - 1, 0);
    z.MOD = x.MOD;
    for (int i = 0; i < (int)x.size(); ++i) for (int j = 0; j < (int)y.size(); ++j) z[i + j] = mod(z[i + j] + x[i] * y[j], z.MOD);
    return z.normalize();
}
pair<ModPolynomial, long long> divmod(ModPolynomial x, long long a) {
    x.normalize();
    for (int i = (int)x.size() - 1; i >= 0; --i) x[i] = mod(x[i] * inv(a, x.MOD), x.MOD);
    return pair<ModPolynomial, long long>(x, 0);
}
ModPolynomial operator / (ModPolynomial x, long long a) {
    x.normalize();
    return divmod(x, a).first;
}
long long operator % (ModPolynomial x, long long a) {
    x.normalize();
    return divmod(x, a).second;
}
pair<ModPolynomial, ModPolynomial> divmod(ModPolynomial x, ModPolynomial y) {
    x.normalize(); y.normalize();
    if (x.size() < y.size()) return make_pair(0, x);
    if (y.size() == 1) return divmod(x, y.back());
    ModPolynomial q((int)x.size() - (int)y.size() + 1, 0);
    for (int i = (int)x.size() - 1; i >= (int)y.size() - 1; --i) {
        long long div = mod(x[i] * inv(y.back(), x.MOD), x.MOD);
        q[i - (int)y.size() + 1] = div;
        for (int j = 0; j < (int)y.size(); ++j) x[i + j - (int)y.size() + 1] = mod(x[i + j - (int)y.size() + 1] - y[j] * div, x.MOD);
    }
    return make_pair(q, x.normalize());
}
ModPolynomial operator / (ModPolynomial x, ModPolynomial y) {
    x.normalize(); y.normalize();
    return divmod(x, y).first;
}
ModPolynomial operator % (ModPolynomial x, ModPolynomial y) {
    x.normalize(); y.normalize();
    return divmod(x, y).second;
}
ModPolynomial pow(ModPolynomial a, long long n) {
    a.normalize();
    ModPolynomial res(1, 1);
    res.MOD = a.MOD;
    while (n > 0) { if (n & 1) { res = res * a; } a = a * a; n >>= 1; }
    return res;
}
ModPolynomial pow(ModPolynomial a, long long n, ModPolynomial PMOD) {
    a.normalize(); PMOD.normalize();
    ModPolynomial res(1, 1);
    res.MOD = a.MOD;
    while (n > 0) { if (n & 1) { res = (res * a) % PMOD; } a = (a * a) % PMOD; n >>= 1; }
    return res;
}
ModPolynomial gcd(ModPolynomial x, ModPolynomial y) {
    x.normalize(); y.normalize();
    if (y.size() == 1 && y.back() == 0) return x;
    else return gcd(y, x%y);
}
inline const ModPolynomial& ModPolynomial::operator += (const ModPolynomial &x) { *this = *this + x; return *this; }
inline const ModPolynomial& ModPolynomial::operator -= (const ModPolynomial &x) { *this = *this - x; return *this; }
inline const ModPolynomial& ModPolynomial::operator *= (long long x) { *this = *this * x; return *this; }
inline const ModPolynomial& ModPolynomial::operator *= (const ModPolynomial &x) { *this = *this * x; return *this; }
inline const ModPolynomial& ModPolynomial::operator /= (long long x) { *this = *this / x; return *this; }
inline const ModPolynomial& ModPolynomial::operator /= (const ModPolynomial &x) { *this = *this / x; return *this; }
inline const ModPolynomial& ModPolynomial::operator %= (long long x) { *this = *this % x; return *this; }
inline const ModPolynomial& ModPolynomial::operator %= (const ModPolynomial &x) { *this = *this % x; return *this; }


long long GCD(long long a, long long b) {
    if (b == 0) return a;
    else return GCD(b, a % b);
}


const int MAX = 10101;      // 素数判定する最大の数
bool IsPrime[MAX];
vector<int> Era(int n = MAX) {
    vector<int> res;
    IsPrime[0] = false; IsPrime[1] = false;
    for (int i = 2; i < n; ++i) IsPrime[i] = true;
    for (int i = 2; i < n; ++i) {
        if (IsPrime[i]) {
            res.push_back(i);
            for (int j = i*2; j < n; j += i) IsPrime[j] = false;
        }
    }
    return res;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    auto prs = Era();
    //COUT(prs);
    
    while (cin >> N) {
        a.resize(N+1);
        for (int i = 0; i < N+1; ++i) cin >> a[i];
        reverse(a.begin(), a.end());
        
        long long g = abs(a.back());
        for (int i = 0; i < N+1; ++i) g = GCD(g, abs(a[i]));
        auto pf = prime_factorize(g);

        set<long long> res;
        for (auto p : pf) res.insert(p.first);
        //for (int i = 0; i < N+1; ++i) a[i] /= g;
        
        if (func(0, 2) % 2 == 0 && func(1, 2) % 2 == 0) res.insert(2);
        //COUT(a);
        
        for (auto p : prs) {
            if (p == 2) continue;
            bool ok = true;
            
            vector<long long> c(p, 0);
            for (int d = 0; d < p; ++d) c[d] = mod(a[d], p);
            for (int d = p; d <= N; ++d) {
                int r = d % (p-1);
                if (r == 0) r = p-1;
                c[r] = mod(c[r] + mod(a[d], p), p);
            }
            
            for (int d = 0; d < p; ++d) {
                if (c[d] % p != 0) {
                    ok = false;
                }
            }
            
            if (ok) res.insert(p);
            
            if (p < 10) {
                //COUT(p);
                //COUT(c);
            }
            
            /*
            ModPolynomial f(N+1, 0);
            f.MOD = p;
            for (int i = 0; i < N+1; ++i) f[i] = a[i];
            f.normalize();
            ModPolynomial kensa(p+1, 0); // 多項式 x
            kensa.MOD = p;
            kensa[1] = -1;
            kensa[p] = 1;
            kensa.normalize();

            auto r = f % kensa;
             */
            
            /*
            cout << "----" << endl;
            COUT(p);
            COUT(f);
            COUT(kensa);
            COUT(r);
             */
            
                /*
            if (r.size() == 1 && r.back() == 0) {
                res.insert(p);
            }
                 */
        }
        
        
        
        for (auto p : res) {
            bool ok = true;
            if (p < 100) {
                //for (int i = 0; i < p; ++i) if (func(i, p) % p != 0) ok = false;
            }
            if (ok) cout << p << endl;
        }
    }
}














Measured memory_bytes: 512