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 OCaml (4.02.3) (judge verdict: Accepted)

open Printf open Scanf
open Array

let rec gcd m n = match m,n with | m,0 -> m | m,n -> gcd n (m mod n)

module SegTree_tmp = struct
  module type S = sig
    type t
    val  op: t -> t -> t
    val ide: t
    val upd: t -> t -> t
  end
  let par i = (i-1)/2
  let chl i = 2*i+1
  let chr i = 2*i+2
  module Make (X:S) = struct
    type t = SegTree of (X.t array * int)
    let raw (SegTree (a,_)) = a
    let make raw = (* O(n) *)
      let ln = Array.length raw in
      let n =
        let n = ref 1 in
        while !n<ln do n := !n*2 done; !n in
      let a = Array.make (2*n-1) X.ide in
      for i=0 to ln-1 do
        a.(i+n-1) <- raw.(i) done;
      for i=n-2 downto 0 do
        a.(i) <- X.op a.(chl i) a.(chr i) done;
      SegTree (a,n)
    let update_destructive (SegTree(a,n)) i v =
      let i = ref @@ i+(n-1) in
      a.(!i) <- X.upd a.(!i) v;
      while !i>0 do
        i := par !i;
        a.(!i) <- X.op a.(chl !i) a.(chr !i) done
    let get_half_open (SegTree(a,n)) l r = (* O(logn), [l,r) *)
      let rec f0 i p q =
        if q<=l || r<=p then X.ide
        else if l<=p && q<=r then a.(i)
        else
          let vl = f0 (2*i+1) p ((p+q)/2) in
          let vr = f0 (2*i+2) ((p+q)/2) q in
          X.op vl vr
      in f0 0 0 n
    let get_closed seg l r = get_half_open seg l (r+1) (* [l,r] *)
  end
end

module ST = SegTree_tmp.Make(struct
  type t = int
  let op = gcd
  let ide = 0
  let upd _prev nw = nw
end)

let () = scanf " %d" @@ fun n ->
  let a = init n (fun _ -> scanf " %d" @@ fun v -> v) in
  let t = ST.make a in
  mapi (fun i _ ->
    let l = if i=0 then 0 else ST.get_closed t 0 (i-1) in
    let r = if i=n-1 then 0 else ST.get_closed t (i+1) (n-1)
    in gcd l r
  ) a
  |> fold_left max 0
  |> print_int