use proconio::input;

// use my::algebra::structures::*;
// use my::algebra::Gcd;
// use my::ds::vec_segtree::*;

fn main() {
    input! {
        n: usize,
        a: [i32; n],
    }
    let a: VecSegtree<Gcd<i32>> = a.into();

    let mut res = 1;
    for i in 0..n {
        let cur = Gcd::<i32>::op(a.fold(..i), a.fold(i + 1..));
        if cur > res {
            res = cur;
        }
    }

    println!("{}", res);
}

// -------- Following codes are bundled automatically. -------- //

pub mod algebra {
    pub mod structures {
        pub trait Magma {
            type Set: Copy;
            fn op(lhs: Self::Set, rhs: Self::Set) -> Self::Set;
            fn op_assign(lhs: &mut Self::Set, rhs: Self::Set);
        }
        pub trait Semigroup: Magma {
            // Operation should be associative.
        }
        pub trait Monoid: Semigroup {
            fn id() -> Self::Set;
        }
        pub trait Group: Monoid {
            fn inv(x: Self::Set) -> Self::Set;
        }
        pub trait AbelianMonoid: Monoid {
            // Operation should be commutative.
        }
        pub trait AbelianGroup: Group {
            // Operation should be commutative.
        }
    }
    pub use structures::*;

    pub mod gcd {
        use std::marker::PhantomData;
        use std::mem;
        use std::ops::RemAssign;

        use num_traits::Zero;

        use crate::algebra::{AbelianMonoid, Magma, Monoid, Semigroup};

        fn gcd<T: Copy + RemAssign + Zero>(mut n: T, mut m: T) -> T {
            while !m.is_zero() {
                n %= m;
                mem::swap(&mut n, &mut m);
            }
            n
        }

        pub struct Gcd<T> {
            p_: PhantomData<T>,
        }

        impl<T: Copy + RemAssign + Zero> Magma for Gcd<T> {
            type Set = T;
            fn op(lhs: T, rhs: T) -> T {
                gcd(lhs, rhs)
            }
            fn op_assign(lhs: &mut T, rhs: T) {
                *lhs = Self::op(*lhs, rhs);
            }
        }
        impl<T: Copy + RemAssign + Zero> Semigroup for Gcd<T> {}
        impl<T: Copy + RemAssign + Zero> Monoid for Gcd<T> {
            fn id() -> T {
                T::zero()
            }
        }
        impl<T: Copy + RemAssign + Zero> AbelianMonoid for Gcd<T> {}
    }
    pub use gcd::*;
}

pub mod ds {
    pub mod range_query {
        pub trait Fold<R> {
            type Output;
            fn fold(&self, irange: R) -> Self::Output;
        }
    }
    pub use range_query::*;

    pub mod vec_segtree {
        use std::convert::From;
        use std::iter::FromIterator;
        use std::ops::{Range, RangeFrom, RangeFull, RangeTo};

        use crate::algebra::Monoid;
        #[doc(hidden)]
        pub use crate::ds::Fold;

        pub struct VecSegtree<M: Monoid> {
            buf: Vec<M::Set>,
            len: usize,
        }

        impl<M: Monoid> VecSegtree<M> {
            pub fn new(len: usize) -> Self {
                VecSegtree {
                    buf: vec![M::id(); len + len],
                    len: len + len,
                }
            }
        }
        impl<M: Monoid> Fold<Range<usize>> for VecSegtree<M> {
            type Output = M::Set;
            fn fold(&self, irange: Range<usize>) -> M::Set {
                let (mut l, mut r) = (irange.start, irange.end);
                let (mut resl, mut resr) = (M::id(), M::id());
                if r > self.len || l >= r {
                    return resl;
                }
                l += self.len;
                r += self.len;
                while l < r {
                    if l & 1 == 1 {
                        M::op_assign(&mut resl, self.buf[l]);
                        l += 1;
                    }
                    if r & 1 == 1 {
                        r -= 1;
                        resr = M::op(self.buf[r], resr);
                    }
                    l >>= 1;
                    r >>= 1;
                }
                M::op(resl, resr)
            }
        }
        impl<M: Monoid> Fold<RangeFull> for VecSegtree<M> {
            type Output = M::Set;
            fn fold(&self, _: RangeFull) -> M::Set {
                self.fold(0..self.len)
            }
        }
        impl<M: Monoid> Fold<RangeFrom<usize>> for VecSegtree<M> {
            type Output = M::Set;
            fn fold(&self, irange: RangeFrom<usize>) -> M::Set {
                self.fold(irange.start..self.len)
            }
        }
        impl<M: Monoid> Fold<RangeTo<usize>> for VecSegtree<M> {
            type Output = M::Set;
            fn fold(&self, irange: RangeTo<usize>) -> M::Set {
                self.fold(0..irange.end)
            }
        }
        impl<M: Monoid> From<Vec<M::Set>> for VecSegtree<M> {
            fn from(mut base: Vec<M::Set>) -> Self {
                let len = base.len();
                let mut buf = vec![M::id(); len];
                buf.append(&mut base);
                for i in (1..len).rev() {
                    buf[i] = M::op(buf[i << 1 | 0], buf[i << 1 | 1]);
                }
                VecSegtree { buf, len }
            }
        }
        impl<M: Monoid> FromIterator<M::Set> for VecSegtree<M> {
            fn from_iter<I: IntoIterator<Item = M::Set>>(iter: I) -> Self {
                Self::from(Vec::from_iter(iter))
            }
        }
    }
    pub use vec_segtree::*;
}

use crate::algebra::structures::*;
use crate::algebra::Gcd;
use crate::ds::vec_segtree::*;


Measured memory_bytes: 4120