CodeEff/ECCO huggingface dataset:
# Original solution
import sys
readline = sys.stdin.buffer.readline


class SegmentTree:
    def __init__(self, N, func, I):
        self.N = N
        self.sz = 2**(N-1).bit_length()
        self.func = func
        self.I = I
        self.seg = [I] * (self.sz * 2)

    def assign(self, k, x):
        self.seg[k + self.sz] = x

    def build(self):
        for i in reversed(list(range(1, self.sz))):
            self.seg[i] = self.func(self.seg[2 * i], self.seg[2 * i + 1])

    def update(self, k, x):
        k += self.sz
        self.seg[k] = x
        while k > 1:
            k >>= 1
            self.seg[k] = self.func(self.seg[2 * k], self.seg[2 * k + 1])

    def query(self, a, b):
        L = self.I
        R = self.I
        a += self.sz
        if b == self.N:
            b = self.sz
        b += self.sz
        while a < b:
            if a & 1:
                L = self.func(L, self.seg[a])
                a += 1
            if b & 1:
                b -= 1
                R = self.func(self.seg[b], R)
            a >>= 1
            b >>= 1
        return self.func(L, R)


def main():
    def gcd(a, b):
        while b:
            a, b = b, a % b
        return a
    N = int(readline())
    L = list(map(int, readline().split()))
    seg = SegmentTree(N, gcd, 0)
    for i, n in enumerate(L):
        seg.assign(i, n)
    seg.build()
    ans = 1
    for i in range(N):
        ans = max(ans, gcd(seg.query(0, i), seg.query(i+1, N)))
    print(ans)


main()


# Optimized solution
# test
import sys
readline = sys.stdin.buffer.readline


class SegmentTree:
    def __init__(self, N, func, I):
        self.N = N
        self.sz = 2**(N-1).bit_length()
        self.func = func
        self.I = I
        self.seg = [I] * (self.sz * 2)

    def assign(self, k, x):
        self.seg[k + self.sz] = x

    def build(self):
        for i in reversed(list(range(1, self.sz))):
            self.seg[i] = self.func(self.seg[2 * i], self.seg[2 * i + 1])

    def update(self, k, x):
        k += self.sz
        self.seg[k] = x
        while k > 1:
            k >>= 1
            self.seg[k] = self.func(self.seg[2 * k], self.seg[2 * k + 1])

    def query(self, a, b):
        L = self.I
        R = self.I
        a += self.sz
        if b == self.N:
            b = self.sz
        b += self.sz
        while a < b:
            if a & 1:
                L = self.func(L, self.seg[a])
                a += 1
            if b & 1:
                b -= 1
                R = self.func(self.seg[b], R)
            a >>= 1
            b >>= 1
        return self.func(L, R)


def main():
    def gcd(a, b):
        while b:
            a, b = b, a % b
        return a
    N = int(readline())
    L = list(map(int, readline().split()))
    seg = SegmentTree(N, gcd, 0)
    for i, n in enumerate(L):
        seg.assign(i, n)
    seg.build()
    ans = 1
    for i in range(N):
        ans = max(ans, gcd(seg.query(0, i), seg.query(i+1, N)))
    print(ans)


main()
# Original solution
import sys
readline = sys.stdin.buffer.readline


class SegmentTree:
    def __init__(self, N, func, I):
        self.N = N
        self.sz = 2**(N-1).bit_length()
        self.func = func
        self.I = I
        self.seg = [I] * (self.sz * 2)

    def assign(self, k, x):
        self.seg[k + self.sz] = x

    def build(self):
        for i in reversed(list(range(1, self.sz))):
            self.seg[i] = self.func(self.seg[2 * i], self.seg[2 * i + 1])

    def update(self, k, x):
        k += self.sz
        self.seg[k] = x
        while k > 1:
            k >>= 1
            self.seg[k] = self.func(self.seg[2 * k], self.seg[2 * k + 1])

    def query(self, a, b):
        if a >= b:
            return self.I
        L = self.I
        R = self.I
        a += self.sz
        if b == self.N:
            b = self.sz
        b += self.sz
        while a < b:
            if a & 1:
                L = self.func(L, self.seg[a])
                a += 1
            if b & 1:
                b -= 1
                R = self.func(self.seg[b], R)
            a >>= 1
            b >>= 1
        return self.func(L, R)


