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)

//第8回シンデレラガール総選挙は是非本田未央ちゃんに投票をお願いします！
//ファンのことも他のアイドルの子たちのことも本当に大事にしてて、今まで周りに色んなものを与えてくれました。
//今度は私たちが未央ちゃんにお返しをする番です。みんなでガラスの靴を履かせてあげましょう！
// #本田未央を一番星に #本田未央を令和のシンデレラガールに #第8回シンデレラガール総選挙
#include<vector>
#include<cmath>
#include<map>
#include<cstdlib>
#include<iostream>
#include<sstream>
#include<fstream>
#include<string>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<set>
#include<stack>
#include<bitset>
#include<functional>
#include<ctime>
#include<queue>
#include<deque>
#include<complex>
#include<cassert>
using namespace std;
#define pb push_back
#define pf push_front
typedef long long lint;
typedef complex<double> P;
#define mp make_pair
#define fi first
#define se second
typedef pair<int,int> pint;
#define All(s) s.begin(),s.end()
#define rAll(s) s.rbegin(),s.rend()
#define REP(i,a,b) for(int i=a;i<b;i++)
#define rep(i,n) REP(i,0,n)
//問題文および制約はちゃんと確認しよう！
//サイズは10^5じゃなくて2×10^5とかかもしれないし、重要な制約・条件を見落としているかも
//とりあえずサンプルを読んでから解法を考えよう？
lint gcd( lint m, lint n )
{
	int a=max(m,n),b=min(m,n);
	if(m==0) return n;if(n==0) return m;
	if(a%b==0) return b;
	return gcd(b,a-b*(a/b));
}
int n;
lint a[10100];
bool ng[4001000];
vector<lint> so;
bool ch(lint x,lint mo){
	//if(mo>1145141919 && mo<2) return false;
	if(mo<2) return false;
	lint now=0;
	for(int i=n;i>=0;i--){
		now=now*x+a[i];now%=mo;
	}
	//cout<<a[n]<<' '<<a[n-2]<<endl;
	//cout<<x<<' '<<mo<<' '<<now<<endl;
	return (now==0);
}
bool cal(lint ko){
	//cout<<ko<<endl;
	rep(i,70){
		lint x=rand()%ko;
		if(!ch(x,ko)) return false;
	}
	return true;
}
int main()
{
	cin>>n;
	for(int i=n;i>=0;i--) cin>>a[i];//cout<<a[0]<<a[1]<<a[2]<<a[3]<<endl;
	memset(ng,false,sizeof(ng));
	for(int i=2;i<4000100;i++){
		if(ng[i]) continue;
		so.pb(i);
		for(int j=i*2;j<4000100;j+=i) ng[j]=true;
	}
	lint sum=0;
	rep(i,n+1) sum=gcd(sum,abs(a[i]));
	//cout<<sum<<endl;
	vector<lint> ko;
	int f=0;
	rep(i,so.size()){
		if(sum%so[i]==0){
			f=1;
			if(so[i]*so[i]<sum) ko.pb(sum/so[i]);
			if(so[i]*so[i]<=sum) ko.pb(so[i]);
		}
	}
	if(f<1 && sum>1) ko.pb(sum);
	//rep(i,ko.size()) cout<<ko[i]<<endl;
	REP(i,2,n+10){
		if(!ng[i]) ko.pb(i);
	}
	//rep(i,ko.size()) cout<<ko[i]<<endl;
	sort(All(ko));ko.erase(unique(All(ko)),ko.end());
	//rep(i,ko.size()) cout<<ko[i]<<endl;
	rep(i,ko.size()){
		if(cal(ko[i])) cout<<ko[i]<<endl;
	}
}