CodeEff/ECCO huggingface dataset:
# Original solution

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


def solve(n, a):
    l, r = [], []
    l = [0 for i in range(n + 1)]
    r = [0 for i in range(n + 1)]
    r[n] = 0

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

    for i in range(n, 0, -1):

        if i == n:
            r[i] = 0
        else:
            r[i] = gcd(r[i+1], a[i])
    m = 0
    for i in range(n):
        # print('m', m)
        m = max(m, gcd(l[i], r[i + 1]))
    return m


def input_from_console():
    n = int(eval(input()))
    a = list(map(int, input().split()))
    return n, a


def main():
    n, a_list = input_from_console()
    print((solve(n, a_list)))


if __name__ == "__main__":
    main()


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


def solve(n, a):
    l = [0] * n
    r = [0] * (n + 1)

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

    m = 0
    for i in range(n):
        m = max(m, gcd(l[i], r[i + 1]))
    return m


def input_from_console():
    n = int(eval(input()))
    a = list(map(int, input().split()))
    return n, a


def main():
    n, a_list = input_from_console()
    print((solve(n, a_list)))


if __name__ == "__main__":
    main()
# Original solution
import math
from functools import reduce
N = int(eval(input()))
A = list(map(int,input().split()))

ans = 1
for i in range(N):
    g = reduce(math.gcd,A[:i]+A[i+1:])
    ans = max(ans,g)
print(ans)

