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 INF_LL (int64)1e18
#define INF (int32)1e9
#define REP(i, n) for(int64 i = 0;i < (n);i++)
#define FOR(i, a, b) for(int64 i = (a);i < (b);i++)
#define all(x) x.begin(),x.end()
#define fs first
#define sc second

using int32 = int_fast32_t;
using uint32 = uint_fast32_t;
using int64 = int_fast64_t;
using uint64 = uint_fast64_t;
using PII = pair<int32, int32>;
using PLL = pair<int64, int64>;

const double eps = 1e-10;

template<typename A, typename B>inline void chmin(A &a, B b){if(a > b) a = b;}
template<typename A, typename B>inline void chmax(A &a, B b){if(a < b) a = b;}

template<typename T>
vector<T> make_v(size_t a){return vector<T>(a);}

template<typename T,typename... Ts>
auto make_v(size_t a,Ts... ts){
  return vector<decltype(make_v<T>(ts...))>(a,make_v<T>(ts...));
}

template<typename T,typename U,typename... V>
typename enable_if<is_same<T, U>::value!=0>::type
fill_v(U &u,const V... v){u=U(v...);}

template<typename T,typename U,typename... V>
typename enable_if<is_same<T, U>::value==0>::type
fill_v(U &u,const V... v){
  for(auto &e:u) fill_v<T>(e,v...);
}

::std::int64_t gcd(::std::int64_t a, ::std::int64_t b) {
	while (b != 0) {
		::std::swap(a, b);
		b = b % a;
	}
	return a;
}

::std::vector<::std::int64_t> primes(::std::int64_t upper){
	::std::vector<::std::int64_t> res;
	for (::std::int64_t i = 2; i <= upper; ++i) {
		bool isPrime = true;
		for (auto x : res) {
			if (x * x > upper) break;
			if (i % x == 0) {
				isPrime = false;
				break;
			}
		}
		if (isPrime)
			res.push_back(i);
	}
	return res;
}



// return vector of prime factors of x
// O(sqrt x)
::std::vector<::std::pair<::std::int64_t, ::std::int32_t>> primeFactors(::std::int64_t x) {
	::std::vector<::std::pair<::std::int64_t, ::std::int32_t>> res;
	for (::std::int64_t i = 2; i*i <= x; ++i) {
		if (x % i == 0) {
			res.emplace_back(i, 1);
			x /= i;
			while (x % i == 0) x /= i, res.back().second++;
		}
	}
	if (x != 1) res.emplace_back(x, 1);
	return res;
}

bool isPrime(::std::int64_t x){
	if (x <= 1) return 0;
	for (::std::int64_t i = 2; i*i <= x; ++i) {
		if (x % i == 0) return false;
	}
	return true;
}

bool ok(int64 x, vector<int64>& v) {
	if (x == 1) return 0;
	REP(i, x-1) {
		int64 sum = 0;
		for (int64 j = i; j < v.size(); j += x-1) {
			sum += abs(v[j]);
		}
		if (sum % x) return false;
	}
	return (v[0] % x == 0);
}

int main(void){
	cin.tie(0);
	ios::sync_with_stdio(false);
	int64 N;
	cin >> N;
	vector<int64> a(N+1);
	REP(i, N+1) cin >> a[N-i];
	int64 g = 0;
	REP(i, N+1) g = gcd(abs(a[i]), g);
	auto pf = primeFactors(g);
	vector<int64> res;
	REP(i, pf.size()) {
		if (ok(pf[i].fs, a))
			res.push_back(pf[i].fs);
	}
	auto ps = primes(N);
	REP(i, ps.size()) {
		if (ok(ps[i], a))
			res.push_back(ps[i]);
	}
	sort(all(res));
	res.erase(unique(all(res)), res.end());
	REP(i, res.size()) {
		cout << res[i] << endl;
	}
}