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)

#pragma GCC optimize(3)
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/priority_queue.hpp>
#define MAXN 10005
#define INF 1000000000
#define MOD 1000000007
#define F first
#define S second
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int,int> P;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;
typedef __gnu_pbds::priority_queue<int,greater<int>,pairing_heap_tag> pq;
int n,a[MAXN];
set<int> ans;
int prime[10*MAXN];
bool is_prime[10*MAXN];
int sieve(int n)
{
    memset(is_prime,true,sizeof(is_prime));
    is_prime[0]=is_prime[1]=false;
    int p=0;
    for(int i=2;i<=n;i++)
    {
        if(is_prime[i]) prime[p++]=i;
        for(int j=0;j<p;j++)
        {
            if(prime[j]*i>n) break;
            is_prime[prime[j]*i]=true;
            if(i%prime[j]==0) break;
        }
    }
    return p;
}
mt19937 wcy(time(NULL));
int main()
{
    int p=sieve(100000);
    scanf("%d",&n);
    for(int i=0;i<=n;i++) scanf("%d",&a[i]);
    reverse(a,a+n+1);
    int g=0;
    for(int i=0;i<=n;i++) g=__gcd(g,a[i]);
    g=abs(g);
    for(int i=0;i<p;i++) 
    {
        int cnt=0;
        while(g%prime[i]==0) g/=prime[i],cnt++;
        if(cnt) ans.insert(prime[i]);
    }
    if(g!=1) ans.insert(g);
    for(int i=0;i<p;i++)
    {
        if(prime[i]>n) break;
        bool f=true;
        for(int j=0;j<100;j++)
        {
            int x=wcy()%prime[i],res=1,sum=0;
            for(int k=0;k<=n;k++)
            {
                sum=(sum+a[k]*res)%prime[i];
                res=res*x%prime[i];
            }
            if(sum!=0) {f=false; break;}
        }
        if(f) ans.insert(prime[i]);
    }
    for(auto x:ans) printf("%d\n",x);
    return 0;
}