// Original C++ solution (slower):
#define _USE_MATH_DEFINES

#include <cassert>

#include <cstdio>

#include <cstring>

#include <iostream>

#include <string>

#include <sstream>

#include <vector>

#include <queue>

#include <stack>

#include <list>

#include <set>

#include <map>

#include <unordered_set>

#include <unordered_map>

#include <algorithm>

#include <complex>

#include <cmath>

#include <numeric>

#include <bitset>

#include <functional>

#include <random>

#include <ctime>



using namespace std;



#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)

template <typename Arg1>

void __f(const char* name, Arg1&& arg1){

  cerr << name << ": " << arg1 << endl;

}

template <typename Arg1, typename... Args>

void __f(const char* names, Arg1&& arg1, Args&&... args){

  const char* comma = strchr(names + 1, ',');

  cerr.write(names, comma - names) << ": " << arg1 << " |";

  __f(comma + 1, args...);

}



typedef long long int64;

typedef pair<int, int> ii;

const int INF = 1 << 29;

const int MOD = 1e9 + 7;



int gcd(int a, int b) {

  while (b) {

    int c = a;

    a = b;

    b = c % b;

  }

  return a;

}



int main() {

  int n;

  scanf("%d", &n);

  vector<int> a(n);

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

    scanf("%d", &a[i]);

  }

  sort(a.begin(), a.end());

  int best = 1;

  for (int k = 1; k * k <= a[0]; ++k) {

    if (a[0] % k) continue;

    int cnt = 0;

    for (int i = 1; i < n; ++i) {

      cnt += (a[i] % k == 0);

    }

    if (cnt >= n - 2) best = max(best, k);

    cnt = 0;

    int u = a[0] / k;

    for (int i = 1; i < n; ++i) {

      cnt += (a[i] % u == 0);

    }

    if (cnt >= n - 2) best = max(best, u);

  }

  int g = a[1];

  for (int i = 2; i < n; ++i) {

    g = gcd(g, a[i]);

  }

  best = max(best, g);

  printf("%d\n", best);

  return 0;

}


// Optimized solution to the same problem (faster):
#define _USE_MATH_DEFINES

#include <cassert>

#include <cstdio>

#include <cstring>

#include <iostream>

#include <string>

#include <sstream>

#include <vector>

#include <queue>

#include <stack>

#include <list>

#include <set>

#include <map>

#include <unordered_set>

#include <unordered_map>

#include <algorithm>

#include <complex>

#include <cmath>

#include <numeric>

#include <bitset>

#include <functional>

#include <random>

#include <ctime>



using namespace std;



#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)

template <typename Arg1>

void __f(const char* name, Arg1&& arg1){

  cerr << name << ": " << arg1 << endl;

}

template <typename Arg1, typename... Args>

void __f(const char* names, Arg1&& arg1, Args&&... args){

  const char* comma = strchr(names + 1, ',');

  cerr.write(names, comma - names) << ": " << arg1 << " |";

  __f(comma + 1, args...);

}



typedef long long int64;

typedef pair<int, int> ii;

const int INF = 1 << 29;

const int MOD = 1e9 + 7;



int gcd(int a, int b) {

  while (b) {

    int c = a;

    a = b;

    b = c % b;

  }

  return a;

}



int main() {

  int n;

  scanf("%d", &n);

  vector<int> a(n);

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

    scanf("%d", &a[i]);

  }

  vector<int> L(n), R(n);

  L[0] = a[0];

  for (int i = 1; i < n; ++i) {

    L[i] = gcd(L[i - 1], a[i]);

  }

  R[n - 1] = a[n - 1];

  for (int i = n - 2; i >= 0; --i) {

    R[i] = gcd(R[i + 1], a[i]);

  }

  int best = max(L[n - 2], R[1]);

  for (int i = 1; i < n - 1; ++i) {

    best = max(best, gcd(L[i - 1], R[i + 1]));

  }

  printf("%d\n", best);

  return 0;

}


// Fastest known solution for this problem: