#include <bits/stdc++.h>
using namespace std;
using namespace __gnu_cxx;
#define dprint(v) cout << #v"=" << v << endl //;)
#define sz(c) ((int)c.size())
#define zero(v) memset(v, 0, sizeof(v))
#define forall(it,v) for(auto it=v.begin();it!=v.end();++it)
#define mp make_pair
#define ff first
#define ss second
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define forn(i, n) for (int i = 0; i < (int)(n); ++i)
#define for1(i, n) for (int i = 1; i <= (int)(n); ++i)
#define ford(i, n) for (int i = (int)(n) - 1; i >= 0; --i)
#define fore(i, a, b) for (int i = (int)(a); i <= (int)(b); ++i)
#define INF (ll)1e16
#define endl '\n'
#define isin(x,y) ((y).find(x)!=(y).end())
#define forr(i,a,b) for(int i=(a); i<(b); i++)

typedef long long ll;
typedef long long lli;
typedef pair<ll, ll> pll;
typedef vector<ll> vll;
typedef vector<vll> vvll;

typedef pair<int,int> ii;
#define pb push_back
#define fst first
#define snd second

/*#define MAXP 100000	//no necesariamente primo
int criba[MAXP+1];
void crearcriba(){
	int w[] = {4,2,4,2,4,6,2,6};
	for(int p=25;p<=MAXP;p+=10) criba[p]=5;
	for(int p=9;p<=MAXP;p+=6) criba[p]=3; 
	for(int p=4;p<=MAXP;p+=2) criba[p]=2;
	for(int p=7,cur=0;p*p<=MAXP;p+=w[cur++&7]) if (!criba[p]) 
		for(int j=p*p;j<=MAXP;j+=(p<<1)) if(!criba[j]) criba[j]=p;
}

vector<int> primos;
void buscarprimos(){
	crearcriba();
	forr (i,2,MAXP+1) if (!criba[i]) primos.push_back(i);
}

//factoriza bien numeros hasta MAXP^2
map<ll,ll> fact(ll n){ //O (cant primos)
	map<ll,ll> ret;
	forall(p, primos){
		while(!(n%*p)){
			ret[*p]++;//divisor found
			n/=*p;
		}
	}
	if(n>1) ret[n]++;
	return ret;
}*/

// To store segment tree 
int *st; 
  
// Function to find gcd of 2 numbers. 
int gcd(int a, int b) 
{ 
    if (a < b) 
        swap(a, b); 
    if (b==0) 
        return a; 
    return gcd(b, a%b); 
} 
  
/*  A recursive function to get gcd of given 
    range of array indexes. The following are parameters for 
    this function. 
  
    st    --> Pointer to segment tree 
    si --> Index of current node in the segment tree. Initially 
               0 is passed as root is always at index 0 
    ss & se  --> Starting and ending indexes of the segment 
                 represented by current node, i.e., st[index] 
    qs & qe  --> Starting and ending indexes of query range */
int findGcd(int ss, int se, int qs, int qe, int si) 
{ 
    if (ss>qe || se < qs) 
        return 0; 
    if (qs<=ss && qe>=se) 
        return st[si]; 
    int mid = ss+(se-ss)/2; 
    return gcd(findGcd(ss, mid, qs, qe, si*2+1), 
               findGcd(mid+1, se, qs, qe, si*2+2)); 
} 
  
//Finding The gcd of given Range 
int findRangeGcd(int ss, int se, int arr[],int n) 
{ 
    if (ss<0 || se > n-1 || ss>se) 
    { 
        return -1; 
    } 
    return findGcd(0, n-1, ss, se, 0); 
} 
  
// A recursive function that constructs Segment Tree for 
// array[ss..se]. si is index of current node in segment 
// tree st 
int constructST(int arr[], int ss, int se, int si) 
{ 
    if (ss==se) 
    { 
        st[si] = arr[ss]; 
        return st[si]; 
    } 
    int mid = ss+(se-ss)/2; 
    st[si] = gcd(constructST(arr, ss, mid, si*2+1), 
                 constructST(arr, mid+1, se, si*2+2)); 
    return st[si]; 
} 
  
/* Function to construct segment tree from given array. 
   This function allocates memory for segment tree and 
   calls constructSTUtil() to fill the allocated memory */
int *constructSegmentTree(int arr[], int n) 
{ 
   int height = (int)(ceil(log2(n))); 
   int size = 2*(int)pow(2, height)-1; 
   st = new int[size]; 
   constructST(arr, 0, n-1, 0); 
   return st; 
} 
  
// Driver program to test above functions 
int main() 
{ 
    int n;
    cin>>n;
    int a[n];
    forn(i,n)cin>>a[i];
    if(n==2){
        cout<<max(a[0],a[1])<<endl;
        return 0;
    }
    constructSegmentTree(a,n);
    int ans=-1;
    for(int i=0;i<n;i++){
        if(!i){
            ans=max(findRangeGcd(1,n-1,a,n),ans);
            continue;
        }
        if(i==n-1){
            ans=max(findRangeGcd(0,n-2,a,n),ans);
            continue;
        }
        ans=max(gcd(findRangeGcd(0,i-1,a,n),findRangeGcd(i+1,n-1,a,n)),ans);
    }
    cout<<ans<<endl;
    return 0; 
} 


Measured memory_bytes: 1664