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 Rust (1.42.0) (judge verdict: Accepted)

#[allow(unused_macros)]
macro_rules! read {
    ([$t:ty] ; $n:expr) =>
        ((0..$n).map(|_| read!([$t])).collect::<Vec<_>>());
    ($($t:ty),+ ; $n:expr) =>
        ((0..$n).map(|_| read!($($t),+)).collect::<Vec<_>>());
    ([$t:ty]) =>
        (rl().split_whitespace().map(|w| w.parse().unwrap()).collect::<Vec<$t>>());
    ($t:ty) =>
        (rl().parse::<$t>().unwrap());
    ($($t:ty),*) => {{
        let buf = rl();
        let mut w = buf.split_whitespace();
        ($(w.next().unwrap().parse::<$t>().unwrap()),*)
    }};
}

#[allow(dead_code)]
fn rl() -> String {
    let mut buf = String::new();
    std::io::stdin().read_line(&mut buf).unwrap();
    buf.trim_end().to_owned()
}

mod segtree {
    pub struct SegTree<T, F: Fn(T, T) -> T> {
        vec: Vec<T>,
        num_leaf: usize,
        fnc: F,
        id: T,
    }

    impl<T: Clone, F: Fn(T, T) -> T> SegTree<T, F> {
        pub fn new(n: usize, fnc: F, id: T) -> Self {
            let b_num = std::mem::size_of::<usize>() * 8;
            let lz = n.leading_zeros();
            let tz = n.trailing_zeros();

            let num_leaf = if lz + tz + 1 == b_num as u32 {
                n
            } else {
                1usize << (b_num - lz as usize)
            };
            let vec_size = (num_leaf << 1) - 1;

            Self {
                id: id.clone(),
                vec: vec![id; vec_size],
                num_leaf: num_leaf,
                fnc: fnc,
            }
        }

        pub fn update(&mut self, i: usize, val: T) {
            let mut idx = i + self.num_leaf - 1;
            self.vec[idx] = val;
            while idx > 0 {
                idx = (idx - 1) / 2;
                self.vec[idx] = (self.fnc)(
                    self.vec[idx*2+1].clone(),
                    self.vec[idx*2+2].clone()
                );
            }
        }

        pub fn query(&self, a: usize, b: usize) -> T {
            self.query_sub(a, b, 0, 0, self.num_leaf)
        }

        /// [a, b) の区間に対するクエリについて
        /// ノードk: 区間[l, r) 相当 が答える
        fn query_sub(&self, a: usize, b: usize, k: usize, l: usize, r: usize) -> T {
            if r <= a || b <= l {
                self.id.clone()
            } else if a <= l && r <= b {
                self.vec[k].clone()
            } else {
                let c1 = self.query_sub(a, b, 2*k+1, l, (l+r)/2);
                let c2 = self.query_sub(a, b, 2*k+2, (l+r)/2, r);
                (self.fnc)(c1, c2)
            }
        }
    }
}

use segtree::SegTree;

fn gcd(mut a: usize, mut b: usize) -> usize {
    std::mem::swap(&mut a, &mut b);
    while b != 0 {
        let r = a%b;
        a = b;
        b = r;
    }
    a
}

fn main() {
    let n = read!(usize);
    let a = read!([usize]);

    let mut st = SegTree::new(n, gcd, 0);
    for i in 0..n {
        st.update(i, a[i]);
    }
    let mut max = 0;
    for i in 0..=n {
        let tmp = gcd(st.query(0, i), st.query(i+1, n));
        if tmp > max {
            max = tmp;
        }
    }
    println!("{}", max);
}