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-----
3
7 6 8

-----Sample Output-----
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.

Difficulty: introductory

Starter code:

Solutions:
import sys
input = sys.stdin.readline # for speed up
#sys.setrecursionlimit(10**9)

n=int(input())
a=list(map(int,input().split()))

l=[0]*(n+2)
r=[0]*(n+2)
l[1]=a[0]
r[n]=a[n-1]
import math 
for ii in range(1,n):
  l[ii+1]=math.gcd(l[ii],a[ii])
  r[n-ii]=math.gcd(r[n-ii+1],a[n-1-ii])
#print(r)
#print(l)
ans=0
for ii in range(1,n+1):
  ans=max(ans,math.gcd(l[ii-1],r[ii+1]))
  #print(l[ii-1],r[ii+1])
print(ans)


import math

N = int(input())
A = list(map(int,input().split()))
gcd1 = [A[0]]
gcd2 = [A[N-1]]
ans_list = []

for i in range(1,N-1):
  gcd1.append(math.gcd(gcd1[-1],A[i]))
  gcd2.append(math.gcd(gcd2[-1],A[N-i-1]))

ans_list.append(gcd1[-1])
for j in range(N-2):
  ans_list.append(math.gcd(gcd1[j],gcd2[N-j-3]))
ans_list.append(gcd2[-1])

print(max(ans_list))

import math,string,itertools,fractions,heapq,collections,re,array,bisect,sys,random,time, copy,bisect
from operator import itemgetter
#from heapq import heappush, heappop
import numpy as np
from scipy.sparse.csgraph import shortest_path, floyd_warshall, dijkstra, bellman_ford, johnson
#from scipy.sparse import csr_matrix

sys.setrecursionlimit(10**7)
inf = 10**20
mod = 10**9 + 7

stdin = sys.stdin

ni = lambda: int(ns())
nf = lambda: float(ns())
na = lambda: list(map(int, stdin.readline().split()))
nb = lambda: list(map(float, stdin.readline().split()))
ns = lambda: stdin.readline().rstrip()  # ignore trailing spaces

N = ni()
A = na()
b = [0] * N
c = [0] * N
b[0] = A[0]
c[-1] = A[-1]
for i in range(N-1):
    b[i+1] = math.gcd(b[i], A[i+1])
    c[-(i+2)] = math.gcd(c[-(i+1)], A[-(i+2)])

ans = 1
ans = max(c[1], ans)
ans = max(b[-2], ans)
for i in range(1, N-1):
    ans = max(math.gcd(b[i-1], c[i+1]), ans)
print(ans)


from math import gcd
N = int(input())
A = list(map(int, input().split()))
B = [0 for i in range(N)]
C = [0 for i in range(N)]
B[0] = A[0]
C[0] = A[N - 1]
for i in range(1, N):
    B[i] = gcd(B[i - 1], A[i])
    C[i] = gcd(C[i - 1], A[N - i - 1])


ans = 0
for i in range(N):
    if i != 0 and i != N - 1:
        ans = max(ans, gcd(B[i - 1], C[N - i - 2]))
    elif i == 0:
        ans = max(ans, C[N - 2])
    else:
        ans = max(ans, B[N - 2])

print(ans)


from typing import Callable, Iterator, Optional, TypeVar

S = TypeVar("S")


class SegmentTree:
    """Segment Tree
    References:
        https://github.com/atcoder/ac-library/blob/master/atcoder/segtree.hpp
    """

    __slots__ = ["_e", "_op", "_n", "_size", "_tree"]

    def __init__(
        self,
        initial_values: Optional[Iterator[S]],
        n: int,
        e: S,
        op: Callable[[S, S], S],
    ) -> None:
        self._e = e
        self._op = op
        self._n = n
        self._size = 1 << (self._n - 1).bit_length()

        self._tree = [e] * 2 * self._size
        if initial_values is None:
            return

        for i, initial_values in enumerate(initial_values, self._size):
            self._tree[i] = initial_values
        for i in range(self._size - 1, 0, -1):
            self._update(i)

    def _update(self, k: int) -> None:
        """Update the value of a[k]."""
        self._tree[k] = self._op(self._tree[2 * k], self._tree[2 * k + 1])

    def set(self, k: int, x: S) -> None:
        """Assign x to a[k] in O(log n)."""
        assert 0 <= k < self._n

        k += self._size
        self._tree[k] = x
        while k:
            k >>= 1
            self._update(k)

    def get(self, k: int) -> S:
        """Return a[k] in O(1)."""
        assert 0 <= k < self._n
        return self._tree[k + self._size]

    def prod(self, l: int, r: int) -> S:
        """Return op(a[l], ..., a[r - 1]). Return e, if l == r.
        Complexity: O(log n)
        """
        assert 0 <= l <= r <= self._n

        sml, smr = self._e, self._e
        l += self._size
        r += self._size

        while l < r:
            if l & 1:
                sml = self._op(sml, self._tree[l])
                l += 1
            if r & 1:
                r -= 1
                smr = self._op(self._tree[r], smr)
            l >>= 1
            r >>= 1
        return self._op(sml, smr)

    def prod_all(self) -> S:
        """Return op(a[0], ..., a[n - 1]. Return e if n == 0.
        Complexity: O(1)
        """
        return self._tree[1]

    def max_right(self, l: int, f: Callable[[S], bool]) -> int:
        """
        Return an index r satisfying both:
            1. r = l or f(op(a[l], a[l + 1], ..., a[r - 1])) = true
            2. r = n or f(op(a[l], a[l + 1], ..., a[r])) = false.

        If f is monotone, this is the maximum r satisfying:
            f(op(a[l], a[l + 1], ..., a[r - 1])) = true.

        Complexity: O(log n)
        """
        assert 0 <= l <= self._n
        assert f(self._e)

        if l == self._n:
            return self._n

        l += self._size
        sm = self._e

        while True:
            while not l & 1:
                l >>= 1

            if not f(self._op(sm, self._tree[l])):
                while l < self._size:
                    l *= 2
                    if f(self._op(sm, self._tree[l])):
                        sm = self._op(sm, self._tree[l])
                        l += 1
                return l - self._size

            sm = self._op(sm, self._tree[l])
            l += 1

            if (l & -l) == l:
                break

        return self._n

    def min_left(self, r: int, f: Callable[[S], bool]) -> int:
        """
        Return an index l satisfying both:
            1. l = r or f(op(a[l], a[l + 1], ..., a[r - 1])) = true
            2. l = 0 or f(op(a[l - 1], a[l + 1], ..., a[r - 1])) = false.
        If f is monotone, this is the minimum l satisfying:
            f(op(a[l], a[l + 1], ..., a[r - 1])) = true.

        Complexity: O(log n)
        """
        assert 0 <= r <= self._n
        assert f(self._e)

        if not r:
            return 0

        r += self._size
        sm = self._e

        while True:
            r -= 1
            while r > 1 and r & 1:
                r >>= 1

            if not f(self._op(self._tree[r], sm)):
                while r < self._size:
                    r = 2 * r + 1
                    if f(self._op(self._tree[r], sm)):
                        sm = self._op(self._tree[r], sm)
                        r -= 1
                return r + 1 - self._size

            if (r & -r) == r:
                break

        return 0


def staticrmq():
    # https://judge.yosupo.jp/problem/staticrmq
    import sys

    read = sys.stdin.buffer.read
    readline = sys.stdin.buffer.readline

    N, _ = list(map(int, readline().split()))
    A = list(map(int, readline().split()))
    LR = list(map(int, read().split()))
    tree = SegmentTree(A, N, (10 ** 10) + 1, min)
    res = [tree.prod(l, r) for l, r in zip(*[iter(LR)] * 2)]
    print(("\n".join(map(str, res))))


def practice2_j():
    # https://atcoder.jp/contests/practice2/tasks/practice2_j
    import sys

    readline = sys.stdin.readline

    N, Q = list(map(int, readline().split()))
    A = list(map(int, readline().split()))
    tree = SegmentTree(A, N, -1, max)
    res = []
    for _ in range(Q):
        t, x, y = list(map(int, readline().split()))
        if t == 1:
            tree.set(x - 1, y)
        elif t == 2:
            res.append(tree.prod(x - 1, y))
        else:
            res.append(tree.max_right(x - 1, lambda n: n < y) + 1)
    print(("\n".join(map(str, res))))


def dsl_2_a():
    # https://onlinejudge.u-aizu.ac.jp/problems/DSL_2_A
    N, Q, *X = list(map(int, open(0).read().split()))
    tree = SegmentTree(None, N, 2 ** 31 - 1, min)
    res = []
    for com, x, y in zip(*[iter(X)] * 3):
        if com:
            res.append(tree.prod(x, y + 1))
        else:
            tree.set(x, y)
    print(("\n".join(map(str, res))))


def abc125_c():
    # https://atcoder.jp/contests/abc125/tasks/abc125_c
    from math import gcd

    N, *A = list(map(int, open(0).read().split()))
    tree = SegmentTree(A, N, 0, gcd)
    res = max(gcd(tree.prod(0, i), tree.prod(i + 1, N)) for i in range(N))
    print(res)


def __starting_point():
    # staticrmq()
    # practice2_j()
    # dsl_2_a()
    abc125_c()

__starting_point()

from math import gcd
from functools import reduce
 
def gcd_list(numbers):
    return reduce(gcd, numbers)

N = int(input())
A = list(map(int,input().split()))


X = [0]*N
Y = [0]*N
X[0] = A[0]
Y[-1] = A[-1]
ans = [0]*N
for i in range(1,N):
  X[i] = gcd(X[i-1],A[i])
  Y[N-i-1] = gcd(Y[N-i],A[N-i-1])
for i in range(1,N-1):
  ans[i] = gcd(X[i-1],Y[i+1])
ans[0],ans[-1] = gcd_list(A[1:]),gcd_list(A[:-1])
print(max(ans))

import math
import itertools

n = int(input())
a = list(map(int, input().split()))
pf = [0] + list(itertools.accumulate(a, math.gcd))
pb = [0] + list(itertools.accumulate(reversed(a), math.gcd))
pb.reverse()
ans = [0]*n
for i in range(n):
  ans[i] = math.gcd(pf[i], pb[i+1])
print(max(ans))

import sys
import math
from collections import defaultdict, deque, Counter
from copy import deepcopy
from bisect import bisect, bisect_right, bisect_left
from heapq import heapify, heappop, heappush
    