def main():
    def gcd(a, b):
        while b:
            a, b = b, a % b
        return a
    N = int(readline())
    L = list(map(int, readline().split()))
    seg = SegmentTree(N, gcd, 0)
    for i, n in enumerate(L):
        seg.assign(i, n)
    seg.build()
    ans = 1
    for i in range(N):
        ans = max(ans, gcd(seg.query(0, i), seg.query(i+1, N)))
    print(ans)


main()


# Optimized solution
import sys
readline = sys.stdin.buffer.readline


class SegmentTree:
    def __init__(self, N, func, I):
        self.N = N
        self.sz = 2**(N-1).bit_length()
        self.func = func
        self.I = I
        self.seg = [I] * (self.sz * 2)

    def assign(self, k, x):
        self.seg[k + self.sz] = x

    def build(self):
        for i in reversed(list(range(1, self.sz))):
            self.seg[i] = self.func(self.seg[2 * i], self.seg[2 * i + 1])

    def update(self, k, x):
        k += self.sz
        self.seg[k] = x
        while k > 1:
            k >>= 1
            self.seg[k] = self.func(self.seg[2 * k], self.seg[2 * k + 1])

    def query(self, a, b):
        L = self.I
        R = self.I
        a += self.sz
        if b == self.N:
            b = self.sz
        b += self.sz
        while a < b:
            if a & 1:
                L = self.func(L, self.seg[a])
                a += 1
            if b & 1:
                b -= 1
                R = self.func(self.seg[b], R)
            a >>= 1
            b >>= 1
        return self.func(L, R)


def main():
    def gcd(a, b):
        while b:
            a, b = b, a % b
        return a
    N = int(readline())
    L = list(map(int, readline().split()))
    seg = SegmentTree(N, gcd, 0)
    for i, n in enumerate(L):
        seg.assign(i, n)
    seg.build()
    ans = 1
    for i in range(N):
        ans = max(ans, gcd(seg.query(0, i), seg.query(i+1, N)))
    print(ans)


main()
# Original solution
# test

import sys
readline = sys.stdin.buffer.readline


class SegmentTree:
    def __init__(self, N, func, I):
        self.N = N
        self.sz = 2**(N-1).bit_length()
        self.func = func
        self.I = I
        self.seg = [I] * (self.sz * 2)

    def assign(self, k, x):
        self.seg[k + self.sz] = x

    def build(self):
        for i in reversed(list(range(1, self.sz))):
            self.seg[i] = self.func(self.seg[2 * i], self.seg[2 * i + 1])

    def update(self, k, x):
        k += self.sz
        self.seg[k] = x
        while k > 1:
            k >>= 1
            self.seg[k] = self.func(self.seg[2 * k], self.seg[2 * k + 1])

    def query(self, a, b):
        L = self.I
        R = self.I
        a += self.sz
        b += self.sz
        while a < b:
            if a & 1:
                L = self.func(L, self.seg[a])
                a += 1
            if b & 1:
                b -= 1
                R = self.func(self.seg[b], R)
            a >>= 1
            b >>= 1
        return self.func(L, R)


def main():
    def gcd(a, b):
        while b:
            a, b = b, a % b
        return a
    N = int(readline())
    L = list(map(int, readline().split()))
    seg = SegmentTree(N, gcd, 0)
    for i, n in enumerate(L):
        seg.assign(i, n)
    seg.build()
    ans = 1
    for i in range(N):
        ans = max(ans, gcd(seg.query(0, i), seg.query(i+1, N)))
    print(ans)


main()


# Optimized solution
import sys
readline = sys.stdin.buffer.readline