# Optimized solution
import math
from collections import deque
N = int(eval(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)
# Original solution
N = int(eval(input()))
A = [int(i) for i in input().split()]

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

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

R.reverse()

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

print((max(M)))

# Optimized solution
N = int(eval(input()))
A = [int(i) for i in input().split()]

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

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

R.reverse()

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

print((max(M)))
# Original solution
"""
最大公約数をもっとも落としている数Xを削る（＝見ないことにする）、という発想に置き換える。
方針１：
Xを特定する。
どうやって特定する？
各Aを素因数分解する。このとき、他の

方針２：
約数をカウントする。すべてのAの約数をカウントして総和する。
このとき、カウントがN個になる約数は初期状態での公約数である。
一方で、カウントがN-1個の約数は、その約数をもたない数が一つだけ存在するということなので、
そのような数Aを削ったときに、公約数になる。
したがって、カウントがN-1個以上の約数のうち最大のものが、数Xを削ったときの最大公約数である。
問題はどうやって約数をカウントするかだ。愚直にやるとO(N√max(A))かかるため間に合わない。
ただ、約数の数自体はせいぜい1000個くらいのはず。いったん素因数分解してから、各素因数を何個累乗させるかで考えればよいか。
"""
def main():
    from collections import Counter
    N = int(eval(input()))
    A = list(map(int,input().split()))
    count = {}

    for a in A:
        tmp = []
        d = 2
        while d*d <= a:
            while a%d == 0:
                tmp.append(d)
                a //= d
            d += 1
        if a != 1:
            tmp.append(a)
        divides = [1]
        for k,v in list(Counter(tmp).items()):
            M = len(divides)
            for i in range(1,v+1):
                for j in range(M):
                    divides.append(divides[j]*pow(k,i))
        
        for d in divides:
            if d not in count:
                count[d] = 0
            count[d] += 1

    ans = 0
    for k,v in list(count.items()):
        if v >= N-1:
            ans = max(ans,k)
    print(ans)
main()

# Optimized solution
def gcd(a,b):
    if a == 0 or b == 0:
        return max(a,b)
    return a if b==0 else gcd(b,a%b)
N = int(eval(input()))
A = list(map(int,input().split()))
rA = A[::-1]

LEFT = [0]
g = A[0]
for i in range(N):
    g = gcd(g,A[i])
    LEFT.append(g)


RIGHT = [0]
g = rA[0]
for i in range(N):
    g = gcd(g,rA[i])
    RIGHT.append(g)


ans = 0
for i in range(1,N+1):
    ans = max(ans,gcd(LEFT[i-1],RIGHT[N-i]))
print(ans)
# Original solution
import math
import copy
import sys
import bisect
input = sys.stdin.readline

def divide(x): #約数配列
    div=[1]
    check=2
    for check in range(1,int(x**0.5)+1):
        if(x%check==0):
            div.append(check)
            div.append(x//check)
    return div

def main():
    n=int(eval(input()))
    a = list(map(int,input().split()))
    ans={}
    for i in range(n):
        div=divide(a[i])
        for c in div:
            if c not in ans:
                ans[c]=1
            else:
                ans[c]+=1
    M=1
    for c in ans:
        if ans[c]>=n-1:
            M=max(M,c)
    print(M)

if __name__ == "__main__":
    main()

# Optimized solution
def gcd(a, b): #最大公約数
    if b == 0:
        return a
    else:
        return gcd(b, a%b)
        
def main():
    n=int(eval(input()))
    a = list(map(int,input().split()))
    L=[a[0] for _ in range(n)]
    R=[a[n-1] for _ in range(n)]
    for i in range(1,n):
        L[i]=gcd(L[i-1],a[i])
    for i in range(1,n):
        R[i]=gcd(R[i-1],a[n-1-i])
    R.reverse()
    LR=[]
    for i in range(1,n-1):
        LR.append( gcd(L[i-1],R[i+1]) )
    if LR==[]:
        print((max(L[n-2],R[1] )))
    else:
        print((max(max(LR),L[n-2],R[1] )))


if __name__ == "__main__":
    main()
# Original solution
n = int(input())
a = input().split()

cnt = 0
for i in a:
    a[cnt] = int(i)
    cnt += 1

chk = {}
chk2 = {}
def make_divisors(k):
    divisors = []
    for i in range(1, int(k**0.5)+1):
        if k % i == 0:
            if i in chk:
                chk[i] += 1
            else:
                chk[i] = 1
            if i != k // i:
                key = int(k//i)
                if key in chk:
                    chk[key] += 1
                else:
                    chk[key] = 1
    return divisors

for i in range(2):
    make_divisors(a[i])
cnt = 1
for i in range(2,len(a)):
    k = a[i]
    if k in chk:
        make_divisors(k)
        cnt += 1
        continue
    del_list = []
    for j in chk:
        if k % j == 0:
            chk[j] += 1
        if chk[j] < cnt+1:
            del_list.append(j)
    for j in del_list:
        del chk[j]
    cnt += 1

answer = 0
for i in chk:
    if int(chk[i]) >= chk[1] - 1 and i > answer:
        answer = i
print(answer)

# Optimized solution
n = int(input())
a = input().split()

cnt = 0
for i in a:
    a[cnt] = int(i)
    cnt += 1

chk = {}
chk2 = {}
def make_divisors(k):
    divisors = []
    for i in range(1, int(k**0.5)+1):
        if k % i == 0:
            if i in chk:
                chk[i] += 1
            else:
                chk[i] = 1
            if i != k // i:
                key = int(k//i)
                if key in chk:
                    chk[key] += 1
                else:
                    chk[key] = 1
    return divisors

for i in range(2):
    make_divisors(a[i])
cnt = 1
for i in range(2,len(a)):
    k = a[i]
    if k not in chk2:
        chk2[k] = 1
    else:
        if chk2[k] == 1:
            chk2[k] += 1
        elif chk2[k] > 1:
            continue
    del_list = []
    for j in chk:
        if k % j == 0:
            chk[j] += 1
        if chk[j] < cnt+1:
            del_list.append(j)
    for j in del_list:
        del chk[j]
    cnt += 1

answer = 0
for i in chk:
    if int(chk[i]) >= chk[1] - 1 and i > answer:
        answer = i
print(answer)
# Original solution
memo = {}

def gcd(a, b):
    if (a, b) in list(memo.keys()):
        return memo[(a, b)]
    if b == 0:
        return a
    g = gcd(b, a % b)
    memo[(a, b)] = g
    return g

n = eval(input())
a_list = list(map(int, input().split()))
max_g = 0
for exclude in range(n):
    g = a_list[0] if exclude > 0 else a_list[1]
    for i, a in enumerate(a_list):
        if i == 0 or i == exclude:
            continue
        g_new = gcd(g, a)
        if (g, a) not in memo:
            memo[(g, a)] = g_new
        g = g_new
        if g <= max_g:
            break
    if g > max_g:
        max_g = g
print(max_g)


# Optimized solution
def gcd(a, b):
    if b == 0:
        return a
    g = gcd(b, a % b)
    return g

n = eval(input())
a_list = list(map(int, input().split()))

gs1 = [None] * n
gs1[0] = a_list[0]
for i in range(1, n):
    gs1[i] = gcd(gs1[i - 1], a_list[i])

gs2 = [None] * n
gs2[n - 1] = a_list[n - 1]
for i in reversed(range(n - 1)):
    gs2[i] = gcd(gs2[i + 1], a_list[i])

max_g = 0
for exclude in range(n):
    if exclude == 0:
        g = gs2[1]
    elif exclude == n - 1:
        g = gs1[n - 2]
    else:
        g = gcd(gs1[exclude - 1], gs2[exclude + 1])
    if g > max_g:
        max_g = g
print(max_g)
# Original solution
import functools
# import math


def solve():
    N = int(eval(input()))
    A = [int(i) for i in input().split()]
    # gcd = functools.reduce(math.gcd, A)
    max_gcd = 1
    for i in range(N):
        A_ = A.copy()
        A_.remove(A[i])
        max_gcd = max(max_gcd, functools.reduce(gcd, A_))
    print(max_gcd)


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


if __name__ == '__main__':
    solve()


# Optimized solution
# 解説を参考に作成
# 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)


if __name__ == '__main__':
    # S = input()
    N = int(eval(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()
# Original solution
from functools import reduce

def gcd_base(x, y):
    if x >= y:
        while y != 0:
            x, y = y, x % y
        return x
    else:
        while x != 0:
            y, x = x, y % x
        return y

def gcd(numbers):
    return reduce(gcd_base, numbers)

N = int(eval(input()))
A = list(map(int, input().split()))
GCD = []

for i in range(N):
    a = A.pop(0)
    GCD.append(gcd(A))
    A.append(a)

print((max(GCD)))

# Optimized solution
def gcd(x, y):
    if x >= y:
        while y != 0:
            x, y = y, x % y
        return x
    else:
        while x != 0:
            y, x = x, y % x
        return y

N = int(eval(input()))
A = list(map(int, input().split()))
L = [0, 0]
for ai in A:
    L.append(gcd(L[-1], ai))
 
R = [0, 0]
for ai in A[::-1]:
    R.append(gcd(R[-1], ai))
 
print((max(gcd(l, r) for l, r in zip(L, reversed(R)))))
# Original solution
# -*- coding: utf-8 -*-
import sys
import math
from bisect import bisect_left
from bisect import bisect_right
import collections
input = sys.stdin.readline

# bisect_left(lists, 3)
# bisect_right(lists, 3)

def main():
	N = int(eval(input()))
	A = input().split()
	A = [int(s) for s in A]

	ans = -1
	Lis = [[-1 for _ in range(N)] for _ in range(N)]

	for i, val in enumerate(A):
		tmp = -1
		for j, vol in enumerate(A):
			if i == j:
				continue

			if tmp == -1:
				tmp = vol
				continue

			if Lis[i][j] != -1:
				tmp = Lis[i][j]
			else:
				tmp = gcd(vol, tmp)
				Lis[i][j] = tmp

		if ans == -1 or tmp > ans:
			ans = tmp

	print(ans)



def gcd(a, b):
	if a > b:
		a, b = b, a
		
	while a > 0:
		a, b = b % a, a
	return b
	
if __name__ == "__main__":
	main()
	

# Optimized solution
# -*- coding: utf-8 -*-
import sys
import math
from bisect import bisect_left
from bisect import bisect_right
import collections
input = sys.stdin.readline
 
# bisect_left(lists, 3)
# bisect_right(lists, 3)
 
def main():
	N = int(eval(input()))
	A = input().split()
	A = [int(s) for s in A]

	base = -1
	for i, val in enumerate(A):
		if i == 0:
			base == val
			continue
		base = gcd(val, base)

	ans = base
	for i, val in enumerate(A):
		tmp = -1
		for j, vol in enumerate(A):
			if i == j:
				continue
 
			if tmp == -1:
				tmp = vol
				continue
 
			tmp = gcd(vol, tmp)
			if tmp <= base:
				break
 
		if tmp > ans:
			ans = tmp
 
	print(ans)
 
 
 
def gcd(a, b):
	if a > b:
		a, b = b, a
		
	while a > 0:
		a, b = b % a, a
	return b
	
if __name__ == "__main__":
	main()
# Original solution
class SegmentTree:
    def __init__(self, seq, func="min"):
        if func=="min":
            self.f = min
            self.e = float('inf')
        if func=="max":
            self.f = max
            self.e = -float('inf')
        if func=="gcd":
            self.f = gcd
            self.e = 0
        self._n = len(seq)
        self.n_seg = 2**(self._n-1).bit_length()
        self.seg = [self.e]*2*self.n_seg
        
        for i in range(self._n):
            self.seg[self.n_seg+i-1] = seq[i]
            
        for i in range(self.n_seg-2, -1, -1):
            self.seg[i] = self.f(self.seg[2*i+1], self.seg[2*i+2])
        
    def update(k, val):
        k += self.n_seg -1
        self.seg[k] = val
        while k+1:
            k = (k-1)//2
            self.seg[k] = self.f(self.seg[k*2+1], self.seg[k*2+2])
        
    def query(self, a, b):
        if b<=a:
            return self.e
        a += self.n_seg-1
        b += self.n_seg-2
        res = self.e
        while b-a>1:
            if a&1==0:
                res = self.f(res, self.seg[a])
            if b&1==1:
                res = self.f(res, self.seg[b])
                b -= 1
            a = a//2
            b = (b-1)//2
        if a==b:
            res = self.f(res, self.seg[a])
        else:
            res = self.f(self.f(res, self.seg[a]), self.seg[b])
        return res
    
    def __repr__(self):
        ret = str(self.seg[self._n-1:])
        return ret

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

if __name__=="__main__":
    N = int(eval(input()))
    A = list(map(int, input().split()))
    A_seg = SegmentTree(A, func="gcd")
    ans = -1
    for i in range(N):
        ans = max(ans, gcd(A_seg.query(0, i), A_seg.query(i+1, N)))
    print(ans)

# Optimized solution
def gcd(a, b):
    if b==0:
        return a
    while b>0:
        a, b = b, a%b
    return a
N = int(eval(input()))
A = list(map(int, input().split()))
S_left = [0 for _ in range(N+1)]
S_right = [0 for _ in range(N+1)]
for i in range(N):
    S_left[i+1] = gcd(S_left[i], A[i])
    S_right[i+1] = gcd(S_right[i], A[-i-1])
S_right = S_right[::-1]
S_left = S_left + [0]
S_right = [0] + S_right
ans = 0
for i in range(1, N+1):
    ans = max(ans, gcd(S_left[i-1], S_right[i+1]))
print(ans)
# Original solution
n=int(eval(input()))
l=list(map(int,input().split()))
gcds=[]

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

for i in range(len(l)):
    omitlist=list(l)
    omitlist.pop(i)
    n=len(omitlist)

    if n==1:
        gcds.append(omitlist[0])
    else:
        element = gcd(omitlist[0], omitlist[1])
        if n==2:
            gcds.append(element)
        else:
            for i in range(2,n):
                element=gcd(element,omitlist[i])
            gcds.append(element)

print((max(gcds)))

# Optimized solution
n=int(eval(input()))
left=list(map(int,input().split()))
right=list(left)
right.reverse()
gcds=[]
gcdleft=[]
gcdright=[]

gcdleft.append(left[0])
gcdright.append(right[0])

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

if n==2:
    gcds.append(gcdleft[0])
    gcds.append(gcdright[0])
else:
    for i in range(1,n-1):
        gcdleft.append(gcd(gcdleft[i-1],left[i]))
        gcdright.append(gcd(gcdright[i-1],right[i]))
    gcds.append(gcdright[-1])
    for i in range(0,n-2):
    	gcds.append(gcd(gcdleft[i],gcdright[n-3-i]))
    gcds.append(gcdleft[-1])

print((max(gcds)))
# Original solution
def gcd(a, b):
    if b == 0:
        return a
    else:
        return gcd(b, a%b)

def gcd_arr(arr, N):
    if N == 2:
        return gcd(arr[0], arr[1])
    elif N == 1:
        return arr[0]
    else:
        mid = N // 2
        return gcd(gcd_arr(arr[:mid], mid), gcd_arr(arr[mid:], N-mid))

def gcd_arr_with_rm(arr, N, remove = 0):
    return gcd_arr(arr[0:remove] + arr[(remove+1):], N - 1)

def solve():
    N = int(input())
    arr = [int(_) for _ in input().split()]
    max_gcd = 1
    for j in range(N):
        tmp = gcd_arr_with_rm(arr, N, remove = j)
        if tmp > max_gcd:
            max_gcd = tmp
    print(str(max_gcd))

if __name__ == '__main__':
    solve()


# Optimized solution
def gcd(a, b):
    if b == 0:
        return a
    else:
        return gcd(b, a%b)

def solve():
    N = int(input())
    arr = [int(_) for _ in input().split()]
    left = [0] * (N + 1)
    right = [0] * (N + 1)
    left[0] = 0
    right[N] = 0
    for i in range(1, N+1):
        left[i] = gcd(left[i - 1], arr[i - 1])
    for i in range(N - 1, 0, -1):
        right[i] = gcd(right[i + 1], arr[i])
    max_gcd = 0
    for i in range(N):
        max_gcd = max(max_gcd, gcd(left[i], right[i+1]))
    print(str(max_gcd))

if __name__ == '__main__':
    solve()
# Original solution
import copy
n = int(eval(input()))
l = sorted(list(map(int, input().split())))
b = []

def gcd(a,b):
	while b:
		a, b = b, a % b
	return a
if n == 2:
	print((max(l[0],l[1])))
elif n == 3:
	print((max(gcd(l[0],l[1]),gcd(l[0],l[2]),gcd(l[2],l[1]))))
else:
	for i in range(n):
		tmp = copy.copy(l)
		tmp.pop(i)
		x = gcd(tmp[0],tmp[1])
		for j in list(range(2, n-1)):
			x = gcd(x,tmp[j])
		b.append(x)
	print((max(b)))

# Optimized solution
def gcd(a,b):
  while b:a,b=b,a%b
  return a
n,a,b=int(eval(input())),list(map(int,input().split())),[]
if n==2:print((max(a[0],a[1])))
elif n==3:print((max(gcd(a[0],a[1]),gcd(a[0],a[2]),gcd(a[1],a[2]))))
else:
  no,mi=a[0],a[0]
  for i in range(1,n):
    s=gcd(no,a[i])
    if s!=no:
      no=max(s,mi)
      mi=gcd(s,mi)
  print(no)
# Original solution
n=int(eval(input()))
A=list(map(int,input().split()))
divsors=[]
for i in range(n):
  for j in range(1,int(A[i]**(1/2)+1)):
    if A[i]%j==0:
      divsors.append(j)
      if j!=A[i]//j:
        divsors.append(A[i]//j)
set_divsors=sorted(list(set(divsors)))[::-1]
for i in range(len(set_divsors)):
  a=divsors.count(set_divsors[i])
  if a==n or a==n-1:
    print((set_divsors[i]))
    break

# Optimized solution
n=int(eval(input()))
A=[]*n
A[:]=list(map(int,input().split()))

def gcd(a,b):
    while b:
        a,b=b,a%b
    return a
      
left=[0]*n
right=[0]*n
for i in range(1,n):
  left[i]=gcd(left[i-1],A[i-1])
  right[n-1-i]=gcd(right[n-i],A[n-i])

ans=0
for i,j in zip(left,right):
  ans=max(ans,gcd(i,j))
print(ans)
# Original solution
from functools import reduce

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

def gcd_list(numbers):
    return reduce(gcd, numbers)

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

max_ans = 0
for i in range(len(A)):
    tmp = A[:i] + A[1+i:]
    ans = gcd_list(tmp)
    if max_ans < ans:
        max_ans = ans
print(max_ans)

# Optimized solution
def gcd(a,b):
  while b!=0:
    a,b=b,a%b
  return a


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

# 累積最大公約数的な
head = []
tail = []
head.append(A[0])
tail.append(A[-1])
for i, j in zip(A[1:], A[N-2::-1]):
    head.append(gcd(head[-1], i))
    tail.append(gcd(tail[-1], j))
ans = 0
for i in range(len(head)-2):
    tmp = gcd(head[i], tail[len(tail)-1-2-i])
    if ans < tmp:
        ans = tmp
print((max(head[-1], head[-2], tail[-2], ans)))
# Original solution
def gcd(a, b):
    while b:
        a, b = b, a % b
    return a

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

d = {}
m = []

if len(A) == 2:
    print((max(A)))
    exit()

for i in range(N):
    _A = []
    _A.extend(A[0:i])
    _A.extend(A[i+1:N])

    for j in range(1, len(_A)):
        if j == 1:
            tmp = gcd(_A[j], _A[j-1])
        else:
            tmp = gcd(_A[j], tmp)
    m.append(tmp)
print((max(m)))


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

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

L = [0] * N
R = [0] * N

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

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

ans = 0
for n in range(N):
    if n == 0:
        ans = max(ans, R[n+1])
    elif n == N - 1:
        ans = max(ans, L[n-1])
    else:
        ans = max(ans, gcd(L[n-1], R[n+1]))

print(ans)
# Original solution
from collections import deque
def gcm(a, b):
  if a < b:
    a = a+b
    b=a-b
    a = a-b
  if b == 0:
    return a
  else:
    r = a%b
    return b if r == 0 else gcm(b, r)
N = int(eval(input()))
A = list(map(int, input().split()))
L = deque([0])
for i in range(1, N):
  L.append(gcm(L[-1],A[i-1]))
R = deque([0])
for i in reversed(list(range(N-1))):
  R.appendleft(gcm(R[0],A[i+1]))
ans = 0
for i in range(N):
  ans = max(ans, gcm(L[i],R[i]))
print(ans)


# Optimized solution
import sys
sys.setrecursionlimit(10**5)
def GCM(a, b):
  if a < b:
    a += b
    b = a-b
    a -= b
  if a % b == 0:
    return b
  else:
    return GCM(b, a%b)

N = int(eval(input()))
A = list(map(int, input().split()))
l2r =[]
r2l = []
g = A[0]
for a in A:
  g = GCM(g, a)
  l2r.append(g)
g = A[-1]
for a in reversed(A):
  g = GCM(g, a)
  r2l.append(g)
r2l = list(reversed(r2l))
ans = r2l[1]
for i in range(1, N-1):
  ans = max(ans, GCM(l2r[i-1], r2l[i+1]))
ans = max(ans, l2r[N-2])
print(ans)