input = sys.stdin.readline
def RD(): return input().rstrip()
def F(): return float(input().rstrip())
def I(): return int(input().rstrip())
def MI(): return map(int, input().split())
def MF(): return map(float,input().split())
def LI(): return list(map(int, input().split()))
def TI(): return tuple(map(int, input().split()))
def LF(): return list(map(float,input().split()))
def Init(H, W, num): return [[num for i in range(W)] for j in range(H)]

gcd = math.gcd
def main():
    N = I()
    A = TI()
    past = math.gcd(A[0], A[1])
    D = {A[0],A[1]}
    for i in A[2:]:
        new_D = set()
        for j in D:
            new_D = new_D | {gcd(j, i)}
        new_D = new_D | {past}
        past = gcd(i, past)
        D = new_D
    
    print(max(D))
    
def __starting_point():
    main()
__starting_point()

import sys
import math
from collections import defaultdict, deque, Counter
from copy import deepcopy
from bisect import bisect, bisect_right, bisect_left
from heapq import heapify, heappop, heappush
    
input = sys.stdin.readline
def RD(): return input().rstrip()
def F(): return float(input().rstrip())
def I(): return int(input().rstrip())
def MI(): return map(int, input().split())
def MF(): return map(float,input().split())
def LI(): return list(map(int, input().split()))
def TI(): return tuple(map(int, input().split()))
def LF(): return list(map(float,input().split()))
def Init(H, W, num): return [[num for i in range(W)] for j in range(H)]

def main():
    N = I()
    A = LI()
    past = math.gcd(A[0], A[1])
    D = {A[0],A[1]}
    
    for i in A[2:]:
        new_D = set()
        for j in D:
            new_D = new_D | {math.gcd(j, i)}
        new_D = new_D | {past}
        past = math.gcd(i, past)
        D = new_D
    
    print(max(D))
    
def __starting_point():
    main()
__starting_point()

import math

N = int(input().rstrip())
A = list(map(int,input().rstrip().split()))
l = [A[0]]
r = [A[-1]]
for i in range(len(A)-1):
    l.append(math.gcd(A[i+1],l[i]))
    r.append(math.gcd(A[-(i+2)],r[i]))
ans = []
ans.append(r[-2])
for i in range(len(A)-2):
    ans.append(math.gcd(l[i],r[-(i+3)]))
ans.append(l[-2])
print(max(*ans))

import math
n=int(input())
a = list(map(int,input().split()))
a.sort()
lr=[0]*n
rl=[0]*n

for i in range(n):
  if i==0:
    g=a[0]
    lr[0]=g
  else:
    g=math.gcd(a[i],g)
    lr[i]=g
    
for i in range(n-1,0,-1):
  if n-1==i:
    g=a[n-1]
    rl[n-1]=g
  else:
    g=math.gcd(a[i],g)
    rl[i]=g  
hantei=0
ans=0
#print(lr)
#print(rl)
for i in range(n):
  if i==0:
    hantei=rl[1]
  elif i==n-1:
    hantei=lr[n-2]
  else:
    hantei=math.gcd(lr[i-1],rl[i+1])
  if ans<=hantei:
    ans=hantei
    
print(ans)

import math
n = int(input())
a = list(map(int, input().split()))
if n == 1:
    print(10 ** 9)
    return
l = [0] * n
r = [0] * n
l[0] = a[0]
r[-1] = a[-1]
for i in range(n-1):
    l[i+1] = math.gcd(a[i+1], l[i])
    r[-i-2] = math.gcd(a[-i-2], r[-i-1])
ans = max(l[-2], r[1])
for i in range(n-2):
    ans = max(ans, math.gcd(l[i], r[i+2]))
print(ans)

import math

n = int(input())
a = list(map(int,input().split()))
L = [0]*(n+1)
R = [0]*(n+1)
for i in range(n):
    L[i+1] = math.gcd(L[i], a[i])
    R[-2-i] = math.gcd(R[-1-i], a[-1-i])
    
ans = 0
for i in range(n):
    G = math.gcd(L[i], R[i+1])
    ans = max(ans, G)
print(ans)


def gcd(a, b):
    while b > 0:
        a, b = b, a % b
    return a


n = int(input())
a = list(map(int, input().strip().split()))

L = [0]
R = [0]
for i in range(n):
    L.append(gcd(L[i], a[i]))
    R.append(gcd(R[i], a[n-i-1]))

res = 0
for i in range(n):
    if res < gcd(L[i], R[n - i - 1]):
        res = gcd(L[i], R[n - i - 1])

print(res)


from typing import Callable, List, Optional, Union

T = Union[int, str]


class SegmentTree:
    """Segment Tree"""

    __slots__ = ["e", "op", "modifying_op", "_n", "_size", "tree"]

    def __init__(
        self,
        a: List[T],
        e: T,
        op: Callable[[T, T], T],
        modifying_op: Optional[Callable[[T], T]] = None,
    ) -> None:
        self.e = e
        self.op = op
        self.modifying_op = modifying_op
        self._n = len(a)
        self._size = 1 << (self._n - 1).bit_length()

        if modifying_op:
            a = list(map(modifying_op, a))
        self.tree = [e] * self._size + a + [e] * (self._size - self._n)
        for i in range(self._size - 1, 0, -1):
            self._update(i)

    def _update(self, k: int) -> None:
        """Update the value of a[k]."""
        self.tree[k] = self.op(self.tree[2 * k], self.tree[2 * k + 1])

    def set(self, k: int, x: T) -> None:
        """Assign x to a[k] in O(log n)."""
        assert 0 <= k < self._n

        k += self._size
        if self.modifying_op:
            x = self.modifying_op(x)
        self.tree[k] = x
        while k:
            k >>= 1
            self._update(k)

    def get(self, k: int) -> T:
        """Return a[k] in O(1)."""
        assert 0 <= k < self._n
        return self.tree[k + self._size]

    def prod(self, l: int, r: int) -> T:
        """Return op(a[l], ..., a[r - 1]). Return e, if l == r.
        Complexity: O(log n)
        """
        assert 0 <= l <= r <= self._n

        sml, smr = self.e, self.e
        l += self._size
        r += self._size

        while l < r:
            if l & 1:
                sml = self.op(sml, self.tree[l])
                l += 1
            if r & 1:
                r -= 1
                smr = self.op(self.tree[r], smr)
            l >>= 1
            r >>= 1
        return self.op(sml, smr)

    def prod_all(self) -> T:
        """Return op(a[0], ..., a[n - 1]. Return e if n == 0.
        Complexity: O(1)
        """
        return self.tree[1]

    def max_right(self, l: int, f: Callable[[T], bool]) -> int:
        """
        Return an index r satisfying both:
            1. r = l or f(op(a[l], a[l + 1], ..., a[r - 1])) = true
            2. r = n or f(op(a[l], a[l + 1], ..., a[r])) = false.

        If f is monotone, this is the maximum r satisfying:
            f(op(a[l], a[l + 1], ..., a[r - 1])) = true.

        Complexity: O(log n)
        """
        assert 0 <= l <= self._n
        assert f(self.e)

        if l == self._n:
            return self._n

        l += self._size
        sm = self.e

        while True:
            while not l & 1:
                l >>= 1

            if not f(self.op(sm, self.tree[l])):
                while l < self._size:
                    l *= 2
                    if f(self.op(sm, self.tree[l])):
                        sm = self.op(sm, self.tree[l])
                        l += 1
                return l - self._size

            sm = self.op(sm, self.tree[l])
            l += 1

            if (l & -l) == l:
                break

        return self._n

    def min_left(self, r: int, f: Callable[[T], bool]) -> int:
        """
        Return an index l satisfying both:
            1. l = r or f(op(a[l], a[l + 1], ..., a[r - 1])) = true
            2. l = 0 or f(op(a[l - 1], a[l + 1], ..., a[r - 1])) = false.
        If f is monotone, this is the minimum l satisfying:
            f(op(a[l], a[l + 1], ..., a[r - 1])) = true.

        Complexity: O(log n)
        """
        assert 0 <= r <= self._n
        assert f(self.e)

        if not r:
            return 0

        r += self._size
        sm = self.e

        while True:
            r -= 1
            while r > 1 and r % 2:
                r >>= 1

            if not f(self.op(self.tree[r], sm)):
                while r < self._size:
                    r = 2 * r + 1
                    if f(self.op(self.tree[r], sm)):
                        sm = self.op(self.tree[r], sm)
                        r -= 1
                return r + 1 - self._size

            if (r & -r) == r:
                break

        return 0


def practice2_j():
    # https://atcoder.jp/contests/practice2/tasks/practice2_j
    N, _, *AQ = list(map(int, open(0).read().split()))
    A, Q = AQ[:N], AQ[N:]
    tree = SegmentTree(A, -1, max)
    res = []
    for t, x, y in zip(*[iter(Q)] * 3):
        if t == 1:
            tree.set(x - 1, y)
        elif t == 2:
            res.append(tree.prod(x - 1, y))
        else:
            res.append(tree.max_right(x - 1, lambda n: n < y) + 1)
    print(("\n".join(map(str, res))))


def staticrmq():
    # https://judge.yosupo.jp/problem/staticrmq
    N, Q, *ALR = list(map(int, open(0).read().split()))
    A, LR = ALR[:N], ALR[N:]
    tree = SegmentTree(A, (10 ** 10) + 1, min)
    res = [tree.prod(l, r) for l, r in zip(*[iter(LR)] * 2)]
    print(("\n".join(map(str, res))))


def dsl_2_a():
    # https://onlinejudge.u-aizu.ac.jp/problems/DSL_2_A
    N, Q, *X = list(map(int, open(0).read().split()))
    tree = SegmentTree([2 ** 31 - 1] * N, 2 ** 31 - 1, min)
    res = []
    for com, x, y in zip(*[iter(X)] * 3):
        if com:
            res.append(tree.prod(x, y + 1))
        else:
            tree.set(x, y)
    print(("\n".join(map(str, res))))


def abc125_c():
    # https://atcoder.jp/contests/abc125/tasks/abc125_c
    from math import gcd

    N, *A = list(map(int, open(0).read().split()))
    tree = SegmentTree(A, 0, gcd)
    res = max(gcd(tree.prod(0, i), tree.prod(i + 1, N)) for i in range(N))
    print(res)


