#include <functional>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <tuple>
#include <set>
#include <map>

#define FOR0(var, max) for (ul (var) = 0; (var) < (max); ++(var))
#define FORi(var, min, max) for (ul (var) = (min); (var) < (max); ++(var))
#define FORi_INV(var, min, max) for (ul (var) = (max) - 1; (var) + 1 > (min); --(var))
#define FORITER(var, iter) for (auto (iter) = (var).begin(); (iter) != (var).end(); (iter)++)
#define FORITER_INV(var, iter) for (auto (iter) = (var).rbegin(); (iter) != (var).rend(); (iter)++)

#define LTLT(a, b, c) (((a) < (b)) && ((b) < (c)))
#define LELT(a, b, c) (((a) <= (b)) && ((b) < (c)))
#define LTLE(a, b, c) (((a) < (b)) && ((b) <= (c)))
#define LELE(a, b, c) (((a) <= (b)) && ((b) <= (c)))

using namespace std;

using uc = unsigned char;
using ui = unsigned int;
using ul = unsigned long long int;

using sc = signed char;
using si = signed int;
using sl = signed long long int;

template <class T>
T gcd(T a, T b) {
  while (b) {
    T t = a % b;
    a = b;
    b = t;
  }
  return a;
}

/* (identity element, operation) */
template <class T>
using Monoid = pair<T, function<T(T, T)>>;

template <class T, ui K>
class SegmentTree {
  const Monoid<T> monoid;
  const ul N = (1 << K);
  T tree[2 * (1 << K) - 1];

  inline ui parent(ui i) const {
    if (i == 0) {
      return 0;
    }
    return (i - 1) / 2;
  }

  inline ui leaf(ui i) const {
    return i + N - 1;
  }

  inline ui left(ui i) const {
    return i * 2 + 1;
  }

  inline ui right(ui i) const {
    return i * 2 + 2;
  }

  inline bool is_leaf(ui i) const {
    return (N - 1 <= i);
  }

  inline bool is_root(ui i) const {
    return i == 0;
  }

  inline ui root(void) const {
    return 0;
  }

public:
  /* Initialize Segment Tree with Monoid `_monoid` */
  SegmentTree(const Monoid<T>& _monoid, const T& default_value) : monoid(_monoid) {
    queue<ui> Q;
    FOR0(i, N) {
      tree[leaf(i)] = default_value;
      if (i % 2 == 0) {
        Q.push(parent(leaf(i)));
      }
    }
    while (!Q.empty()) {
      auto v = Q.front();
      Q.pop();
      tree[v] = monoid.second(tree[left(v)], tree[right(v)]);
      if (!is_root(v)) {
        if (left(parent(v)) == v) {
          Q.push(parent(v));
        }
      }
    }
  }

  SegmentTree(const Monoid<T>& _monoid)
      : SegmentTree(_monoid, _monoid.first) {
  }

  void update(ui i, T x) {
    ui cur = leaf(i);
    tree[cur] = x;
    while (!is_root(cur)) {
      cur = parent(cur);
      tree[cur] = monoid.second(tree[left(cur)], tree[right(cur)]);
    }
  }

  // [a, b)
  T query(ui a, ui b) {
    if (a == b) {
      throw invalid_argument("[a, a)");
    }
    T resL = monoid.first;
    T resR = monoid.first;
    ui vL = leaf(a);
    ui vR = leaf(b - 1);
    while (vL != vR) {
      if (right(parent(vL)) == vL) {
        resL = monoid.second(resL, tree[vL]);
        vL = vL + 1;
      }
      if (vL == vR) {
        break;
      }
      if (left(parent(vR)) == vR) {
        resR = monoid.second(tree[vR], resR);
        vR = vR - 1;
      }
      vL = parent(vL);
      vR = parent(vR);
    }
    resL = monoid.second(resL, tree[vL]);
    return monoid.second(resL, resR);
  }
};
const static ul NMAX = 100000;
const static ul SEGNMAX = (1 << 17);
const static ul AiMAX = 1000000000;

static ul N;
static ul Ai[NMAX];

static Monoid<ul> monoid = make_pair(0ULL, gcd<ul>);
static SegmentTree<ul, 17> tree(monoid);

void solve(void) {
  FOR0(i, N) {
    tree.update(i, Ai[i]);
  }
  ul res = 0;
  FOR0(i, N) {
    ul t = 0;
    if (0 != i) {
      t = tree.query(0, i);
    }
    if (i + 1 != N) {
      t = gcd(t, tree.query(i + 1, N));
    }
    if (res < t) {
      res = t;
    }
  }
  cout << res << endl;
}

int main(void) {
  cin >> N;
  FOR0(i, N) {
    cin >> Ai[i];
  }
  solve();
  return 0;
}

Measured memory_bytes: 3180