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)

// デバッグ実行：Ctrl+F5

using System;
using System.Collections.Generic;

class Program
{
    static void Main(string[] args)
    {
        String line;
        line = Console.ReadLine();
        int N = int.Parse(line) + 1;
        int[] keisu = new int[N];
        int min_keisu = 1000000001;
        for(int i = 0; i < N; i++)
        {
            line = Console.ReadLine();
            keisu[i] = int.Parse(line);
            if (min_keisu > Math.Abs(keisu[i])) min_keisu = Math.Abs(keisu[i]);
        }
        int min = (int)Math.Sqrt(min_keisu) +1;
        //素数一覧表の作成
        List<int> sosu = new List<int>();
        sosu.Add(2);

        double sqrt;
        bool sosu_flag;
        for(int i = 3; i < min; i+=2)
        {
            sqrt = Math.Sqrt(i);
            sosu_flag = true;
            for(int j = 3; j < sqrt; j+=2)
            {
                if (i % j == 0)
                {
                    //素数でない
                    sosu_flag = false;
                    break;
                }
            }
            if (sosu_flag) sosu.Add(i);
        }
        sosu_flag = true;
        if (min_keisu % 2 == 0 || min_keisu < 2) sosu_flag = false;
        if (sosu_flag)
        {
            for (int j = 3; j < min_keisu; j += 2)
            {
                if (min_keisu % j == 0)
                {
                    //素数でない
                    sosu_flag = false;
                    break;
                }
            }
        }

        if (sosu_flag) sosu.Add(min_keisu);
        sosu_flag = true;
        int N_1 = N - 1;
        if (N_1 % 2 == 0 || N_1 < 2) sosu_flag = false;
        if (sosu_flag)
        {
            for (int j = 3; j < N_1; j += 2)
            {
                if (N_1 % j == 0)
                {
                    //素数でない
                    sosu_flag = false;
                    break;
                }
            }
        }
        if (sosu_flag) sosu.Add(N_1);
        //各素数で割ってみる
        bool OK;
        foreach(int i in sosu)
        {
            OK = true;
            for(int j = 0; j < N; j++)
            {
                if (keisu[j] % i != 0)
                {
                    OK = false;
                    break;
                }
            }
            if (N - 1 == i && keisu[N - 1] % i == 0) OK = true;

            if (OK)
            {
                Console.WriteLine(i);
            }
        }
    }
}