Problem:
Score : 300 points

Problem Statement

There are N integers, A_1, A_2, ..., A_N, written on the blackboard.

You will choose one of them and replace it with an integer of your choice between 1 and 10^9 (inclusive), possibly the same as the integer originally written.

Find the maximum possible greatest common divisor of the N integers on the blackboard after your move.

Constraints

All values in input are integers.

2 \leq N \leq 10^5

1 \leq A_i \leq 10^9

Output

Input is given from Standard Input in the following format:

N
A_1 A_2 ... A_N

Output

Print the maximum possible greatest common divisor of the N integers on the blackboard after your move.

Sample Input 1

3
7 6 8

Sample Output 1

2

If we replace 7 with 4, the greatest common divisor of the three integers on the blackboard will be 2, which is the maximum possible value.

Sample Input 2

3
12 15 18

Sample Output 2

6

Sample Input 3

2
1000000000 1000000000

Sample Output 3

1000000000

We can replace an integer with itself.

Solution in Haskell (GHC 7.10.3) (judge verdict: Runtime Error)

module Main where
import           Control.Monad
import           Data.Bits
import Data.Maybe
import qualified Data.ByteString.Char8 as BS
import Data.Monoid
data SegmentTree m = Empty | SegmentTree {node :: m,left :: SegmentTree m,right :: SegmentTree m} deriving (Show)

build :: Monoid m => Int -> SegmentTree m
build 0    = Empty
build 1    = SegmentTree mempty Empty Empty
build size = SegmentTree mempty (build newSize) (build newSize)
    where newSize = (size + 1) `div` 2

depth :: SegmentTree m -> Int
depth Empty = 0
depth tree  = (depth $ left tree) + 1

update :: Monoid m => SegmentTree m -> m -> Int -> SegmentTree m
update tree@(SegmentTree _ Empty Empty) _ _ = tree
update tree@(SegmentTree n l r) value idx =
    update' tree value idx (2 ^ (depth tree - 1))

update' :: Monoid m => SegmentTree m -> m -> Int -> Int -> SegmentTree m
update' tree@(SegmentTree n l r) value idx size
    | size == 1
    = SegmentTree value Empty Empty
    | idx <= newSize
    = let newNode = node (update' l value idx newSize) `mappend` node r
      in  SegmentTree newNode (update' l value idx newSize) r
    | otherwise
    = let newNode = node l
              `mappend` node (update' r value (idx - newSize) newSize)
      in  SegmentTree newNode l (update' r value (idx - newSize) newSize)
    where newSize = size `div` 2


query :: Monoid m => SegmentTree m -> Int -> Int -> m --[a,b)に対しての演算の結果
query tree = query' tree size where size = 2 ^ (depth tree-1)

query' :: Monoid m => SegmentTree m -> Int -> Int -> Int -> m

query' tree@(SegmentTree n l r) size a b
    | a == b    = mempty
    | a == 0 && b == size  =   n
    | b <= newSize   =   query' l newSize a b
    | a >= newSize  =   query' r newSize (a-newSize) (b-newSize)
    | otherwise     =   (query' l newSize a newSize) `mappend` (query' r newSize 0 (b-newSize+1))
    where newSize = size `div` 2


get :: Monoid m => SegmentTree m -> Int -> m
get tree idx = query tree idx (idx + 1)

initial :: Monoid m => [m] -> SegmentTree m
initial list = init' list 1

init' :: Monoid m => [m] -> Int -> SegmentTree m
init' []       idx = build (idx - 1)
init' (m : ms) idx = update (init' ms (idx + 1)) m idx



newtype Gcd = Gcd Integer deriving (Show,Eq,Ord,Read)


instance Monoid Gcd where
    mempty = Gcd 0
    Gcd x `mappend` Gcd y = Gcd (gcd x y)

toI :: Gcd -> Integer
toI (Gcd x) = x

tuplify2 (x:y:_) = (x,y)
tuplify2 _ = undefined


readInt = fst . fromJust . BS.readInteger
readIntTuple = tuplify2 . map readInt . BS.words
readIntList = map readInt . BS.words

getInt = readInt <$> BS.getLine
getIntList = readIntList <$> BS.getLine
getIntNList n = map readIntList <$> replicateM (fromIntegral n) BS.getLine
getIntMatrix = map readIntList . BS.lines <$> BS.getContents
getIntTuple = readIntTuple <$> BS.getLine
getIntNTuples n = map readIntTuple <$> replicateM (fromIntegral n) BS.getLine
getIntTuples = map readIntTuple . BS.lines <$> BS.getContents

solve :: [Integer] -> Integer
solve a =
    let seg = initial (map Gcd a) :: SegmentTree Gcd
    in maximum $ map toI [(query seg 0 i) `mappend` (query seg (i+1) (length a)) | i <- [0..length a -1]]

main :: IO ()
main = do
    getLine
    a <- getIntList
    print (solve a)
--    let seg = initial (map Gcd a) :: SegmentTree Gcd
--    print . show $ map toI [(query seg 0 i) `mappend` (query seg (i+1) (length a)) | i <- [1..length a -2]]
--    let seg = initial $ map Gcd [2,4,5,8]
--    print . show $ query seg 1 2
    --print . show $ seg
    return()