#define _USE_MATH_DEFINES
#include<math.h>

//#include<cmath>

#include<deque>
#include<queue>
#include<vector>
#include<algorithm>
#include<iostream>
#include<set>
#include<cmath>
#include<tuple>
#include<string>
#include<chrono>
#include<functional>
#include<iterator>
#include<random>
#include<unordered_set>
#include<array>
#include<map>
#include<iomanip>
#include<assert.h>
#include<bitset>
#include<stack>
#include<memory>



//#include "Ants.h"
using namespace std;
typedef long long ll;
#define EPS (1e-7)
#define INF (1e9)
#define PI (acos(-1))
typedef pair < int, int> P;
/****Union-Ford-Tree***/
int par[int(0x7ffffff)];//Parent
int Rank[int(0x7ffffff)];//Deep_of_the_Tree

//int a[100] = { 4,2,3,1,5 }, m[100] ={3,2,2};
//int n = 0;
//const ll mod = 1000000007;


//n要素で初期化
void init(int n) {
	for (int i = 0; i < n; i++) {
		par[i] = i;
		Rank[i] = 0;
	}
}
//木の根探し
int find(int x) {
	if (par[x] == x) {
		return x;
	}
	else {
		return par[x] = find(par[x]);
	}
}
//xとyの属する集合を併合
void unite(int x, int y) {
	x = find(x);
	y = find(y);
	if (x == y)return;

	if (Rank[x] < Rank[y]) {
		par[x] = y;
	}
	else {
		par[y] = x;
		if (Rank[x] == Rank[y])Rank[x]++;
	}
}

bool same(int x, int y) {
	return find(x) == find(y);
}

/************************************************************************************
//*無向グラフのBELL_MAN_FORD;*//*
struct edge { int from, to, cost; };
edge es[10000];
int d[10000];
void shortest_path(int s) {
	for (int i = 0; i < V; i++)d[i] = INF;
	d[s] = 0;
	while (true) {
		bool update = false;
		for (int i = 0; i < E*2; i++) {
			edge e = es[i];
			if (d[e.from] != INF && d[e.to] > d[e.from] + e.cost) {
				d[e.to] = d[e.from] + e.cost;
				update = true;
			}
		}
		if (!update)break;
	}

}
int main() {
	cin >> V >> E;
	for (int i = 0; i < E*2; i = i+2) {
		edge e;
		cin >> e.from >> e.to >> e.cost;
		es[i] = e;
		swap(e.to, e.from);
		es[i + 1] = e;

	}
	shortest_path(0);
	cout << d[6] << endl;
}
*////////////////////////////////////////*
int gcd(int a, int b) {//最大公約数を求める
	if (b == 0) return a;
	return gcd(b, a%b);
}
/*****************************************************************************/
//int dx[4] = { 1,0,-1,0 }, dy[4] = { 0,1,0,-1};
//vector<int> G[10000];


//struct edge { int to, cost; };
//vector<edge>G[100000];


/**************/


/****
//priority_queue<int> //大きいものから順番に出てくる
//priority_queue<int,vector<int>,greater<int>>//小さいものから出てくる（順位キュー）
.top();
.pop();
.empty();
**/
//void solve();
//int V, E;
//void shortest_path(int);
typedef long double ld;
typedef unsigned long long ull;
const int MX = 3007;


int N, A[100000];
int main()
{
	cin >> N;
	for (int i = 0; i < N; i++)cin >> A[i];
	sort(A, A + N);
	int pos=0,pre=INF;
	/*for (int i = 0; i < N; i++) {
		int res = 0;
		for (int j = 0; j < N; j++) {
			if (i == j)continue;
			res = max(res,gcd(A[i], A[j]));
		}
		//cout << res << endl;
		if (pre > res) {
			pre = res;
			pos = i;
		}
	}*/
	int res = A[0];
	pre = res;
	for (int i = 1; i < N; i++) {
		res = gcd(res, A[i]);
		if (pre > res) {
			pre = res;
			pos = i;
		}
	}
	//cout << pos << endl;
	//cout << pos << endl;
	const int restore = A[0];
	A[0] = 0;
	res = A[0];
	for (int i = 1; i < N; i++) {
		res = gcd(res, A[i]);
	}
	
	A[0] = restore;
	A[pos] = 0;
	int ans = A[0];
	for (int i = 1; i < N; i++) {
		//cout << ans << endl;
		ans = gcd(ans, A[i]);
	

	}
	if (0 == max(ans, res)) {
		cout << restore << endl;
		return 0;
	}
	cout << max(ans, res) << endl;

	
	
	
}

Measured memory_bytes: 640