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 namespace std;

#define int long long
#define ll long long
typedef pair<int, int> P;
#define mod 1000000007
#define INF (1LL<<60)

#define rep(i,n) for(int i=0, i##_len=(n); i<i##_len; ++i)
#define YES cout << "YES" << endl
#define Yes cout << "Yes" << endl
#define NO cout << "NO" << endl
#define No cout << "No" << endl


// aとbの最大公約数
ll gcd(ll a, ll b) {
	if (a < b) gcd(b, a);
	ll r;
	while ((r = a%b)) {
		a = b;
		b = r;
	}
	return b;
}

// nの素因子
set<int> prime(int n){
	set<int> ret;
	for (int p = 2; p*p <= n; p++){
		if (n%p == 0){
			ret.insert(p);
			while (n % p == 0) n /= p;
		}
	}
	if (n>1) ret.insert(n);
	return ret;
}

// 素数判定
bool isprime(int  n){
	if (n < 2) return false;
	else if (n == 2) return true;
	else if (n % 2 == 0) return false;
	else
		for (int i = 3; i*i <= n; i++)
			if (n%i == 0) return false;

	return true;
}

// n以下のエラトステネスのふるい
vector<bool> prime_table(int n){
	vector<bool> v(n + 1);

	for (int i = 0; i <= n; i++){
		v[i] = true;
	}
	v[0] = v[1] = false;
	for (int i = 2; i*i <= n; i++){
		if (isprime(i)){
			int j = 2 * i;
			while (j <= n){
				v[j] = false;
				j = j + i;
			}
		}
	}
	return v;
}

signed main(){

	int N;
	cin >> N;
	vector<int> a(N + 1);
	rep(i, N + 1) cin >> a[N - i];

	set<int> ans;

	// a[i]のgcdは自明
	int g = abs(a[N]);
	for (int i = 0; i < N; i++){
		if (a[i] != 0)
			g = gcd(g, abs(a[i]));
	}

	ans = prime(g);

	// あらかじめgcdで割っておく
	rep(i, N + 1) a[i] /= g;

//	vector<bool> era = prime_table(10001);

	// 候補についてチェック
	for (int p = 2; p <= 10001; p++){
		if (!isprime(p)) continue;
//		if (era[p] == false) continue;
		vector<int> c;
		c = a;
		for(int i=p-1; i<=N; i++)
			c[i % (p - 1)] += c[i];

		// すべてがpで割り切れるか
		bool found = true;
		rep(i, p-1){
			if (c[i] % p == 0) continue;
			else {
				found = false;
				break;
			}
		}
		if (found)
			ans.insert(p);
	}

	for (int p : ans){
		cout << p << endl;
	}

	return 0;
}