#include <iostream>
#include <string>
#include <vector>
#include <array>
#include <queue>
#include <deque>
#include <algorithm>
#include <set>
#include <map>
#include <bitset>
#include <cmath>
#include <functional>
#include <iomanip>
#include <cstring>
#define vll vector<ll>
#define vvvl vector<vvl>
#define vvl vector<vector<ll>>
#define VV(a, b, c, d) vector<vector<d>>(a, vector<d>(b, c))
#define VVV(a, b, c, d) vector<vvl>(a, vvl(b, vll (c, d)));
#define re(c, b) for(ll c=0;c<b;c++)
#define all(obj) (obj).begin(), (obj).end()
typedef long long int ll;
typedef long double ld;
using namespace std;

#define SPLIT 3
template<typename T>
struct PersistentArray{
  struct vertex{
    T dat;
    array<vertex*, SPLIT> ch;
    vertex(){ch.fill(nullptr);};
  };
  T zero;
  PersistentArray(){};
  PersistentArray(T z):zero(z){};
  vertex* root = nullptr;
  ll ver = 0;
  vector<vertex*> version; //指定したバージョンのルート

  inline vertex* set(ll idx, T x, vertex* par){

    vertex* now = new vertex();
    if(par) {
      now->ch = par->ch;
      now->dat = par->dat;
    }
    if(idx==0) now->dat = x;
    else now->ch[idx%SPLIT] = set(idx/SPLIT, x, now->ch[idx%SPLIT]);
    return now;
  }

  ll update(ll prev, ll idx, T x){
    vertex* now = set(idx, x, (prev==-1?root:version[prev]));
    version.push_back(now);
    return ver++;
  }

  T query(ll prev, ll idx){
    vertex* now = (prev==-1?root:version[prev]);
    if(now==nullptr) return zero;
    while(idx){
      now = now->ch[idx%SPLIT];
      idx/=SPLIT;
      if(now==nullptr) return zero;
    }
    return now->dat;
  }
};

template<typename T>
struct PersistentSegtree{
  typedef function<T(T, T)> G; //merge
  typedef function<T(T, T)> H; //update
  PersistentArray<T> dat;
  vector<ll> las; //PersistentArrayの最後のバージョン
  ll M=1, ver=0;
  G g;
  H h;
  T UNIT;
  PersistentSegtree(ll N, T unit, G merge_func, H update_func):UNIT(unit){
    dat = PersistentArray<T>(UNIT);
    g = merge_func;
    h = update_func;
    while(M<N) M*=2;
  }
  inline ll update(ll v, ll k, T x,ll l=0, ll r=-1){
    if(r==-1) r = M;
    k+=M-1;
    ll array_ver = (v==-1?-1:las[v]);
    ll num = h(dat.query(array_ver, k), x);
    ll idx = dat.update(array_ver, k, num);
    las.push_back(idx);
    while(k>0){
      k = (k-1)/2;
      T L = dat.query(las[ver], k*2+1);
      T R = dat.query(las[ver], k*2+2);
      num = g(L, R);
      las[ver] = dat.update(las[ver], k, num);
    }
    return ver++;
  }

  T query(ll v, ll a, ll b=-1, ll k=0, ll l=0, ll r=-1){
    if(r==-1) r = M;
    if(b==-1) b = M;
    if(r<=a || b<=l) return UNIT;
    if(a<=l && r<=b) return dat.query((v==-1?-1:las[v]), k);
    T A = query(v, a, b, k*2+1, l, (l+r)/2);
    T B = query(v, a, b, k*2+2, (l+r)/2, r);
    return g(A, B);
  }
};

ll gcd(ll a, ll b){
  if(b<a) swap(a, b);
  ll r = a % b;
  if(r==0) return b;
  while(r!=0) r = a % b, a = b, b = r;
  return a;
}

ll mg(ll l, ll r){
  if(l==0) return r;
  if(r==0) return l;
  return gcd(l, r);
}
ll upd(ll old, ll nw){
  return nw;
}

int main(){
  ll n;std::cin >> n;
  PersistentSegtree<int> seg(n+1, 0, mg, upd);
  ll v = -1;

  for(int i=0;i<n;i++){
    ll t;scanf("%lld", &t);
    v = seg.update(v, i, t);
  }
  ll ans = 0;
  for(int i=0;i<n;i++){
    ll L = seg.query(v, 0, i);
    ll R = seg.query(v, i+1, n);
    ans = max(ans, gcd(L, R));
  }
  std::cout << ans << '\n';
}


Measured memory_bytes: 614100