def __starting_point():
    # practice2_j()
    # staticrmq()
    # dsl_2_a()
    abc125_c()

__starting_point()

from math import gcd
n = int(input())
a = list(map(int,input().split()))
l,r = [a[0]]*n,[a[n-1]]*n
for i in range(1,n-1):
  l[i] = gcd(l[i-1],a[i])
  r[n-i-1] = gcd(r[n-i],a[n-i-1])
ans = [0]*n
ans[0] = r[1]
ans[n-1] = l[n-2]
for i in range(1,n-1):
  ans[i] = gcd(l[i-1],r[i+1])
print(max(ans))

import sys
from math import gcd
from itertools import accumulate

read = sys.stdin.read
readline = sys.stdin.readline
readlines = sys.stdin.readlines
sys.setrecursionlimit(10 ** 9)
INF = 1 << 60
MOD = 1000000007


def main():
    N, *A = list(map(int, read().split()))

    vec1 = [0] * (N + 1)
    vec2 = [0] * (N + 1)
    for i in range(N):
        vec1[i + 1] = gcd(vec1[i], A[i])
    for i in range(N - 1, -1, -1):
        vec2[i] = gcd(vec2[i + 1], A[i])

    ans = 0
    for i in range(N):
        g = gcd(vec1[i], vec2[i + 1])
        if ans < g:
            ans = g

    print(ans)
    return


def __starting_point():
    main()

__starting_point()

from math import gcd

N = int(input())
A = list(map(int,input().split()))

L,R = [0],[0]

for i in range(N-1):
    L += [gcd(L[i],A[i])]
    R += [gcd(R[i],A[-i-1])]

print((max(gcd(L[i],R[-i-1])for i in range(N))))



import math
n=int(input())
a=list(map(int, input().split()))
alist=[]
gcd1=a[0]
for i in range(0,n):
  gcd1=math.gcd(gcd1,a[i])
  alist.append(gcd1)
blist=[]
gcd2=a[n-1]
for i in range(n-1,-1,-1):
  gcd2=math.gcd(gcd2,a[i])
  blist.append(gcd2)
clist=[alist[n-2],blist[n-2]]
for i in range(n-2):
  clist.append(math.gcd(alist[i],blist[n-i-3]))
print(max(clist))

def main():
    def gcd(a, b):
        if b == 0:
            return a
        else:
            return gcd(b, a%b)

    n = int(input())
    a = [int(x) for x in input().split()]
    x = [0] * n
    y = [0] * n
    # x []   [0~1][0~2][0~3]...[0~n-1][0~n]
    # y [0~n][1~n][2~n][3~n]...[n]    []
    # yのrangeのとり方を工夫する
    for i in range(1,n):
        x[i] = gcd(x[i-1], a[i-1])
    for i in range(n-2, -1, -1):
        y[i] = gcd(y[i+1], a[i+1])
    ans = [gcd(x[i], y[i]) for i in range(n)]
    print(max(ans))

def __starting_point():
    main()
__starting_point()

import sys
input = sys.stdin.readline

def gcd(a, b):
    if b == 0:
        return a
    return gcd(b, a%b)

def main():
    N = int(input())
    A = list(map(int, input().split()))

    left = [A[0]] * (N+2)
    right = [A[-1]] * (N+2)

    for i in range(N):
        left[i+1] = gcd(left[i], A[i])
        right[N-i] = gcd(right[N-i+1], A[N-1-i])
    # print(left)
    # print(right)
    ans = max(left[-3], right[2])
    for i in range(1, N+1):
        ans = max(ans, gcd(left[i-1], right[i+1]))
    print(ans)

def __starting_point():
    main()
__starting_point()

#!/usr/bin/env python3

#import
import math
#import numpy as np
N = int(input())
A = list(map(int, input().split()))

class SegTree:
    def __init__(self, segfunc, e, v, init_val = None):
        """
        segfunc: function 区間にしたい操作\n
        e: Any 単位元\n
        v: int or List 要素数か格納する配列\n
        init_val: Any 初期値
        """
        self.segfunc = segfunc
        self.e = e
        self.init_val = init_val if init_val != None else e
        if isinstance(v, int):
            v = [self.init_val] * v
        self.n = len(v)
        self.log = (self.n).bit_length()
        self.size = 1 << self.log
        self.tree = [e] * 2 * self.size
        # 1-indexedなのでtree[1:self.size]がN-1要素
        # tree[self.size:self.size + N]が配列
        for i in range(self.n):
            self.tree[self.size + i] = v[i]
        for i in range(self.size - 1, 0, -1):
            self._update(i)

    def set(self, k, x) -> None:
        """
        k番目の値をxに更新\n
        k: index(0-indexed)\n
        x: update value
        """
        k += self.size
        self.tree[k] = x
        for i in range(1, self.log + 1):
            self._update(k >> i)

    def get(self, k):
        """
        a[k]を返す\n
        k: index(0-indexed)
        """
        assert 0 <= k < self.size
        return self.tree[k + self.size]

    def query(self, l, r):
        """
        [l, r)のsegfuncしたものを得る\n
        l: index(0-indexed)\n
        r: index(0-indexed)
        """
        res = self.e
        l += self.size
        r += self.size
        while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
        return res

    def all_query(self):
        """
        全範囲にsegfuncしたものを得る
        """
        return self.tree[1]

    # 二分探索実装、いる？

    def _update(self, k):
        self.tree[k] = self.segfunc(self.tree[k * 2], self.tree[k * 2 + 1])

seg = SegTree(math.gcd, 0, A)

ans = 0

for i in range(N):
    ans = max(ans, math.gcd(seg.query(0, i), seg.query(i + 1, N)))

print(ans)


import sys
import math
from collections import defaultdict, deque, Counter
from copy import deepcopy
from bisect import bisect, bisect_right, bisect_left
from heapq import heapify, heappop, heappush
    
input = sys.stdin.readline
def RD(): return input().rstrip()
def F(): return float(input().rstrip())
def I(): return int(input().rstrip())
def MI(): return map(int, input().split())
def MF(): return map(float,input().split())
def LI(): return list(map(int, input().split()))
def TI(): return tuple(map(int, input().split()))
def LF(): return list(map(float,input().split()))
def Init(H, W, num): return [[num for i in range(W)] for j in range(H)]

def main():
    N = I()
    A = TI()
    past = math.gcd(A[0], A[1])
    D = {A[0],A[1]}
    for i in A[2:]:
        new_D = set()
        for j in D:
            new_D = new_D | {math.gcd(j, i)}
        new_D = new_D | {past}
        past = math.gcd(i, past)
        D = new_D
    
    print(max(D))
    
def __starting_point():
    main()
__starting_point()

from math import*
N=int(input())
*A,=map(int,input().split())
R=[0]*(N+1)
for i in range(N):
    R[-i-2]=gcd(R[-i-1],A[-i-1])
L=0
M=1
for i in range(N):
    M=max(M,(gcd(L,R[i+1])))
    L=gcd(L,A[i])
print(M)

import math
import itertools

n = int(input())
a = list(map(int, input().split()))
pf = [0]*(n+1)
pb = [0]*(n+1)
p = a[0]
for i in range(n):
  p = math.gcd(p, a[i])
  pf[i+1] = p
p = a[-1]
for i in range(-1, -n-1, -1):
  p = math.gcd(p, a[i])
  pb[i-1] = p
ans = [0]*n
for i in range(n):
  ans[i] = math.gcd(pf[i], pb[i+1])
print(max(ans))

import math

def main():
	N = int(input())
	A = [int(a) for a in input().split(" ")]
	gcd1 = []
	gcd2 = []
	for i in range(len(A)):
		if i == 0:
			gcd1.append(A[0])
			gcd2.append(A[-1])
		else:
			gcd1.append(math.gcd(A[i], gcd1[-1]))
			gcd2.insert(0, math.gcd(A[-i-1], gcd2[0]))

	gcds = []
	for i in range(N):
		if i == 0:
			gcds.append(gcd2[1])
		elif i == N - 1:
			gcds.append(gcd1[-2])
		else:
			gcds.append(math.gcd(gcd1[i-1], gcd2[-N+i+1]))
	print((max(gcds)))

main()


from math import gcd
n = int(input())
alst = list(map(int, input().split()))
l_gcd = [alst[0]]
for num in alst[1:-1]:
    l_gcd.append(gcd(l_gcd[-1], num))

r_gcd = [alst[-1]]
for num in alst[1:-1][::-1]:
    r_gcd.append(gcd(r_gcd[-1], num))
r_gcd = r_gcd[::-1]
ans = max(r_gcd[0], l_gcd[-1])


for num1, num2 in zip(r_gcd[1:], l_gcd[:-1]):
    tmp = gcd(num1, num2)
    ans = max(ans, tmp)
print(ans)

# 解説を参考に作成
# import sys
# sys.setrecursionlimit(10 ** 6)
# import bisect
# from collections import deque

def gcd(a, b):
    """最大公約数"""
    a, b = (a, b) if a >= b else (b, a)
    if b == 0:
        return a
    return gcd(b, a % b)


# from decorator import stop_watch
# 
# 
# @stop_watch
def solve(N, A):
    L = [0] * N
    L[0] = A[0]
    for i in range(1, N):
        L[i] = gcd(A[i], L[i - 1])
    R = [0] * N
    R[-1] = A[-1]
    for i in range(1, N):
        R[-(i + 1)] = gcd(A[-(i + 1)], R[-i])
    ans = 0
    for i in range(N):
        if i == 0:
            ans = max(ans, R[i + 1])
        elif i == N - 1:
            ans = max(ans, L[i - 1])
        else:
            ans = max(ans, gcd(L[i - 1], R[i + 1]))
    print(ans)


def __starting_point():
    # S = input()
    N = int(input())
    # N, M = map(int, input().split())
    A = [int(i) for i in input().split()]
    # B = [int(i) for i in input().split()]
    # AB = [[int(i) for i in input().split()] for _ in range(N)]
    solve(N, A)

    # # test
    # from random import randint
    # from func import random_str
    # solve()

__starting_point()

from math import gcd


N, *A = list(map(int, open(0).read().split()))

acc_l = [0] * (N + 1)
acc_r = [0] * (N + 1)
for i in range(1, N + 1):
    acc_l[i] = gcd(acc_l[i - 1], A[i - 1])
    acc_r[i] = gcd(acc_r[i - 1], A[-i])
