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# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Collections.Generic;
class Program
    {
        static long f (int x, int[] a, int mod)
        {
            long ret = 0;
            long powX = 1;
            for (int i=0; i<a.Length; i++)
            {
                ret = (ret + (long)a[i] * (long)powX) % mod;
                powX = (powX * (long)x) % mod;
            }
            return ret;
        }
        static bool devideF (int[] a, int num)
        {
            long n = a[a.Length-1];
            for (int i=a.Length-1; i>0; i--)
            {
                n = a[i-1] + (long)n * num % 1000000007;
            }
            if (n == 0) return true;
            else return false;
        }
        static void Main(string[] args)
        {
            int n = int.Parse(Console.ReadLine());
            int[] a = new int[n+1];
            for (int i=n; i>=0; i--) a[i] = int.Parse(Console.ReadLine());
            int zeroPoint = 0;
            while (a[zeroPoint] == 0) zeroPoint++;
            List<int> prime = new List<int>();
            if (n == 0)
            {
                for (int i=2; i<10000; i++)
                {
                    bool isPrime = true;
                    foreach (int p in prime)
                    {
                        if (i % p == 0)
                        {
                            isPrime = false;
                            break;
                        }
                    }
                    if (isPrime && a[0] % i == 0)
                    {
                        while (a[0] % i == 0) {a[0] /= i;}
                        prime.Add(i);
                    }
                }
                if (Math.Abs(a[0]) > 1) prime.Add(Math.Abs(a[0]));
                foreach (int p in prime) Console.WriteLine(p);
                return;
            }

            int bigPrime = Math.Abs(a[zeroPoint]);

            for (int i=2; i<10000; i++)
            {
                bool isPrime = true;
                foreach (int p in prime)
                {
                    if (i % p == 0)
                    {
                        isPrime = false;
                        break;
                    }
                }
                if (isPrime && a[0] % i == 0) 
                {
                    prime.Add(i);
                    while (bigPrime % i == 0) bigPrime /= i;
                }
            }
            int mod = 1;
            List<int> ans = new List<int>();
            for (int i=1; prime.Count>0; i++)
            {
                //foreach (int p in prime) Console.Error.WriteLine(p + " " + i);
                if (devideF(a, i)) continue;
                int pCount = prime.Count;
                long num = -1;
                bool firstCheck = true;
                if (pCount < 20)
                {
                    firstCheck = false;
                    mod = 1;
                    foreach (int j in prime) mod *= j;
                    num = f (i, a, mod);
                }
                for (int j = 0; j < pCount; j++)
                {
                    int p = prime[j];
                    if (firstCheck) num = f (i, a, p);
                    if (num == -1) return;
                    //Console.Error.WriteLine(p + " " + i + " " + j + " " + pCount);
                    if (num % p != 0)
                    {
                        prime.Remove(p);
                        pCount--;
                        j--;
                    }
                    else if (i >= p - 1)
                    {
                        ans.Add(p);
                        prime.Remove(p);
                        pCount--;
                        j--;
                    }
                }
            }
            if (bigPrime > 10000)
            {
                bool bigPrimeIsAns = true;
                foreach (int num in a) if (num % bigPrime != 0) {bigPrimeIsAns = false; break;}
                if (bigPrimeIsAns) ans.Add(bigPrime);
            }
            if (ans.Count > 0) foreach (int p in ans) Console.WriteLine(p);
            
        }
    }
    //mcs Main.cs
    //mono Main.exe