class SegmentTree:
    def __init__(self, N, func, I):
        self.N = N
        self.sz = 2**(N-1).bit_length()
        self.func = func
        self.I = I
        self.seg = [I] * (self.sz * 2)

    def assign(self, k, x):
        self.seg[k + self.sz] = x

    def build(self):
        for i in range(self.sz-1, 0, -1):
            self.seg[i] = self.func(self.seg[2 * i], self.seg[2 * i + 1])

    def update(self, k, x):
        k += self.sz
        self.seg[k] = x
        while k > 1:
            k >>= 1
            self.seg[k] = self.func(self.seg[2 * k], self.seg[2 * k + 1])

    def query(self, a, b):
        L = self.I
        R = self.I
        a += self.sz
        if b == self.N:
            b = self.sz
        b += self.sz
        while a < b:
            if a & 1:
                L = self.func(L, self.seg[a])
                a += 1
            if b & 1:
                b -= 1
                R = self.func(self.seg[b], R)
            a >>= 1
            b >>= 1
        return self.func(L, R)


def main():
    def gcd(a, b):
        while b:
            a, b = b, a % b
        return a
    N = int(readline())
    L = list(map(int, readline().split()))
    seg = SegmentTree(N, gcd, 0)
    for i, n in enumerate(L):
        seg.assign(i, n)
    seg.build()
    ans = 1
    for i in range(N):
        ans = max(ans, gcd(seg.query(0, i), seg.query(i+1, N)))
    print(ans)


main()
# Original solution
import sys
readline = sys.stdin.buffer.readline


class SegmentTree:
    def __init__(self, N, func, I):
        self.N = N
        self.sz = 2**(N-1).bit_length()
        self.func = func
        self.I = I
        self.seg = [I] * (self.sz * 2)

    def assign(self, k, x):
        self.seg[k + self.sz] = x

    def build(self):
        for i in range(self.sz-1, 0, -1):
            self.seg[i] = self.func(self.seg[2 * i], self.seg[2 * i + 1])

    def update(self, k, x):
        k += self.sz
        self.seg[k] = x
        while k > 1:
            k >>= 1
            self.seg[k] = self.func(self.seg[2 * k], self.seg[2 * k + 1])

    def query(self, a, b):
        L = self.I
        R = self.I
        a += self.sz
        if b == self.N:
            b = self.sz
        b += self.sz
        while a < b:
            if a & 1:
                L = self.func(L, self.seg[a])
                a += 1
            if b & 1:
                b -= 1
                R = self.func(self.seg[b], R)
            a >>= 1
            b >>= 1
        return self.func(L, R)


def main():
    def gcd(a, b):
        while b:
            a, b = b, a % b
        return a
    N = int(readline())
    L = list(map(int, readline().split()))
    seg = SegmentTree(N, gcd, 0)
    for i, n in enumerate(L):
        seg.assign(i, n)
    seg.build()
    ans = 1
    for i in range(N):
        ans = max(ans, gcd(seg.query(0, i), seg.query(i+1, N)))
    print(ans)


main()


# Optimized solution
import sys
readline = sys.stdin.buffer.readline


class SegmentTree:
    def __init__(self, N, func, I):
        self.N = N
        self.sz = 2**(N-1).bit_length()
        self.func = func
        self.I = I
        self.seg = [I] * (self.sz * 2)

    def assign(self, k, x):
        self.seg[k + self.sz] = x

    def build(self):
        for i in reversed(list(range(1, self.sz))):
            self.seg[i] = self.func(self.seg[2 * i], self.seg[2 * i + 1])

    def update(self, k, x):
        k += self.sz
        self.seg[k] = x
        while k > 1:
            k >>= 1
            self.seg[k] = self.func(self.seg[2 * k], self.seg[2 * k + 1])

    def query(self, a, b):
        L = self.I
        R = self.I
        a += self.sz
        if b == self.N:
            b = self.sz
        b += self.sz
        while a < b:
            if a & 1:
                L = self.func(L, self.seg[a])
                a += 1
            if b & 1:
                b -= 1
                R = self.func(self.seg[b], R)
            a >>= 1
            b >>= 1
        return self.func(L, R)


def main():
    def gcd(a, b):
        while b:
            a, b = b, a % b
        return a
    N = int(readline())
    L = list(map(int, readline().split()))
    seg = SegmentTree(N, gcd, 0)
    for i, n in enumerate(L):
        seg.assign(i, n)
    seg.build()
    ans = 1
    for i in range(N):
        ans = max(ans, gcd(seg.query(0, i), seg.query(i+1, N)))
    print(ans)