ans = 0
for i in range(N + 1):
    ans = max(ans, gcd(acc_l[i], acc_r[N - i - 1]))
print(ans)


import sys
sys.setrecursionlimit(10**9)

def mi(): return map(int,input().split())
def ii(): return int(input())
def isp(): return input().split()
def deb(text): print("-------\n{}\n-------".format(text))
def fde(): print("-flag-")

def divisors(n):
    res = []
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            res.append(i)
            if i != n // i:
                res.append(n//i)

    return res


def main():
    N=ii()
    A=list(mi())
    R = divisors(A[0]) + divisors(A[1])

    ans = 0
    for r in R:
        miss_count = 0
        for a in A:
            if a % r != 0:
                miss_count += 1
                if miss_count == 2:
                    break
        
        if miss_count <= 1:
            ans = max(ans,r)
            

    print(ans)








def __starting_point():
    main()
__starting_point()

import sys
import math
import itertools
import collections
from collections import deque
from collections import defaultdict

sys.setrecursionlimit(1000000)
MOD = 10 ** 9 + 7
MOD2 = 998244353
INF = float('inf')
input = lambda: sys.stdin.readline().strip()

NI = lambda: int(input())
NMI = lambda: map(int, input().split())
NLI = lambda: list(NMI())
SI = lambda: input()

def main():
    N = NI()
    A = NLI()
    
    L = [0 for _ in range(N)]
    L_gcd = 0
    for n in range(0,N-1):
        L_gcd = math.gcd(A[n],L_gcd)
        L[n+1] = L_gcd

    

    R = [0 for _ in range(N)]
    R_gcd = 0
    for n in range(N-1,-1,-1):
        R_gcd = math.gcd(A[n],R_gcd)
        R[n-1] = R_gcd
    R[-1] = 0

    
    ans = 0
    for n in range(N):
        ans = max(ans,math.gcd(L[n],R[n]))
    print(ans)
    


def __starting_point():
    main()
__starting_point()

import math
n=int(input())
a=list(map(int,input().split()))

ra=list(reversed(a))

left=[]
right=[]
right.append(ra[0])
left.append(a[0])

if n>2:
  k=math.gcd(a[0],a[1])
  left.append(k)
  for i in range(2,n-1):
    k=math.gcd(k,a[i])
    left.append(k)

  k=math.gcd(ra[0],ra[1])
  right.append(k)
  for i in range(2,n-1):
    k=math.gcd(k,ra[i])
    right.append(k)

  ans=[right[-1]]
  for i in range(1,n-1):
    ans.append(math.gcd(left[i-1],right[len(right)-i-1]))
  ans.append(left[-1])
  print(max(ans))
else:
  print(max(a[1],a[0]))

from itertools import accumulate
from math import gcd

N = int(input())
A = list(map(int, input().split()))

l = list(accumulate(A[:-1], gcd, initial=0))
r = list(accumulate(A[::-1], gcd, initial=0))
print(max(gcd(l[i], r[N-i-1]) for i in range(N)))

def gcd(x,y):
    if x==0 or y==0:
        return max(x,y)
    if x<y:
        x,y=y,x
    if x%y==0:
        return y
    return gcd(y,x%y)
n=int(input())
a=list(map(int,input().split()))
L=[a[0]]*n
R=[a[-1]]*n
for i in range(n-1):
    L[i+1]=gcd(L[i],a[i+1])
    R[-i-2]=gcd(R[-i-1],a[-i-2])
ans=1
L=[0]+L
R=R+[0]
for i in range(n):
    ans=max(ans,gcd(L[i],R[i+1]))
print(ans)

import math
from itertools import accumulate

n = int(input())
a = list(map(int, input().split()))

fromleft = list(accumulate(a, math.gcd))
fromright = list(accumulate(a[::-1], math.gcd))[::-1]

gcd = []

gcd.append(fromright[1])
for i in range(1, n-1):
    gcd.append(math.gcd(fromleft[i-1], fromright[i+1]))
gcd.append(fromleft[n-2])

print((max(gcd)))


#a, b, k = map(int, input().split( ))
import math

 
n = int(input())
a = list(map(int,input().split()))

left = [0] * (n + 1)
right = [0] * (n + 1)
for i in range(n):
    left[i + 1] = (math.gcd(left[i],a[i]))
    right[n - i - 1] = (math.gcd(right[n - i],a[n - 1 - i]))
#print(left, right)

ans = 0
for i in range(n):
  ans = max(ans, math.gcd(left[i],right[i+1]))
print(ans)

from math import ceil,floor,factorial,gcd,sqrt,log2,cos,sin,tan,acos,asin,atan,degrees,radians,pi,inf
from itertools import accumulate,groupby,permutations,combinations,product,combinations_with_replacement
from collections import deque,defaultdict,Counter
from bisect import bisect_left,bisect_right
from operator import itemgetter
from heapq import heapify,heappop,heappush
from queue import Queue,LifoQueue,PriorityQueue
from copy import deepcopy
from time import time
from functools import reduce
import string
import sys
sys.setrecursionlimit(10 ** 7)
def input() : return sys.stdin.readline().strip()
def INT()   : return int(input())
def MAP()   : return map(int,input().split())
def MAP1()  : return map(lambda x:int(x)-1,input().split())
def LIST()  : return list(MAP())
def LIST1() : return list(MAP1())

def solve():
    N = INT()
    a = LIST()
    l = [0]*N
    r = [0]*N
    l[0] = a[0]
    r[N-1] = a[N-1]

    for i in range(1, N):
        l[i] = gcd(l[i-1], a[i])
    for i in range(N-2, -1, -1):
        r[i] = gcd(r[i+1], a[i])

    ans = max(r[1], l[N-2])
    for i in range(1, N-1):
        ans = max(ans, gcd(l[i-1], r[i+1]))
    print(ans)
    
def __starting_point():
    solve()
__starting_point()

from math import gcd

N = int(input())
A = list(map(int, input().split()))


class SegmentTree(object):
    def __init__(self, init_val, segfunc, ide_ele):
        self.init_val = init_val
        self.segfunc = segfunc
        self.ide_ele = ide_ele
        n = len(init_val)

        self.num = 1 << (n - 1).bit_length()

        self.tree = [ide_ele] * 2 * self.num

        for i in range(n):
            self.tree[self.num + i] = init_val[i]

        for i in range(self.num - 1, 0, -1):
            self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

    def query(self, left, right):
        res = self.ide_ele

        left += self.num
        right += self.num

        while left < right:
            if left & 1:
                res = self.segfunc(res, self.tree[left])
                left += 1

            if right & 1:
                res = self.segfunc(res, self.tree[right - 1])

            left >>= 1
            right >>= 1

        return res

    def update(self, k, val):
        k += self.num
        self.tree[k] = val

        while k > 1:
            self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
            k >>= 1


def segfunc(x, y):
    return gcd(x, y)


def get_lcm(a, b):
    return (a * b) // gcd(a, b)


g = A[0]
for a in A[1:]:
    g = get_lcm(g, a)


ide_ele = g
st = SegmentTree(A, segfunc, ide_ele)


res = 0
for i in range(N):
    left = st.query(0, i)
    right = st.query(i + 1, N)

    res = max(res, gcd(left, right))

print(res)


from math import gcd
class SegmentTree:
    def __init__(self,n,ele=0):

        self.ide_ele = ele

        self.num =2**(n-1).bit_length()
        self.seg=[self.ide_ele]*2*self.num


    #####segfunc######
    def segfunc(self,x,y):
        return gcd(x,y)

    def init(self,init_val):
        #set_val
        for i in range(n):
            self.seg[i+self.num-1]=init_val[i]    
        #built
        for i in range(self.num-2,-1,-1) :
            self.seg[i]=self.segfunc(self.seg[2*i+1],self.seg[2*i+2]) 
        
    def update(self,k,x):
        k += self.num-1
        self.seg[k] = x
        while k:
            k = (k-1)//2
            self.seg[k] = self.segfunc(self.seg[k*2+1],self.seg[k*2+2])
        
    def query(self,p,q):
        if q<=p:
            return self.ide_ele
        p += self.num-1
        q += self.num-2
        res=self.ide_ele
        while q-p>1:
            if p&1 == 0:
                res = self.segfunc(res,self.seg[p])
            if q&1 == 1:
                res = self.segfunc(res,self.seg[q])
                q -= 1
            p = p//2
            q = (q-1)//2
        if p == q:
            res = self.segfunc(res,self.seg[p])
        else:
            res = self.segfunc(self.segfunc(res,self.seg[p]),self.seg[q])
        return res
n=int(input())
a=list(map(int,input().split()))
st=SegmentTree(n)
st.init(a)
ans=-1
for i in range(n):
    ans=max(ans,gcd(st.query(0,i),st.query(i+1,n)))
print(ans)

from math import ceil,floor,factorial,gcd,sqrt,log2,cos,sin,tan,acos,asin,atan,degrees,radians,pi,inf
from itertools import accumulate,groupby,permutations,combinations,product,combinations_with_replacement
from collections import deque,defaultdict,Counter
from bisect import bisect_left,bisect_right
from operator import itemgetter
from heapq import heapify,heappop,heappush
from queue import Queue,LifoQueue,PriorityQueue
from copy import deepcopy
from time import time
from functools import reduce
import string
import sys
sys.setrecursionlimit(10 ** 7)
def input() : return sys.stdin.readline().strip()
def INT()   : return int(input())
def MAP()   : return map(int,input().split())
def MAP1()  : return map(lambda x:int(x)-1,input().split())
def LIST()  : return list(MAP())
def LIST1() : return list(MAP1())

#####segfunc#####
def segfunc(x, y):
    return gcd(x, y)
#################

#####ide_ele#####
ide_ele = 0
#################

class SegTree:
    """
    init(init_val, ide_ele): 配列init_valで初期化 O(N)
    update(k, x): k番目の値をxに更新 O(logN)
    query(l, r): 区間[l, r)をsegfuncしたものを返す O(logN)
    """
    def __init__(self, init_val, segfunc, ide_ele):
        """
        init_val: 配列の初期値
        segfunc: 区間にしたい操作
        ide_ele: 単位元
        n: 要素数
        num: n以上の最小の2のべき乗
        tree: セグメント木(1-index)
        """
        n = len(init_val)
        self.segfunc = segfunc
        self.ide_ele = ide_ele
        self.num = 1 << (n - 1).bit_length()
        self.tree = [ide_ele] * 2 * self.num
        # 配列の値を葉にセット
        for i in range(n):
            self.tree[self.num + i] = init_val[i]
        # 構築していく
        for i in range(self.num - 1, 0, -1):
            self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

    def update(self, k, x):
        """
        k番目の値をxに更新
        k: index(0-index)
        x: update value
        """
        k += self.num
        self.tree[k] = x
        while k > 1:
            self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
            k >>= 1

    def query(self, l, r):
        """
        [l, r)のsegfuncしたものを得る
        l: index(0-index)
        r: index(0-index)
        """
        res = self.ide_ele

        l += self.num
        r += self.num
        while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
        return res

def solve():
    N = INT()
    a = LIST()
    seg = SegTree(a, segfunc, ide_ele)

    ans = 1
    for i in range(N):
        seg.update(i, 0)
        ans = max(ans, seg.query(0, N))
        seg.update(i, a[i])
    print(ans)

def __starting_point():
    solve()
__starting_point()

import math
from itertools import accumulate

n = int(input())
a = list(map(int, input().split()))

fromright = list(accumulate(a, math.gcd))
a.reverse()
fromleft = list(accumulate(a, math.gcd))
fromleft.reverse()

gcd = []

gcd.append(fromleft[1])

for i in range(1, n-1):
  gcd.append(math.gcd(fromright[i-1], fromleft[i+1]))

gcd.append(fromright[n-2])

if n == 2:
  print(max(a))
else:
  print(max(gcd))

import math

N=int(input())
A=list(map(int,input().split()))
L=[0]*(N+1)
R=[0]*(N+1)
M=[0]*N
for i in range(N):
  L[i+1]=math.gcd(L[i],A[i])
for i in range(N-1,0,-1):
  R[i]=math.gcd(R[i+1],A[i])
for i in range(N):
  M[i]=math.gcd(L[i],R[i+1])
print(max(M))

from math import gcd

N = int(input())
A = list(map(int, input().split()))

left = [0]
right = [0]

for i in range(1, N + 1):
    l = gcd(left[-1], A[i - 1])
    left.append(l)

    r = gcd(right[-1], A[N - i])
    right.append(r)

res = 0
for i in range(N):
    res = max(res, gcd(left[i], right[N - i - 1]))

print(res)

n=int(input())
a=list(map(int,input().split()))
from collections import deque
from math import gcd
a_left=deque()

a_left.append(a[0])


a_right=deque()

a_right.append(a[-1])

for i in range(n-1):
    a_left.append(gcd(a_left[-1],a[i+1]))
    a_right.appendleft(gcd(a_right[0],a[n-i-2]))


a_right=list(a_right)
a_left=list(a_left)

count=max(a_left[-2],a_right[1])

for j in range(n-2):
    count=max(gcd(a_left[j],a_right[j+2]),count)
print(count)

import math
from itertools import accumulate

n = int(input())
a = list(map(int, input().split()))

fromleft = list(accumulate(a, math.gcd))
fromright = list(accumulate(a[::-1], math.gcd))[::-1]

gcd = []

gcd.append(fromright[1])
for i in range(1, n-1):
    gcd.append(math.gcd(fromleft[i-1], fromright[i+1]))
gcd.append(fromleft[n-2])

print(max(gcd))

import math

# 1つ自由に書き換える⇒ある数を除くGCDの最大値
# 累積GCDを事前に算出することで、ある数を除くGCDをO(N)で求められる

n = int(input())
a = list(map(int, input().split()))

gcd_l = [0] * (n + 1)
gcd_r = [0] * (n + 1)

for i in range(n):
    gcd_l[i+1] = math.gcd(gcd_l[i], a[i])
    gcd_r[n-i-1] = math.gcd(gcd_r[n-i], a[n-i-1])

ans = 1
for l,r in zip(gcd_l, gcd_r[1:]):
    ans = max(ans, math.gcd(l, r))

print(ans)

import math

n = int(input())
a = list(map(int,input().split()))

lefGcd = [0]*100100
rigGcd = [0]*100100

lefGcd[0] = a[0]
rigGcd[n-1] = a[n-1]

#左側からGCDを計算した値を保持する。
for i in range(1,n):
	lefGcd[i] = math.gcd(lefGcd[i-1],a[i])

#右側からGCDを計算した値を保持する。
for i in reversed(list(range(0,n-1))):
	rigGcd[i] = math.gcd(rigGcd[i+1],a[i])

#一番左か一番右の値を除去したGCDの値を初期値にする。
ans = max(rigGcd[1],lefGcd[n-2])

#左からのGCD,1個飛ばし,右からのGCDを計算し、比較する。
for i in range(1,n-1):
	ans = max(ans,math.gcd(lefGcd[i-1],rigGcd[i+1]))

print(ans)


from math import gcd


N, *A = list(map(int, open(0).read().split()))
acc_l = [0]
acc_r = [0]
for i in range(N):
    acc_l.append(gcd(acc_l[-1], A[i]))
    acc_r.append(gcd(acc_r[-1], A[N - i - 1]))

ans = 0
for i in range(N):
    ans = max(ans, gcd(acc_l[i], acc_r[N - i - 1]))
print(ans)


N=int(input())
*A,=map(int,input().split())

def gcd(a,b):
  if b==0:return a
  return gcd(b, a%b)

def cum(array, merge, unit):
    new=[unit]
    for i in range(len(array)):
        new.append(merge(new[-1], array[i]))
    return new
  
cum1 = cum(A,gcd,A[0])
cum2 = cum(A[::-1],gcd,A[-1])[::-1]

res=[]
for i in range(N):
  if i == 0:
    tmp = cum2[i+1]
  elif i == N-1:
    tmp = cum1[i]
  else:
    tmp = gcd(cum1[i],cum2[i+1])
  res.append(tmp)
  
print(max(res))

import math
N = int(input())
List = list(map(int,input().split()))
L=[0]*N
R=[0]*N
for i in range(1,N):
  L[i] = math.gcd(L[i-1],List[i-1])
  R[-i-1] = math.gcd(R[-i],List[-i])
ans = 0
for i in range(N):
  ans = max(ans,math.gcd(L[i],R[i]))
print(ans)

#!/usr/bin/env python3
import sys
from math import gcd
from functools import reduce

def f(A):
    ret = [A[0]]
    for a in A:
        ret.append(gcd(ret[-1], a))
    ret[0] = reduce(gcd, A[1:])
    return ret

def solve(N: int, A: "List[int]"):    
    return  max(gcd(g0, g1) for g0, g1 in zip(f(A), f(A[::-1])[-2::-1]))

# Generated by 1.1.7.1 https://github.com/kyuridenamida/atcoder-tools
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  # type: int
    A = [int(next(tokens)) for _ in range(N)]  # type: "List[int]"
    print((solve(N, A)))

def test():
    import doctest
    doctest.testmod()

def __starting_point():
    #test()
    main()

__starting_point()

from math import gcd
N=int(input())
A=list(map(int,input().split()))

L=[A[0]]
R=[A[-1]]

for i in range(1,N):
    L.append(gcd(L[-1],A[i]))
    R.append(gcd(R[-1],A[-1-i]))
R=R[::-1]
#print(L)
#print(R)

ans=1
for j in range(N):
    if j==0:
        tmp = R[1]
    elif j==N-1:
        tmp = L[N-2]
    else:
        tmp = gcd(L[j-1],R[j+1])
    #print(j,tmp)
    ans=max(ans,tmp)
    
print(ans)

from math import gcd

n, *a = list(map(int, open(0).read().split()))

l = [0] * n
r = [0] * n
for i in range(n - 1):
    l[i + 1] = gcd(l[i], a[i])
for i in range(n - 1, 0, -1):
    r[i - 1] = gcd(r[i], a[i])
print((max(gcd(l[i], r[i]) for i in range(n))))


import sys
from math import gcd
from itertools import accumulate

read = sys.stdin.read
readline = sys.stdin.readline
readlines = sys.stdin.readlines
sys.setrecursionlimit(10 ** 9)
INF = 1 << 60
MOD = 1000000007


def main():
    N, *A = list(map(int, read().split()))

    vec1 = list(accumulate(A, func=gcd))
    vec2 = list(accumulate(reversed(A), func=gcd))

    ans = 0
    for i in range(N):
        if i == 0:
            res = vec2[-2]
        elif i == N - 1:
            res = vec1[-2]
        else:
            res = gcd(vec1[i - 1], vec2[N - i - 2])

        if ans < res:
            ans = res

    print(ans)
    return


def __starting_point():
    main()

__starting_point()

import math
n=int(input())
a=list(map(int,input().split()))
l=[0]*n
r=[0]*n
l[0]=a[0]
r[-1]=a[-1]
for i in range(n-1):
  l[i+1]=math.gcd(l[i],a[i+1])
for i in reversed(range(n-1)):
  r[i] = math.gcd(r[i+1],a[i])

ans=max(l[-2],r[1])
for i in range(1,n-1):
  ans = max(ans, math.gcd(l[i-1],r[i+1]))
print(ans)

from math import gcd


class SegmentTree:
    def __init__(self, size, op, e):
        self._op = op
        self._e = e
        self._size = size
        t = 1
        while t < size:
            t *= 2
        self._offset = t - 1
        self._data = [e] * (t * 2 - 1)

    def __getitem__(self, key):
        return self._data[self._offset + key]

    def __setitem__(self, key, value):
        op = self._op
        data = self._data
        i = self._offset + key
        data[i] = value
        while i >= 1:
            i = (i - 1) // 2
            data[i] = op(data[i * 2 + 1], data[i * 2 + 2])

    def build(self, iterable):
        op = self._op
        data = self._data
        data[self._offset:self._offset + self._size] = iterable
        for i in range(self._offset - 1, -1, -1):
            data[i] = op(data[i * 2 + 1], data[i * 2 + 2])

    def query(self, start, stop):
        def iter_segments(data, l, r):
            while l < r:
                if l & 1 == 0:
                    yield data[l]
                if r & 1 == 0:
                    yield data[r - 1]
                l = l // 2
                r = (r - 1) // 2
        op = self._op
        it = iter_segments(self._data, start + self._offset,
                           stop + self._offset)
        result = self._e
        for v in it:
            result = op(result, v)
        return result


N = int(input())
A = list(map(int, input().split()))

st = SegmentTree(N, gcd, 0)
st.build(A)

result = st.query(1, N)
for i in range(1, N - 1):
    result = max(result, gcd(st.query(0, i), st.query(i + 1, N)))
result = max(result, st.query(0, N - 1))
print(result)


N = int(input())
a = list(map(int, input().split()))


def gcd(x, y):
    if x < y:
        x, y = y, x
    while y != 0:
        tmp = x % y
        x = y
        y = tmp
    return x


ans = 1
if N == 2:
    print(max(a))
    return

l = [1] * N
l[0] = a[0]
r = [1] * N
r[N-1] = a[N-1]
for i in range(1, N):
    l[i] = gcd(l[i-1], a[i])
    r[N-1-i] = gcd(r[N-i], a[N-1-i])
    
for i in range(N):
    if i == 0:
        n = r[1]
    elif i == N-1:
        n = l[N-2]
    else:
        n = gcd(l[i-1], r[i+1])
    ans = max(ans, n)
print(ans)

import math
from collections import deque
N = int(input())
A = list(map(int,input().split()))

M = 0
L = deque([0])
R = deque([0])
for i in range(1,N+1):
    L.append(math.gcd(L[-1],A[i-1]))
    R.appendleft(math.gcd(R[0],A[N-i]))
for j in range(N):
    m = math.gcd(L[j],R[j+1])
    M = max(M,m)
print(M)

N = int(input())
A = list(map(int, input().split()))
ans = 0

def gcd(x, y):
  if x < y:
    x, y = y, x
  if y == 0:
    return x
  while y > 0:
    temp = x % y
    x = y
    y = temp
  return x

L = [0]
R = 0

for i in range(N-1):
  L.append(gcd(A[i], L[i]))
for i in range(N):
  temp = gcd(L[N-i-1], R)
  R = gcd(R, A[N-i-1])
  if ans < temp:
    ans = temp
    
print(ans)


import sys
def gcd(m, n):
    if n == 0:
        n, m = m, n
    r = m % n
    return gcd(n, r) if r else n

n = int(input())
a = list(map(int, sys.stdin.readline().split()))
l, r = [0]*(n+1), [0]*(n+1)
for i in range(1, n+1):
    l[i] = gcd(l[i-1], a[i-1])
    r[n-i] = gcd(r[n-i+1], a[n-i])
ans = 0
for i in range(n):
    m = gcd(l[i], r[i+1])
    if ans < m:
        ans = m
print(ans)

import math
from math import gcd,pi,sqrt
INF = float("inf")

import sys
sys.setrecursionlimit(10**6)
import itertools
from collections import Counter,deque
def i_input(): return int(input())
def i_map(): return list(map(int, input().split()))
def i_list(): return list(i_map())
def i_row(N): return [i_input() for _ in range(N)]
def i_row_list(N): return [i_list() for _ in range(N)]
def s_input(): return input()
def s_map(): return input().split()
def s_list(): return list(s_map())
def s_row(N): return [s_input for _ in range(N)]
def s_row_str(N): return [s_list() for _ in range(N)]
def s_row_list(N): return [list(s_input()) for _ in range(N)]


def main():
    n = i_input()
    a = i_list()

    left = [0]
    right = [0]

    for i in range(n):
        left.append(gcd(left[i], a[i]))
        right.append(gcd(right[i], a[-(i+1)]))

    ans = 0
    for i in range(n):
        ans = max(ans, gcd(left[i], right[n - i - 1]))
    print(ans)



def __starting_point():
    main()

__starting_point()

class SegmentTree: #1-indexed
    def __init__(self,list,f=lambda x,y:x+y,inf=0):
        self.height=(len(list)-1).bit_length()+1 #木の高さ
        self.zero=2**(self.height-1) #最下段に添字を合わせる用
        self.id=inf #単位元
        self.tree=[self.id]*(2**self.height) #木を単位元で初期化
        self.f=f
        for i in range(len(list)):
            self.tree[self.zero+i]=list[i]
        for i in range(self.zero-1,0,-1):
            self.tree[i]=self.f(self.tree[2*i],self.tree[2*i+1])
        
    def update(self,i,x): #i番目の要素をxに変更
        i+=self.zero
        self.tree[i]=x
        while i>1:
            i//=2
            self.tree[i]=self.f(self.tree[2*i],self.tree[2*i+1])
    
    def query(self,l,r): #区間[l,r)
        l+=self.zero
        r+=self.zero
        lf,rf=self.id,self.id
        while l<r:
            if l&1:
                lf=self.f(lf,self.tree[l])
                l+=1
            if r&1:
                r-=1
                rf=self.f(self.tree[r],rf)
            l//=2
            r//=2
        return self.f(lf,rf)

    '''
    FFFFTTTTとしたときの最小のTを求める
    '''
    def BinarySearch(self,l,r,f): #fの返り値はboolにする
        if not f(self.query(l,r)): #そもそも区間内にTがなければ右端をreturn
            return r
        l+=self.zero
        while True:
            if f(self.tree[l]):
                if l>=self.zero:
                    return l-self.zero+1 #最下段ならreturn
                else:
                    l*=2 #左の子供を見る
            else:
                if l%2==0:
                    l+=1 #左の子なら右を見る
                else:
                    l=(l//2)+1 #右の子なら親の右を見る

from math import gcd
n=int(input())
a=list(map(int,input().split()))
S=SegmentTree(a,gcd)
ans=0
for i in range(n):
    S.update(i,0)
    ans=max(ans,S.tree[1])
    S.update(i,a[i])
print(ans)

def gcd(a, b):
    while b:
        a, b = b, a % b
    return a


N = int(input())
A = list(map(int, input().split()))

Left = [A[0]]
for i in range(N-1):
    Left.append(gcd(Left[i], A[i+1]))

Right = [A[N-1]]
for i in range(N-1):
    Right.append(gcd(Right[i], A[N-2-i]))
Right.reverse()

ans_list = []
ans_list.append(Right[1])
for i in range(1, N-1):
    ans_list.append(gcd(Left[i-1], Right[i+1]))
ans_list.append(Left[N-2])

print(max(ans_list))

import sys
from math import gcd

input = sys.stdin.readline


def main():
    N = int(input())
    A = list(map(int, input().split()))

    if N == 2:
        ans = max(A)
        print(ans)
        return

    L_GCD = [0] * N
    L_GCD[0] = A[0]
    for i in range(N - 1):
        L_GCD[i + 1] = gcd(L_GCD[i], A[i + 1])

    R_GCD = [0] * N
    R_GCD[-1] = A[-1]
    for i in reversed(list(range(N - 1))):
        R_GCD[i] = gcd(R_GCD[i + 1], A[i])

    ans = 1
    for i in range(N):
        if i == 0:
            ans = max(ans, R_GCD[1])
        elif i == N - 1:
            ans = max(ans, L_GCD[-2])
        else:
            res = gcd(L_GCD[i - 1], R_GCD[i + 1])
            ans = max(ans, res)

    print(ans)


def __starting_point():
    main()

__starting_point()

from math import gcd
n = int(input())
a = [*map(int,input().split())]

lgcd = [0]*(n+2)
rgcd = [0]*(n+2)

for i in range(n):
    lgcd[i+1] = gcd(lgcd[i],a[i])
    rgcd[n-i] = gcd(rgcd[n-i+1],a[n-i-1])
ans = 0
for i in range(n+1):
    ans = max(ans,gcd(lgcd[i-1],rgcd[i+1]))
print(ans)

#!/usr/bin/env python3
import sys
from math import gcd

def f(A):
    ret = [0]
    for a in A:
        ret.append(gcd(ret[-1], a))
    return ret

def solve(N: int, A: "List[int]"):    
    return  max(gcd(g0, g1) for g0, g1 in zip(f(A), f(A[::-1])[-2::-1]))

# Generated by 1.1.7.1 https://github.com/kyuridenamida/atcoder-tools
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  # type: int
    A = [int(next(tokens)) for _ in range(N)]  # type: "List[int]"
    print((solve(N, A)))

def test():
    import doctest
    doctest.testmod()

def __starting_point():
    #test()
    main()

__starting_point()

from math import gcd
from itertools import accumulate

n = int(input())
a = list(map(int, input().split()))

l = list(accumulate(a, lambda x, y: gcd(x, y)))
r = list(accumulate(a[::-1], lambda x, y: gcd(x, y)))[::-1]
ans = max(r[1], l[-2])
for i in range(1, n-1):
    ans = max(ans, gcd(l[i-1], r[i+1]))
print(ans)

def main():
    import math
    n = int(input())
    a = sorted(list(map(int,input().split())))
    if n==2:
        print((a[1]))
        return
    ans = 0
    g = math.gcd(a[0],a[1])
    ans_list = []
    for i in range(1,int(g**0.5)+1):
        if g%i==0:
            ans_list.append(i)
    ans_list.append(g)
    for an in ans_list:
        cnt = 0
        for i in range(n):
            if a[i] % an != 0:
                cnt += 1
        if cnt < 2:
            if an>ans:
                ans = an
    g = math.gcd(a[1],a[2])
    ans_list = []
    for i in range(1,int(g**0.5)+1):
        if g%i==0:
            ans_list.append(i)
    ans_list.append(g)
    for an in ans_list:
        cnt = 0
        for i in range(n):
            if a[i] % an != 0:
                cnt += 1
        if cnt < 2:
            if an>ans:
                ans = an
    g = math.gcd(a[0],a[2])
    ans_list = []
    for i in range(1,int(g**0.5)+1):
        if g%i==0:
            ans_list.append(i)
    ans_list.append(g)
    for an in ans_list:
        cnt = 0
        for i in range(n):
            if a[i] % an != 0:
                cnt += 1
        if cnt < 2:
            if an>ans:
                ans = an
    print(ans)

def __starting_point():
    main()

__starting_point()

n = int(input())
a = list(map(int,input().split()))

def make_divisors(n):
    lower_divisors , upper_divisors = [], []
    i = 1
    while i*i <= n:
        if n % i == 0:
            lower_divisors.append(i)
            if i != n // i:
                upper_divisors.append(n//i)
        i += 1
    return lower_divisors + upper_divisors[::-1]


adiv = sorted(set(make_divisors(a[0]) + make_divisors(a[1])),reverse=True)


def is_ok(arg):
    #print(f"index{arg}でーす{adiv[arg]}")
    cnt = 0
    for i in range(n):
        if a[i]%adiv[arg] != 0:
            cnt += 1
            #print(str(a[i])+"×")

        if cnt>=2:
            #print("だめ"+str(a[i])+" iは"+str(i))
            return False
            break    
    else:
        #print("ok-")
        return True

import sys
for i in range(len(adiv)):
    if is_ok(i):
        print(adiv[i])
        return

import math

n=int(input())

a=list(map(int,input().split()))

L=[0]

for i in range(n):
  L.append(math.gcd(L[i],a[i]))

R=[0]
for i in range(n):
  R.append(math.gcd(R[i],a[n-1-i]))

ans=1
for i in range(n):
  ans=max(ans,math.gcd(L[i],R[n-1-i]))

print(ans)


# coding: UTF-8
import sys
import numpy as np
import math


n = int(input())
aList = list(map(int, input().split()))
gcdListLeft = [0 for i in range(n)]
gcdListRight = [0 for i in range(n)]

tmp = aList[0]
for i in range(n):
	tmp = gcdListLeft[i] = math.gcd(tmp, aList[i])

tmp = aList[n-1]
for i in range(n-1, -1, -1):
	tmp = gcdListRight[i] = math.gcd(tmp,aList[i])

ans = gcdListRight[1]
for i in range(1,n-1):
	ans = max(ans, math.gcd(gcdListLeft[i-1], gcdListRight[i+1]))
ans = max(ans, gcdListLeft[n-2])
print(ans)

from typing import Callable, List, Union

T = Union[int, str]


class SegmentTree:
    """Segment Tree"""

    __slots__ = ["e", "op", "_n", "_size", "tree"]

    def __init__(self, a: List[T], e: T, op: Callable[[T, T], T]) -> None:
        self.e = e
        self.op = op
        self._n = len(a)
        self._size = 1 << (self._n - 1).bit_length()

        self.tree = [e] * self._size + a + [e] * (self._size - self._n)
        for i in range(self._size - 1, 0, -1):
            self._update(i)

    def _update(self, k: int) -> None:
        """Update the value of a[k]."""
        self.tree[k] = self.op(self.tree[2 * k], self.tree[2 * k + 1])

    def set(self, k: int, x: T) -> None:
        """Assign x to a[k] in O(log n)."""
        assert 0 <= k < self._n

        k += self._size
        self.tree[k] = x
        while k:
            k >>= 1
            self._update(k)

    def get(self, k: int) -> T:
        """Return a[k] in O(1)."""
        assert 0 <= k < self._n
        return self.tree[k + self._size]

    def prod(self, l: int, r: int) -> T:
        """Return op(a[l], ..., a[r - 1]). Return e, if l == r.
        Complexity: O(log n)
        """
        assert 0 <= l <= r <= self._n

        sml, smr = self.e, self.e
        l += self._size
        r += self._size

        while l < r:
            if l & 1:
                sml = self.op(sml, self.tree[l])
                l += 1
            if r & 1:
                r -= 1
                smr = self.op(self.tree[r], smr)
            l >>= 1
            r >>= 1
        return self.op(sml, smr)

    def prod_all(self) -> T:
        """Return op(a[0], ..., a[n - 1]. Return e if n == 0.
        Complexity: O(1)
        """
        return self.tree[1]

    def max_right(self, l: int, f: Callable[[T], bool]) -> int:
        """
        Return an index r satisfying both:
            1. r = l or f(op(a[l], a[l + 1], ..., a[r - 1])) = true
            2. r = n or f(op(a[l], a[l + 1], ..., a[r])) = false.

        If f is monotone, this is the maximum r satisfying:
            f(op(a[l], a[l + 1], ..., a[r - 1])) = true.

        Complexity: O(log n)
        """
        assert 0 <= l <= self._n
        assert f(self.e)

        if l == self._n:
            return self._n

        l += self._size
        sm = self.e

        while True:
            while not l & 1:
                l >>= 1

            if not f(self.op(sm, self.tree[l])):
                while l < self._size:
                    l *= 2
                    if f(self.op(sm, self.tree[l])):
                        sm = self.op(sm, self.tree[l])
                        l += 1
                return l - self._size

            sm = self.op(sm, self.tree[l])
            l += 1

            if (l & -l) == l:
                break

        return self._n

    def min_left(self, r: int, f: Callable[[T], bool]) -> int:
        """
        Return an index l satisfying both:
            1. l = r or f(op(a[l], a[l + 1], ..., a[r - 1])) = true
            2. l = 0 or f(op(a[l - 1], a[l + 1], ..., a[r - 1])) = false.
        If f is monotone, this is the minimum l satisfying:
            f(op(a[l], a[l + 1], ..., a[r - 1])) = true.

        Complexity: O(log n)
        """
        assert 0 <= r <= self._n
        assert f(self.e)

        if not r:
            return 0

        r += self._size
        sm = self.e

        while True:
            r -= 1
            while r > 1 and r % 2:
                r >>= 1

            if not f(self.op(self.tree[r], sm)):
                while r < self._size:
                    r = 2 * r + 1
                    if f(self.op(self.tree[r], sm)):
                        sm = self.op(self.tree[r], sm)
                        r -= 1
                return r + 1 - self._size

            if (r & -r) == r:
                break

        return 0


def practice2_j():
    # https://atcoder.jp/contests/practice2/tasks/practice2_j
    N, _, *AQ = list(map(int, open(0).read().split()))
    A, Q = AQ[:N], AQ[N:]
    tree = SegmentTree(A, -1, max)
    res = []
    for t, x, y in zip(*[iter(Q)] * 3):
        if t == 1:
            tree.set(x - 1, y)
        elif t == 2:
            res.append(tree.prod(x - 1, y))
        else:
            res.append(tree.max_right(x - 1, lambda n: n < y) + 1)
    print(("\n".join(map(str, res))))


def staticrmq():
    # https://judge.yosupo.jp/problem/staticrmq
    N, Q, *ALR = list(map(int, open(0).read().split()))
    A, LR = ALR[:N], ALR[N:]
    tree = SegmentTree(A, (10 ** 10) + 1, min)
    res = [tree.prod(l, r) for l, r in zip(*[iter(LR)] * 2)]
    print(("\n".join(map(str, res))))


def dsl_2_a():
    # https://onlinejudge.u-aizu.ac.jp/problems/DSL_2_A
    N, Q, *X = list(map(int, open(0).read().split()))
    tree = SegmentTree([2 ** 31 - 1] * N, 2 ** 31 - 1, min)
    res = []
    for com, x, y in zip(*[iter(X)] * 3):
        if com:
            res.append(tree.prod(x, y + 1))
        else:
            tree.set(x, y)
    print(("\n".join(map(str, res))))


def abc125_c():
    # https://atcoder.jp/contests/abc125/tasks/abc125_c
    from math import gcd

    N, *A = list(map(int, open(0).read().split()))
    tree = SegmentTree(A, 0, gcd)
    res = max(gcd(tree.prod(0, i), tree.prod(i + 1, N)) for i in range(N))
    print(res)


def __starting_point():
    # practice2_j()
    # staticrmq()
    # dsl_2_a()
    abc125_c()

__starting_point()

from math import gcd

N = int(input())
A = list(map(int, input().split()))

A = [0] + A + [0]

#Left side
L = [A[1]]
tempL = A[1]
for i in range(1, N):
    tempL = gcd(tempL, A[i+1])
    L.append(tempL)
L = [0] + L
    
#Right side
R = [A[-2]]
tempR = A[-2]
for i in range(1, N):
    tempR = gcd(tempR, A[-i-2])
    R.append(tempR)
R = list(reversed(R)) + [0]

ans = []
for i in range(N):
    result = gcd(L[i], R[i+1])
    ans.append(result)

print((max(ans)))


from math import gcd
n = int(input())
a = list(map(int,input().split()))
l = 0
r = 0
x = [0] * (n+1)
y = [0] * (n+1)
for i in range(n):
    x[i+1] = gcd(x[i],a[i])
for i in range(n)[::-1]:
    y[i] = gcd(y[i+1],a[i])
m = []
for i in range(n):
    m.append(gcd(x[i],y[i+1]))
print(max(m))

N=int(input())
A=list(map(int,input().split()))
A=[0]+A
import math

L=[0 for i in range(N+2)]
R=[0 for i in range(N+2)]
for i in range(0,N+1):
  L[i+1]=math.gcd(L[i],A[i])
for i in range(N,-1,-1):
  R[i]=math.gcd(R[i+1],A[i])

M=[0 for i in range(N+1)]
for i in range(1,N+1):
  M[i]=math.gcd(L[i],R[i+1])
print(max(M))

from math import*
N=int(input())
*A,=map(int,input().split())
L=[0]
l=A[0]
for a in A:
    l=gcd(l,a)
    L.append(l)
R=[0]
r=A[-1]
for a in A[::-1]:
    r=gcd(a,r)
    R.append(r)
R=R[::-1]
M=[]
for i in range(N):
    M.append(gcd(L[i],R[i+1]))
print(max(M))

N = int(input())
A = list(map(int, input().split()))

import math
L = [0] * (N + 1)
R = [0] * (N + 1)

for i in range(N):
    L[i + 1] = math.gcd(L[i], A[i])
    R[N - i - 1] = math.gcd(R[N - i], A[N - i - 1])

ans = 0
for i in range(N):
    ans = max(ans, math.gcd(L[i], R[i+1]))

print(ans)

import math
from itertools import accumulate

n = int(input())
a = list(map(int, input().split()))

fromleft = list(accumulate(a, math.gcd))
a.reverse()
fromright = list(accumulate(a, math.gcd))
fromright.reverse()
a.reverse()

gcd = []

gcd.append(fromright[1])
for i in range(1, n-1):
    gcd.append(math.gcd(fromleft[i-1], fromright[i+1]))

gcd.append(fromleft[n-2])

if n == 2:
    print((max(a[1], a[0])))
else:
    print((max(gcd)))


from math import gcd

class SegTree():
    def segfunc(self, x, y):
        return gcd(x, y)

    def __init__(self, ide, init_val):
        n = len(init_val)
        self.ide_ele = ide
        self.num = 2**(n-1).bit_length()
        self.seg = [self.ide_ele] * 2 * self.num
        for i in range(n):
            self.seg[i+self.num-1] = init_val[i]    
        for i in range(self.num-2,-1,-1):
            self.seg[i] = self.segfunc(self.seg[2*i+1],self.seg[2*i+2]) 
    def update(self, idx, val):
        idx += self.num-1
        self.seg[idx] = val
        while idx:
            idx = (idx-1)//2
            self.seg[idx] = self.segfunc(self.seg[idx*2+1], self.seg[idx*2+2])
    def query(self, begin, end):
        if end <= begin:
            return self.ide_ele
        begin += self.num-1
        end += self.num-2
        res = self.ide_ele
        while begin + 1 < end:
            if begin&1 == 0:
                res = self.segfunc(res, self.seg[begin])
            if end&1 == 1:
                res = self.segfunc(res, self.seg[end])
                end -= 1
            begin = begin//2
            end = (end-1)//2
        if begin == end:
            res = self.segfunc(res, self.seg[begin])
        else:
            res = self.segfunc(self.segfunc(res, self.seg[begin]), self.seg[end])
        return res

def main():
    n = int(input())
    a = list(map(int, input().split()))
    seg = SegTree(0, a)
    ans = 1
    for i in range(n):
        ans = max(ans, gcd(seg.query(0, i), seg.query(i+1, n)))
    print(ans)

def __starting_point():
    main()
__starting_point()

n=int(input())
A=list(map(int,input().split()))

def gcd(a,b):
    if b==0: return a
    else:
        return gcd(b,a%b)
def lcm(a,b):
    return a*b//gcd(a,b)

l=[A[0]]* n
r=[A[-1]]*n
for i in range(n-1):
    l[i+1]=gcd(l[i], A[i+1])
    r[-i-2]= gcd(r[-i-1], A[-i-2])

ans=0
for i in range(n):
    if i==0:
        ans=max(ans, r[1]);continue
    if i==n-1:
        ans=max(ans, l[-2]);continue
    ans=max(ans, gcd(l[i-1], r[i+1]))
print(ans)

from math import *

n = int(input())
a = list(map(int, input().split()))

l = [a[0]]
for i in range(1, n-1):
  l.append(gcd(a[i], l[i-1]))

ans = l[n-2]
r = a[n-1]
for i in range(n-2,0,-1):
  r = gcd(r, a[i+1])
  ans = max(ans, gcd(l[i-1], r))
ans = max(ans, gcd(r,a[1]))
print(ans)

import math

n = int(input())
a = list(map(int,input().split()))

lefGcd = [0]*100100
rigGcd = [0]*100100

lefGcd[0] = a[0]
rigGcd[n-1] = a[n-1]

for i in range(1,n):
	lefGcd[i] = math.gcd(lefGcd[i-1],a[i])

for i in reversed(list(range(0,n-1))):
	rigGcd[i] = math.gcd(rigGcd[i+1],a[i])

ans = max(rigGcd[1],lefGcd[n-2])

for i in range(1,n-1):
	ans = max(ans,math.gcd(lefGcd[i-1],rigGcd[i+1]))

print(ans)


from math import gcd
n=int(input())
a=list(map(int,input().split()))
l=[0 for i in range(n)]
r=[0 for i in range(n)]
l[0]=a[0]
r[0]=a[-1]
for i in range(n-1):
    l[i+1]=gcd(l[i],a[i+1])
for i in range(n-1):
    r[i+1]=gcd(r[i],a[-2-i])

ans=[0 for i in range(n)]

for i in range(1,n-1):
    ans[i]=gcd(l[i-1],r[-i+n-2])
ans[0]=r[n-2]
ans[n-1]=l[n-2]

print((max(ans)))

    



from math import gcd

N = int(input())
A = list(map(int, input().split()))

# L = [0, A_1のgcd, A_1~A_2のgcd, A_1~A_3のgcd, ..., A_1~A_Nのgcd]、len = N+1
L = [0]
for i in range(N):
    L.append(gcd(L[-1], A[i]))


# R = [A_1~A_Nのgcd, A_2~A_Nのgcd, ..., A_N-1~A_Nのgcd, A_Nのgcd, 0], len = N+1
R = [0]
for i in range(N):
    R.append(gcd(R[-1], A[-i - 1]))
R = R[::-1]

ans_list = []
# A_1を消す場合, A_2を消す場合, ..., A_Nを消す場合
for i in range(N):
    ans_list.append(gcd(L[i], R[i + 1]))

print((max(ans_list)))


import math

N = int(input())
A = [int(i) for i in input().split()]

left = [0] * (N+1)
for i in range(1, N+1):
    left[i] = math.gcd(left[i-1], A[i-1])
    
right = [0] * (N+1)
right[N-1] = A[N-1]
for i in range(N-2, -1, -1):
    right[i] = math.gcd(right[i+1], A[i])
    
output = 0
for i in range(N):
    output = max(output, math.gcd(left[i], right[i+1]))
    
print(output)

from math import*
N=int(input())
*A,=map(int,input().split())
R=[0]
r=A[-1]
for a in A[::-1]:
    r=gcd(a,r)
    R.append(r)
R=R[::-1]
M=[]
L=0
for i in range(N):
    M.append(gcd(L,R[i+1]))
    L=gcd(L,A[i])
print(max(M))

from math import gcd

n = int(input())
a = list(map(int, input().split()))
l = [a[-1], a[0]]
r = [a[-1]]
for x in a[1:-1]:
    l.append(gcd(l[-1], x))
for x in a[-2:0:-1]:
    r.append(gcd(r[-1], x))
r = r[::-1]
r.append(a[0])
print(max(gcd(l[i], r[i]) for i in range(n)))

from math import gcd
n = int(input())
a = list(map(int,input().split()))
l,r = [a[0]]*n,[a[n-1]]*n
for i in range(1,n-1):
  l[i] = gcd(l[i-1],a[i])
  r[n-i-1] = gcd(r[n-i],a[n-i-1])
ans = [0]*n
ans[0] = r[1]
ans[n-1] = l[n-2]
for i in range(1,n-1):
  ans[i] = gcd(l[i-1],r[i+1])
print(max(ans))

import bisect, collections, copy, heapq, itertools, math, string, sys
input = lambda: sys.stdin.readline().rstrip() 
sys.setrecursionlimit(10**7)
INF = float('inf')
def I(): return int(input())
def F(): return float(input())
def SS(): return input()
def LI(): return [int(x) for x in input().split()]
def LI_(): return [int(x)-1 for x in input().split()]
def LF(): return [float(x) for x in input().split()]
def LSS(): return input().split()

def resolve():
    N = I()
    A = LI()

    # [0, i)の累積GCD
    gcd_cum_l = [0] * (N + 1)
    for i in range(N):
        gcd_cum_l[i+1] = math.gcd(A[i], gcd_cum_l[i])
    # [i, N)の累積GCD
    gcd_cum_r = [0] * (N + 1)
    for i in range(N - 1, -1, -1):
        gcd_cum_r[i] = math.gcd(A[i], gcd_cum_r[i+1])
    # print(gcd_cum_l)
    # print(gcd_cum_r)

    ans = 0
    for i in range(N):
        ans = max(math.gcd(gcd_cum_l[i], gcd_cum_r[i+1]), ans)

    print(ans)

def __starting_point():
    resolve()

__starting_point()

from math import gcd as g
#####segfunc#####
def segfunc(x, y):
    return g(x,y)
#################

#####ide_ele#####
ide_ele =0
#################

class SegTree:
    """
    init(init_val, ide_ele): 配列init_valで初期化 O(N)
    update(k, x): k番目の値をxに更新 O(logN)
    query(l, r): 区間[l, r)をsegfuncしたものを返す O(logN)
    """
    def __init__(self, init_val, segfunc, ide_ele):
        """
        init_val: 配列の初期値
        segfunc: 区間にしたい操作
        ide_ele: 単位元
        n: 要素数
        num: n以上の最小の2のべき乗
        tree: セグメント木(1-index)
        """
        n = len(init_val)
        self.segfunc = segfunc
        self.ide_ele = ide_ele
        self.num = 1 << (n - 1).bit_length()
        self.tree = [ide_ele] * 2 * self.num
        # 配列の値を葉にセット
        for i in range(n):
            self.tree[self.num + i] = init_val[i]
        # 構築していく
        for i in range(self.num - 1, 0, -1):
            self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

    def update(self, k, x):
        """
        k番目の値をxに更新
        k: index(0-index)
        x: update value
        """
        k += self.num
        self.tree[k] = x
        while k > 1:
            self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
            k >>= 1

    def query(self, l, r):
        """
        [l, r)のsegfuncしたものを得る
        l: index(0-index)
        r: index(0-index)
        """
        res = self.ide_ele

        l += self.num
        r += self.num
        while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
        return res

n=int(input())
a=list(map(int,input().split()))
seg=SegTree(a,segfunc,ide_ele)
ans=1
for i in range(n):
    p=seg.query(0,i)
    q=seg.query(i+1,n)
    ans=max(ans,g(p,q))
print(ans)








# author:  Taichicchi
# created: 11.10.2020 00:03:10

import sys
from math import gcd
N = int(input())
A = list(map(int, input().split()))

L = [0]
R = [0]

for i in range(N):
    L.append(gcd(L[-1], A[i]))

for i in range(N)[::-1]:
    R.append(gcd(R[-1], A[i]))

R.reverse()

M = 0

for i in range(N):
    M = max(M, gcd(L[i], R[i + 1]))

print(M)


ma = lambda :map(int,input().split())
lma = lambda :list(map(int,input().split()))
tma = lambda :tuple(map(int,input().split()))
ni = lambda:int(input())
yn = lambda fl:print("YES") if fl else print("NO")
import collections
import math
import itertools
import heapq as hq
gcd = math.gcd
n = ni()
A = lma()
gcd_l = [1]*n
gcd_l[0]=A[0]
gcd_r =[1]*n
gcd_r[-1] = A[-1]
for i in range(1,n):
    gcd_l[i] = gcd(A[i],gcd_l[i-1])
    gcd_r[-i-1] = gcd(A[-i-1],gcd_r[-i])
ans = max(gcd_l[-2],gcd_r[1])
for i in range(1,n-1):
    ggg = gcd(gcd_l[i-1],gcd_r[i+1])
    ans = max(ans,ggg)
print(ans)