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 <iostream>
#include <sstream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <string>
#include <algorithm>
#include <map>
#include <set>
#include <queue>

#define FOR(idx, begin, end) for(int idx = (int)(begin); idx < (int)(end); ++idx)

#ifdef _DEBUG
#define DMP(x) cerr << #x << ": " << x << "\n"
#else
#define DMP(x) ((void)0)
#endif

using namespace std;
typedef long long lint;

class Prime {
private:
	void Eratos(lint N) {
		for (lint i = 2; i * i < N; i++) {
			if (Ptb[i]) {
				for (int j = 0; i * (j + 2) < N; j++) {
					Ptb[i *(j + 2)] = 0;
				}
			}
		}
	}
public:
	vector<int> Ptb;
	
	Prime(lint N = 10000) :Ptb(N + 1, 1) { Eratos(N + 1); }
	
	vector<pair<lint,int>> Pfact(lint num) {
		vector<pair<lint, int>> res;
		for (lint i = 2; i * i <= num; i++) {
				int cnt = 0;
				while (num % i == 0) {
					cnt++;
					num /= i;
				}
				if(cnt) res.emplace_back(i, cnt);
		}
		if (num != 1) res.emplace_back(make_pair(num, 1));
		return res;
	}

	bool isPrime(lint num) {
		if (num < 2) return false;
		else if (num == 2 || num == 3) return true;
		else if (num % 2 == 0 || num % 3 == 0) return false;
		else if (num % 6 != 1 && num % 6 != 5) return false;
		for (lint i = 5; i * i <= num; i += 6) {
			if (num % i == 0) return false;
			if (num % (i + 2) == 0) return false;
		}
		return true;
	}
};

lint gcd(lint a, lint b) { return b ? gcd(b, a%b) : a; }

int main() {

	cin.tie(0);

	int N;
	cin >> N;

	vector<lint> a(N + 1);
	set<lint> ans;
	FOR(i, 0, N + 1) cin >> a[i];

	Prime p(10000);

	for (int prime = 2; prime < 10000; prime++) {

		if (p.Ptb[prime]) {

			vector<lint> mod(prime);
			bool flag = true;
			FOR(i, 0, N+1) mod[i % (prime - 1)] += a[i] % prime;
			
			FOR(i, 0, prime) if (mod[i]%prime) flag = false;

			if (flag) {
				ans.insert(prime);
			}
			//else {
			//	bool flag = true;
			//	FOR(j, 0, prime) {
			//		lint sum = 0;
			//		FOR(i, 0, N + 1) {
			//			sum += mod[i]
			//			//DMP(sum);
			//		}
			//		if (sum % prime != 0) {
			//			flag = false;
			//			break;
			//		}if (!flag) break;
			//	}
			//	if (flag) cout << prime << "\n";
			//}
		}
	}

	lint a_gcd = 0;
	FOR(i, 0, N + 1) a_gcd = gcd(a_gcd, abs(a[i]));

	auto pfac = p.Pfact(a_gcd);
	for (const auto &elem : pfac) ans.insert(elem.first);

	for (const auto& elem : ans) cout << elem << "\n" ;
	return 0;
}