main()
# Original solution
import sys
input = sys.stdin.readline
N = int(eval(input()))
A = list(map(int,input().split()))

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

ans = 0
B = []
for i in range(N):
    b = [A[i],A[i-1]]
    B.append(gcd(max(b),min(b)))
for i in range(-1,-N-1,-1):
    if N == 2:
        ans = max(A)
        break
    while 1:
        C = B.copy()
        C.pop(i)
        C.pop(i-(-1))
        c = []
        for j in range(len(C)):
            c.append(gcd(C[j],C[j-1]))
        if c == C:
            ans = max(ans,max(c))
            break
        C = c
print(ans)

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

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

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

res = 0
for i in range(N):
    if i == 0:
        res = max(res,R[-3])
    elif i == N-1:
        res = max(res,L[-3])
    else:
        res = max(res,gcd(L[i-1],R[-i-3]))
        
print(res)
# Original solution
import sys
sys.setrecursionlimit(10**8)
input = sys.stdin.readline
from math import gcd

class SegTree:
    def __init__(self, N, ele):
        self.num = 2**(N-1).bit_length()
        self.el = ele
        self.data = [ele]*(2*self.num)

    def calc(self, x, y):
        return gcd(x, y)

    def update(self, idx, x):
        idx += (self.num - 1)
        self.data[idx] = x
        while idx > 0:
            idx = (idx-1)//2
            self.data[idx] = self.calc(self.data[2*idx+1], self.data[2*idx+2])

    def prod(self, l, r):
        L = l + self.num
        R = r + self.num
        res = self.el
        while L < R:
            if L & 1:
                res  = self.calc(res, self.data[L-1])
                L += 1
            if R & 1:
                R -= 1
                res = self.calc(res, self.data[R-1])
            L >>= 1
            R >>= 1
        return res

    def get(self, idx):
        idx += (self.num - 1)
        return self.data[idx]
    

n = int(eval(input()))
A = list(map(int, input().split()))
seg = SegTree(n, 0)
for i, a in enumerate(A):
    seg.update(i, a)

ans = 0
for i in range(n):
    g = seg.get(i)
    seg.update(i, 0)
    ans = max(ans, seg.prod(0, n))
    seg.update(i, g)
print(ans)

# Optimized solution
from math import gcd
n = int(eval(input()))
A = [0] + list(map(int, input().split())) + [0]
n += 2

L, R = [0]*n, [0]*n
gl, gr = 0, 0
for i in range(n):
    gl = gcd(gl, A[i])
    gr = gcd(gr, A[n-i-1])
    L[i] = gl
    R[n-i-1] = gr

ans = L[-1]
for i in range(n-2):
    ans = max(ans, gcd(L[i], R[i+2]))
print(ans)
# Original solution
import functools
import copy

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

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

if N == 2:
    n = max(A)
else:
    for i in range(N):
        l = copy.copy(A)
        l.pop(i)
        res = functools.reduce(lambda x, y: gcd(x, y), l)
        if res > n:
            n = res
print(n)


# Optimized solution
import functools
import copy

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

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

l = [0] * N  #L_i, i = 0, 1, 2, ..., N-1
for i in range(N):
    if i == 0:
        continue
    else:
        l[i] = gcd(l[i-1], A[i-1])

r = [0] * N #R_i, i = 0, 1, 2, ..., N-1
for j in range(N):
    if j == 0:
        continue
    else:
        r[N-j-1] = gcd(r[N-j], A[N-j])

m = [0] * N
for i in range(N):
    m[i] = gcd(l[i], r[i])

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

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

def f(a,an):
     an = max(functools.reduce(gcd, a),an)
     return an
     
for i in range(n):
     ans = f(a[:i]+a[i+1:],ans)
print(ans)


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

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

b = [a[0]]
c = [a[-1]]

for i in range(1,n):
     j = n-1-i
     b.append(gcd(b[-1],a[i]))
     c.append(gcd(c[-1],a[j]))
     
