#include <bits/stdc++.h>
using namespace std;
#define IO ios_base::sync_with_stdio(false); cin.tie(NULL);

#define endl '\n'
#define D(x) cout << #x << " = " << (x) << endl;

const int debug = 0;

class segment_tree {
public:
  vector<int> value, node, lazy;

  segment_tree(vector<int> v) {
    value = v;
    node.resize(4 * value.size());

    lazy.resize(4 * value.size());
  }

  void build(int at, int left_segment, int right_segment) {
    if (debug) cout << "[build] at: " << at << ", left: " << left_segment << ", right: " << right_segment << endl;

    if (right_segment - left_segment == 1) {
      node[at] = value[left_segment];
    } else {
      int mid = (left_segment + right_segment) / 2;
      build(at * 2, left_segment, mid);
      build(at * 2 + 1, mid, right_segment);
      node[at] = combine(node[at * 2], node[at * 2 + 1]);
    }
  }

  void push(int at, int left_segment, int right_segment) {
    int mid = (left_segment + right_segment) / 2;
    update(at * 2, lazy[at], left_segment, mid);
    update(at * 2 + 1, lazy[at], mid, right_segment);
    lazy[at] = 0;
  }

  void modify(int at, int by, int left_operation, int right_operation, int left_segment, int right_segment) {
    if (right_segment <= left_operation or right_operation <= left_segment) {
      return;
    }

    if (left_operation <= left_segment and right_segment <= right_operation) {
      update(at, by, left_segment, right_segment);
      return;
    }

    push(at, left_segment, right_segment);

    int mid = (left_segment + right_segment) / 2;
    modify(at * 2, by, left_operation, right_operation, left_segment, mid);
    modify(at * 2 + 1, by, left_operation, right_operation, mid, right_segment);
    node[at] = combine(node[at * 2], node[at * 2 + 1]);
  }

  int query(int at, int left_query, int right_query, int left_segment, int right_segment) {
    if (right_segment <= left_query or right_query <= left_segment) {
      return 0;
    }

    if (left_query <= left_segment and right_segment <= right_query) {
      if (debug) cout << "[query] at: " << at << ", left_query: " << left_query << ", right_query: " << right_query;
      if (debug) cout << ", left_segment: " << left_segment << ", right_segment: " << right_segment << " => ret: " << node[at] << endl;

      return node[at];
    }

    push(at, left_segment, right_segment);

    int mid = (left_segment + right_segment) / 2;
    int ret = combine(query(at * 2, left_query, right_query, left_segment, mid),
               query(at * 2 + 1, left_query, right_query, mid, right_segment));

    if (debug) cout << "[query] at: " << at << ", left_query: " << left_query << ", right_query: " << right_query;
    if (debug) cout << ", left_segment: " << left_segment << ", right_segment: " << right_segment << " => ret: " << ret << endl;

    return ret;
  }

  void update(int at, int by, int left_segment, int right_segment) {
    lazy[at] += by;
    node[at] += by;
  }

  int combine(int left, int right) {
    if (left == 0 or right == 0) {
      return max(left, right);
    }

    return __gcd(left, right);
  }
};

int main() { IO;
  int n;
  cin >> n;

  vector<int> v(n);
  for (auto &x : v) cin >> x;

  segment_tree st(v);
  st.build(1, 0, n);

  int ans = 1;
  for (int i = 0; i < n; ++i) {
    int left = 0, right = 0;
    if (i) left = st.query(1, 0, i, 0, n);
    if (i < n - 1) right = st.query(1, i + 1, n, 0, n);

    int g = left;
    if (right) g = __gcd(g, right);
    ans = max(ans, g);
  }
  cout << ans << endl;

  return 0;
}


Measured memory_bytes: 4608