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 Haskell (GHC 7.10.3) (judge verdict: Wrong Answer)

{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE ScopedTypeVariables #-}
import Control.Monad
import Data.Int
import Data.List
import qualified Data.ByteString.Char8 as BS
import qualified Data.Vector.Unboxed as U
import qualified Data.Vector.Unboxed.Mutable as UM

content :: U.Vector Int64 -> Int64
content v = loop 0 v
  where
    loop 1 _ = 1
    loop g v | U.null v = g
             | otherwise = loop (gcd (U.head v) g) (U.tail v)

infixr 5 !:
(!:) :: a -> [a] -> [a]
(!x) !: xs = x : xs

sieve :: Int -> [Int64]
sieve !max = 2 : U.ifoldr (\i isPrime xs -> if isPrime then fromIntegral (2 * i + 1) !: xs else xs) [] vec
  where
    vec = U.create $ do
      vec <- UM.replicate ((max - 1) `quot` 2 + 1) True
      UM.write vec 0 False -- 1 is not a prime
      -- vec ! i : is (2 * i + 1) prime?
      let clear !p = forM_ [3*p,5*p..max] $ \n -> UM.write vec (n `quot` 2) False
          factorBound = floor (sqrt (fromIntegral max) :: Double)
          loop !i | 2 * i + 1 > factorBound = return ()
                  | otherwise = do b <- UM.read vec i
                                   when b $ clear (2 * i + 1)
                                   loop (i + 1)
      loop 1
      return vec

-- |
-- >>> takeWhile (< 100) primes
-- [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97]
primes :: [Int64]
primes = sieve 31622
-- floor (sqrt (10^9+9)) == 31622
-- length primes == 3401

-- x <= 10^9+9
-- |
-- >>> factor 100
-- [(2,2),(5,2)]
-- >>> factor 144
-- [(2,4),(3,2)]
-- >>> factor (10^9+6)
-- [(2,1),(500000003,1)]
-- >>> factor (10^9+7)
-- [(1000000007,1)]
factor :: Int64 -> [(Int64, Int)]
factor 0 = error "factor 0"
factor x | x > 10^9+9 = error "factor: too large"
factor x = loop x primes
  where
    loop 1 _ = []
    loop x (p:ps) = case factorOut 0 x p of
                      (0,y) -> loop x ps
                      (n,y) -> (p,n) : loop y ps
    loop x [] = [(x,1)]
    factorOut !n !x !p | (q,0) <- x `quotRem` p = factorOut (n+1) q p
                       | otherwise = (n, x)

-- (p,q) = splitCoprime x y
-- p * q == x, gcd p q == 1, gcd p y == 1
-- |
-- >>> splitCoprime 72 2
-- (9,8)
-- >>> splitCoprime 72 3
-- (8,9)
splitCoprime :: Int64 -> Int64 -> (Int64, Int64)
splitCoprime !x !y = loop x 1
  where
    loop !p !q = case gcd p y of
                   1 -> (p, q)
                   p' -> loop (p `quot` p') (q * p')

removeTailZeroes :: U.Vector Int64 -> U.Vector Int64
removeTailZeroes v | U.null v = v
                   | U.last v == 0 = removeTailZeroes (U.init v)
                   | otherwise = v

reduceP :: Int -> U.Vector Int64 -> U.Vector Int64
reduceP !p v | U.length v <= p-1 = removeTailZeroes $ U.map (`mod` fromIntegral p) v
             | otherwise = let n = U.length v
                           in removeTailZeroes $ U.generate (p-1) $ \i -> sum [v U.! (i + (p-1) * j) | j <- [0..(n-1-i) `quot` (p-1)]] `mod` fromIntegral p

valueAtMod :: U.Vector Int64 -> Int64 -> Int -> Int64
valueAtMod coeffs !x !p = U.foldl' (\a b -> (a * x + b) `mod` fromIntegral p) 0 coeffs

valueAt :: U.Vector Int64 -> Int64 -> Integer
valueAt coeffs !x = U.foldl' (\a b -> a * fromIntegral x + fromIntegral b) 0 coeffs

test :: Int -> U.Vector Int64 -> Bool
test !p coeffs = let rr = reduceP p coeffs
                 in (U.head coeffs `mod` fromIntegral p == 0) && (U.null rr || all (\x -> valueAtMod rr x p == 0) [1..fromIntegral (p-1)])

choose :: Integer -> [Integer] -> Int64
choose !g _ | g /= 0 && g <= 10^9 = fromInteger g
choose g (x:xs) = choose (gcd g x) xs

dedup :: (Eq a) => [a] -> [a]
dedup [] = []
dedup (x:xs) = loop x xs
  where
    loop !x (y:ys) | x == y = loop x ys
                   | otherwise = x : loop y ys
    loop !x [] = [x]

main = do
  n <- readLn -- 10^4
  coeffs :: U.Vector Int64 <- U.reverse <$> U.replicateM (n+1) readLn
  let ct = content coeffs
      ps0 = map (fromIntegral . fst) $ factor (abs ct)
      coeffsPP = U.map (`div` ct) coeffs
  -- coeffs ! i <= 10^9
  let a = choose 0 $ filter (/= 0) $ fromIntegral (U.head coeffs) : concatMap (\i -> [valueAt coeffsPP i, valueAt coeffsPP (-i)]) [1..fromIntegral ((n+1) `div` 2)]
      ps = filter (flip test coeffsPP) $ map (fromIntegral . fst) $ factor (abs a)
  mapM_ print $ dedup $ sort (ps0 ++ ps)