ans = max(b[-2],c[-2])
for i in range(n):
     ans = max(ans,gcd(b[i],c[n-3-i]))
print(ans)
# Original solution
N = int(eval(input()))
As = list(map(int,input().split()))
As.sort(reverse=True)
first_d = As[0]
def make_divisors(n):
    divisors = []
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            divisors.append(i)
            if i != n // i:
                divisors.append(n//i)

    # divisors.sort()
    return divisors

if N == 2:
    print((max(As)))
else:
    first = make_divisors(As[0])
    second = make_divisors(As[1])
    
    third  = make_divisors(As[2])
    
    div_list = list((set(first) & set(second)) | (set(first) & set(third)) | (set(third) & set(second)))
    div_list.sort(reverse=True)
    
    for d in range(len(div_list)):
        cnt = 0
        for i in range(N):
            if As[i] % (div_list[d]) == 0:
                cnt += 1
        if cnt >= N-1:
            ans = div_list[d]
            break
    print(ans)



# Optimized solution
N = int(eval(input()))
As = list(map(int,input().split()))
As.sort(reverse=True)
first_d = As[0]
def make_divisors(n):
    divisors = []
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            divisors.append(i)
            if i != n // i:
                divisors.append(n//i)

    # divisors.sort()
    return divisors

if N == 2:
    print((max(As)))
else:
    first = make_divisors(As[0])
    second = make_divisors(As[1])
    third  = make_divisors(As[2])
    div_list = list((set(first) & set(second)) | (set(first) & set(third)) | (set(third) & set(second)))
    div_list.sort(reverse=True)
    
    for d in range(len(div_list)):
        cnt = 0
        for i in range(N):
            if As[i] % (div_list[d]) != 0:
                cnt += 1
                if cnt > 1:
                    break
        if cnt <= 1 :
            ans = div_list[d]
            break
    print(ans)
# Original solution
#!/usr/bin/python3
# -*- coding: utf-8 -*-
def euclid(a, b):
    if b == 0:
        return a
    else:
        return euclid(b, a%b)
def list_euclid(int_list):
    ans = int_list[0]
    for i in range(1,len(int_list)):
        ans = euclid(ans, int_list[i])
        if ans == 1:
            return ans
    return ans
n = int(eval(input()))
a = list(map(int, input().split()))
a.sort()
max = 0
b_int = 0
if n < 5:
  for i in range(0,n):
    if b_int == a[0]:
      p = a.pop(0)
      a.append(p)
    else:
      p = a.pop(0)
      b_int = p
      x = list_euclid(a)
      if max < x:
        max = x
      a.append(p)
else:
  for i in range(0,n):
    if b_int == a[0]:
      p = a.pop(0)
      a.append(p)
    else:
      p = a.pop(0)
      b_int = p
      k = len(a) // 2
      x = 0
      y = list_euclid(a[0:k])
      if y == 1:
        x = 1
      else:
        z = list_euclid(a[k:n-1])
        x = euclid(y, z)
      if max < x:
        max = x
      a.append(p)
print(max)

# Optimized solution
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys
def gcd(a, b): #最大公約数
  while b:
    a, b = b, a % b
  return int(a)
    
n = int(eval(input()))
a = list(map(int, input().split()))
if n==2:
  print((max(a)))
  sys.exit(0)
elif n==3:
  lis = [gcd(a[0], a[1]), gcd(a[1], a[2]), gcd(a[2], a[0])]
  print((max(lis)))
  sys.exit(0)
tmp_unused = gcd(a[0], a[1])
tmp_used = max(a[0], a[1])
#print("used=", tmp_used, "unused=", tmp_unused)
for i in range(2,n):
  #print(a[i])
  tmp_used = max(tmp_unused, gcd(tmp_used, a[i]))
  tmp_unused = gcd(tmp_unused, a[i])
  
  #print("used=", tmp_used, "unused=", tmp_unused)
print(tmp_used)
# Original solution
#!/usr/bin/env python3

import sys
import math
from bisect import bisect_right as br
from bisect import bisect_left as bl
sys.setrecursionlimit(2147483647)
from heapq import heappush, heappop,heappushpop
from collections import defaultdict
from itertools import accumulate
from collections import Counter
from collections import deque
from operator import itemgetter
from itertools import permutations
mod = 10**9 + 7
inf = float('inf')
def I(): return int(sys.stdin.readline())
def LI(): return list(map(int,sys.stdin.readline().split()))

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

n = I()
a = LI()
l = [0]*n
r = [0]*n
l[0] = a[0]
for i in range(1,n):
    l[i] = gcd(l[i-1],a[i])
r[-1] = a[-1]
for i in range(n-1)[::-1]:
    r[i] = gcd(r[i+1],a[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[-2])
    else:
        ans = max(ans,gcd(l[i-1],r[i+1]))
print(ans)



# Optimized solution
#!/usr/bin/env python3

import sys
import math
from bisect import bisect_right as br
from bisect import bisect_left as bl
sys.setrecursionlimit(2147483647)
from heapq import heappush, heappop,heappushpop
from collections import defaultdict
from itertools import accumulate
from collections import Counter
from collections import deque
from operator import itemgetter
from itertools import permutations
mod = 10**9 + 7
inf = float('inf')
def I(): return int(sys.stdin.readline())
def LI(): return list(map(int,sys.stdin.readline().split()))

n = I()
a = LI()
L = [0] * (n+2)
L[0] = a[0]
R = [0] * (n+2)
R[-1] = a[-1]
for i in range(n):
    L[i+1] = math.gcd(a[i], L[i])
    R[-(i+2)] = math.gcd(a[-(i+1)], R[-(i+1)])

ans = 0
for i in range(1, n+1):
    if i - 1 == 0:
        ans = max(ans, R[i+1])
    elif i == n:
        ans = max(ans, L[i-1])
    else:
        ans = max(ans, math.gcd(L[i-1], R[i+1]))
print(ans)
# Original solution
def egcd(a, b):
    (x, lastx) = (0, 1)
    (y, lasty) = (1, 0)
    while b != 0:
        q = a // b
        (a, b) = (b, a % b)
        (x, lastx) = (lastx - q * x, x)
        (y, lasty) = (lasty - q * y, y)
    return a

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

l=[0]*N
l[0]=a[0]

for i in range(1,N):
    l[i]=egcd(l[i-1],a[i])

r=[0]*N
r[N-1]=a[N-1]
for i in range(N-2,-1,-1):
    r[i]=egcd(r[i+1],a[i])

ans=0
for i in range(N):
    if i==0: tmp=r[1]
    elif i==N-1: tmp=l[N-2]
    else: tmp=egcd(l[i-1],r[i+1])
    ans=max(tmp,ans)

print(ans)

# Optimized solution
def gcd(a, b):
    (x, lastx) = (0, 1)
    (y, lasty) = (1, 0)
    while b != 0:
        q = a // b
        (a, b) = (b, a % b)
        (x, lastx) = (lastx - q * x, x)
        (y, lasty) = (lasty - q * y, y)
    return a

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

l=[0]*N
l[0]=a[0]
for i in range(1,N):
    l[i]=gcd(l[i-1],a[i])

r=[0]*N
r[N-1]=a[N-1]
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):
    tmp=gcd(l[i-1],r[i+1])
    ans=max(tmp,ans)

print(ans)
# Original solution
def gcd(a, b):
    (x, lastx) = (0, 1)
    (y, lasty) = (1, 0)
    while b != 0:
        q = a // b
        (a, b) = (b, a % b)
        (x, lastx) = (lastx - q * x, x)
        (y, lasty) = (lasty - q * y, y)
    return a

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

l=[0]*N
l[0]=a[0]
for i in range(1,N):
    l[i]=gcd(l[i-1],a[i])

r=[0]*N
r[N-1]=a[N-1]
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):
    tmp=gcd(l[i-1],r[i+1])
    ans=max(tmp,ans)

print(ans)

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

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

l=[0]*N
l[0]=a[0]
for i in range(1,N):
    l[i]=gcd(l[i-1],a[i])

r=[0]*N
r[N-1]=a[N-1]
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):
    tmp=gcd(l[i-1],r[i+1])
    ans=max(tmp,ans)

print(ans)