// Slower C++ solution:
// #define _GLIBCXX_DEBUG // for STL debug (optional)

#include <iostream>

#include <iomanip>

#include <cstdio>

#include <string>

#include <cstring>

#include <deque>

#include <list>

#include <queue>

#include <stack>

#include <vector>

#include <utility>

#include <algorithm>

#include <map>

#include <set>

#include <complex>

#include <cmath>

#include <limits>

#include <cfloat>

#include <climits>

#include <ctime>

#include <cassert>

#include <numeric>

#include <fstream>

#include <functional>

#include <bitset>

#include <unordered_map>

using namespace std;



#define debug(...) fprintf(stderr, __VA_ARGS__)

#define int long long int

 

template<typename T> void chmax(T &a, T b) {a = max(a, b);}

template<typename T> void chmin(T &a, T b) {a = min(a, b);}

template<typename T> void chadd(T &a, T b) {a = a + b;}

 

typedef pair<int, int> pii;

typedef long long ll;

 

int dx[] = {0, 0, 1, -1};

int dy[] = {1, -1, 0, 0};

const ll INF = 1001001001001001LL;

const ll MOD = 1000000007LL;



// 約数全列挙

vector<ll> OutDivisor(ll n) {

    vector<ll> ret;

    for(ll i=1; i*i<=n; i++) {

        if(n % i == 0) {

            ret.push_back(i);

            if(i*i!=n) ret.push_back(n / i);

        }

    }

    return ret;

}



map<int, int> mp;

signed main() {

    int N; cin >> N;

    vector<int> A(N);

    for(int i=0; i<N; i++) {

        cin >> A[i];

    }



    set<int> cand;

    for(int i=0; i<min(N, 2LL); i++) {

        auto vec = OutDivisor(A[i]);

        for(auto e : vec) cand.insert(e);

    }



    for(int i=0; i<N; i++) {

        for(auto e : cand) {

            if(A[i] % e == 0) mp[e]++;

        }

    }



    int ans = 0;

    for(auto e : mp) {

        if(e.second >= N-1) chmax(ans, e.first);

    }

    cout << ans << endl;

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.359713663470908x):
#include <vector>

#include <algorithm>

#include <functional>

#include <iostream>

using namespace std;



// 累積演算 (0-indexed・prefix, suffix, 任意連続部分列)

// 任意連続部分列は逆演算があるときのみできる？



template <typename MonoidType>

struct Accumulation {

    int n;

    vector<MonoidType> val_array, pre, suf;

    MonoidType E;

    

    using MMtoM = function< MonoidType(MonoidType, MonoidType) >;

    MMtoM op, rop;



    void build(int m, vector<MonoidType> vec) {

        pre = suf = vector<MonoidType>(m+1, E);

        for(int i=0; i<m; i++) {

            pre[i+1] = op(pre[i], vec[i]);

        }

        for(int i=m-1; i>=0; i--) {

            suf[i] = op(suf[i+1], vec[i]);

        }

    }



    Accumulation() {}

    Accumulation(vector<MonoidType> val_array_, MonoidType E_,

                 MMtoM op_, MMtoM rop_ = MMtoM()) :

        val_array(val_array_), E(E_), op(op_), rop(rop_) {

        n = val_array_.size();

        build(n, val_array);

    }



    // [0, k)

    inline MonoidType get_prefix(int k) { return pre[k]; }

    // [k, n)

    inline MonoidType get_suffix(int k) { return suf[k]; }

    // [l, r) (rop が定義されてるときのみ)

    inline MonoidType get_subseq(int l, int r) {

        return rop(pre[r], pre[l]);

    }

};





int gcd(int a, int b) {

    return b == 0 ? a : gcd(b, a%b);

}



// Verified on Apr 28, 2019 (prefix, suffix のみ)

// Judge: https://atcoder.jp/contests/abc125/tasks/abc125_c

void ABC125_C() {

    int N; cin >> N;

    vector<int> A(N);

    for(int i=0; i<N; i++) {

        cin >> A[i];

    }

    

    Accumulation<int> acc(A, 0,

                          [](int a, int b) { return gcd(a, b); });



    int ans = 0;

    for(int i=0; i<N; i++) {

        int vl = acc.get_prefix(i), vr = acc.get_suffix(i+1);

        ans = max(ans, gcd(vl, vr));

    }

    cout << ans << endl;

}



int main() {

    ABC125_C();

    return 0;

}