#include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;

//constexpr long long int MOD = 1000000007;
//constexpr int MOD = 1000000007;
//constexpr int MOD = 998244353;
constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-9;

//int N, M, K, H, W, L, R;
long long int N, M, K, H, W, L, R;

vector<int> Prime(int num) {
	vector<int>ret;
	ret.push_back(2);
	ret.push_back(3);
	for (int i = 5; i <= num; i += 6) {
		bool flag = true;
		for (int j = 2; j < ret.size(); j++) {
			if (ret[j] * ret[j] > i)break;
			if (i%ret[j] == 0) {
				flag = false;
				break;
			}
		}
		if (flag)ret.push_back(i);
		flag = true;
		for (int j = 2; j < ret.size(); j++) {
			if (ret[j] * ret[j] > i + 2)break;
			if ((i + 2) % ret[j] == 0) {
				flag = false;
				break;
			}
		}
		if (flag)ret.push_back(i + 2);
	}
	return ret;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	auto P = Prime(1000000);
	vector<int>conv(1000001, -1);
	for (int i = 0; i < P.size(); i++) {
		conv[P[i]] = i;
	}
	cin >> N;
	vector<bitset<78500>>bs(N + 1);
	int ans = MOD;
	unordered_map<bitset<78500>, int>mp;
	mp[bs[0]] = 0;
	for (int i = 1; i <= N; i++) {
		cin >> M;
		bs[i] ^= bs[i - 1];
		for (int j = 0; P[j] * P[j] <= M; j++) {
			while (M%P[j] == 0) {
				bs[i].flip(j);
				M /= P[j];
			}
		}
		if (M > 1) {
			bs[i].flip(conv[M]);
		}
		if (mp.find(bs[i]) != mp.end()) {
			ans = min(ans, i - mp[bs[i]]);
		}
		mp[bs[i]] = i;
	}
	if (ans == MOD)ans = -1;
	cout << ans << endl;
}


#include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;

//constexpr long long int MOD = 1000000007;
//constexpr int MOD = 1000000007;
//constexpr int MOD = 998244353;
constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-9;

//int N, M, K, H, W, L, R;
long long int N, M, K, H, W, L, R;

vector<int> Prime(int num) {
	vector<int>ret;
	ret.push_back(2);
	ret.push_back(3);
	for (int i = 5; i <= num; i += 6) {
		bool flag = true;
		for (int j = 2; j < ret.size(); j++) {
			if (ret[j] * ret[j] > i)break;
			if (i%ret[j] == 0) {
				flag = false;
				break;
			}
		}
		if (flag)ret.push_back(i);
		flag = true;
		for (int j = 2; j < ret.size(); j++) {
			if (ret[j] * ret[j] > i + 2)break;
			if ((i + 2) % ret[j] == 0) {
				flag = false;
				break;
			}
		}
		if (flag)ret.push_back(i + 2);
	}
	return ret;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	auto P = Prime(1000000);
	vector<int>conv(1000001, -1);
	for (int i = 0; i < P.size(); i++) {
		conv[P[i]] = i;
	}
	vector<int>box(78500);
	for (int i = 0; i < 78500; i++)box[i] = i;
	shuffle(box.begin(), box.end(),rand());
	cin >> N;
	bitset<78500>bs;
	int ans = MOD;
	unordered_map<long long , int>mp;
	hash<bitset<78500>>h;
	mp[h(bs)] = 0;
	for (int i = 1; i <= N; i++) {
		cin >> M;
		for (int j = 0; P[j] * P[j] <= M; j++) {
			while (M%P[j] == 0) {
				bs.flip(box[j]);
				M /= P[j];
			}
		}
		if (M > 1) {
			bs.flip(box[conv[M]]);
		}
		if (mp.find(h(bs)) != mp.end()) {
			ans = min(ans, i - mp[h(bs)]);
		}
		mp[h(bs)] = i;
	}
	if (ans == MOD)ans = -1;
	cout << ans << endl;
}


#include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;

//constexpr long long int MOD = 1000000007;
//constexpr int MOD = 1000000007;
//constexpr int MOD = 998244353;
constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-9;

//int N, M, K, H, W, L, R;
long long int N, M, K, H, W, L, R;

vector<int> Prime(int num) {
	vector<int>ret;
	ret.push_back(2);
	ret.push_back(3);
	for (int i = 5; i <= num; i += 6) {
		bool flag = true;
		for (int j = 2; j < ret.size(); j++) {
			if (ret[j] * ret[j] > i)break;
			if (i%ret[j] == 0) {
				flag = false;
				break;
			}
		}
		if (flag)ret.push_back(i);
		flag = true;
		for (int j = 2; j < ret.size(); j++) {
			if (ret[j] * ret[j] > i + 2)break;
			if ((i + 2) % ret[j] == 0) {
				flag = false;
				break;
			}
		}
		if (flag)ret.push_back(i + 2);
	}
	return ret;
}

void Search(vector<vector<int>>&edge, vector<int>&dis, int &ans, int node) {
	for (auto i : edge[node]) {
		if (dis[i] == MOD) {
			dis[i] = dis[node] + 1;
			Search(edge,dis,ans,i);
		}
		else {
			if(dis[i]<dis[node]-1)ans = min(ans, dis[node] - dis[i]+1);
		}
	}
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	auto P = Prime(1000000);
	vector<int>conv(1000001, -1);
	for (int i = 0; i < P.size(); i++) {
		conv[P[i]] = i;
	}
	conv[1] = P.size();
	vector<vector<int>>edge(P.size() + 1);
	cin >> N;
	int ans = MOD;
	for (int i = 0; i < N; i++) {
		cin >> M;
		for (int j = 0; P[j]*P[j] <= M; j++) {
			if (M%P[j] == 0) {
				int cnt = 0;
				while (M%P[j] == 0) {
					M /= P[j];
					cnt++;
				}
				if (cnt & 1) {
					edge[j].push_back(conv[M]);
					edge[conv[M]].push_back(j);
				}
				else {
					edge[conv[1]].push_back(conv[M]);
					edge[conv[M]].push_back(conv[1]);
				}
				M = 0;
				break;
			}
		}
		if (M) {
			if (M == 1) {
				cout << 1 << endl;
				return 0;
			}
			edge[conv[1]].push_back(conv[M]);
			edge[conv[M]].push_back(conv[1]);
		}
	}
	for (int i = 0; i <= P.size(); i++) {
		sort(edge[i].begin(), edge[i].end());
		for (int j = 1; j < edge[i].size(); j++) {
			if (edge[i][j] == edge[i][j - 1]) {
				cout << 2 << endl;
				return 0;
			}
		}
	}
	for (int i = 0; i < 200; i++) {
		vector<int>dis(P.size(), MOD);
		dis[i] = 0;
		Search(edge,dis,ans,i);
	}
	vector<int>dis(P.size(), MOD);
	dis[P.size()] = 0;
	Search(edge, dis, ans, P.size());
	if (ans == MOD)ans = -1;
	cout << ans << endl;
}


#include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;

//constexpr long long int MOD = 1000000007;
//constexpr int MOD = 1000000007;
//constexpr int MOD = 998244353;
constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-9;

//int N, M, K, H, W, L, R;
long long int N, M, K, H, W, L, R;

vector<int> Prime(int num) {
	vector<int>ret;
	ret.push_back(2);
	ret.push_back(3);
	for (int i = 5; i <= num; i += 6) {
		bool flag = true;
		for (int j = 2; j < ret.size(); j++) {
			if (ret[j] * ret[j] > i)break;
			if (i%ret[j] == 0) {
				flag = false;
				break;
			}
		}
		if (flag)ret.push_back(i);
		flag = true;
		for (int j = 2; j < ret.size(); j++) {
			if (ret[j] * ret[j] > i + 2)break;
			if ((i + 2) % ret[j] == 0) {
				flag = false;
				break;
			}
		}
		if (flag)ret.push_back(i + 2);
	}
	return ret;
}

void Search(vector<vector<int>>&edge, vector<int>&dis, int &ans, int node) {
	for (auto i : edge[node]) {
		if (dis[i] == MOD) {
			dis[i] = dis[node] + 1;
			Search(edge,dis,ans,i);
		}
		else {
			if(dis[i]<dis[node]-1)ans = min(ans, dis[node] - dis[i]+1);
		}
	}
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	auto P = Prime(1000000);
	cout << P[200] << endl;
	vector<int>conv(1000001, -1);
	for (int i = 0; i < P.size(); i++) {
		conv[P[i]] = i;
	}
	conv[1] = P.size();
	vector<vector<int>>edge(P.size() + 1);
	cin >> N;
	int ans = MOD;
	for (int i = 0; i < N; i++) {
		cin >> M;
		vector<int>box;
		for (int j = 0; P[j] * P[j] <= M; j++) {
			while (M%P[j]==0) {
				if (box.size() && box.back() == j)box.pop_back();
				else box.push_back(j);
				M /= P[j];
			}
		}
		if (M > 1)box.push_back(conv[M]);
		if (box.size() == 0) {
			cout << 1 << endl;
			return 0;
		}
		else if (box.size() == 1) {
			edge[conv[1]].push_back(box.back());
			edge[box.back()].push_back(conv[1]);
		}
		else {
			edge[box.front()].push_back(box.back());
			edge[box.back()].push_back(box.front());
		}

	}
	for (int i = 0; i <= P.size(); i++) {
		sort(edge[i].begin(), edge[i].end());
		for (int j = 1; j < edge[i].size(); j++) {
			if (edge[i][j] == edge[i][j - 1]) {
				cout << 2 << endl;
				return 0;
			}
		}
	}
	for (int i = 0; i < 300; i++) {
	//	cout << i << endl;
		vector<int>dis(P.size()+1, MOD);
		dis[i] = 0;
		Search(edge,dis,ans,i);
	}
	vector<int>dis(P.size()+1, MOD);
	dis[P.size()] = 0;
	Search(edge, dis, ans, P.size());
	if (ans == MOD)ans = -1;
	cout << ans << endl;
}


#include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;

//constexpr long long int MOD = 1000000007;
//constexpr int MOD = 1000000007;
//constexpr int MOD = 998244353;
constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-9;

//int N, M, K, H, W, L, R;
long long int N, M, K, H, W, L, R;

vector<int> Prime(int num) {
	vector<int>ret;
	ret.push_back(2);
	ret.push_back(3);
	for (int i = 5; i <= num; i += 6) {
		bool flag = true;
		for (int j = 2; j < ret.size(); j++) {
			if (ret[j] * ret[j] > i)break;
			if (i%ret[j] == 0) {
				flag = false;
				break;
			}
		}
		if (flag)ret.push_back(i);
		flag = true;
		for (int j = 2; j < ret.size(); j++) {
			if (ret[j] * ret[j] > i + 2)break;
			if ((i + 2) % ret[j] == 0) {
				flag = false;
				break;
			}
		}
		if (flag)ret.push_back(i + 2);
	}
	return ret;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	auto P = Prime(1000000);
	vector<int>conv(1000001, -1);
	for (int i = 0; i < P.size(); i++) {
		conv[P[i]] = i;
	}
	cin >> N;
	bitset<78500>bs;
	int ans = MOD;
	unordered_map<bitset<78500>, int>mp;
	mp[bs] = 0;
	for (int i = 1; i <= N; i++) {
		cin >> M;
		for (int j = 0; P[j] * P[j] <= M; j++) {
			while (M%P[j] == 0) {
				bs.flip(j);
				M /= P[j];
			}
		}
		if (M > 1) {
			bs.flip(conv[M]);
		}
		if (mp.find(bs) != mp.end()) {
			ans = min(ans, i - mp[bs]);
		}
		mp[bs] = i;
	}
	if (ans == MOD)ans = -1;
	cout << ans << endl;
}


#include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;

//constexpr long long int MOD = 1000000007;
//constexpr int MOD = 1000000007;
//constexpr int MOD = 998244353;
constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-9;

//int N, M, K, H, W, L, R;
long long int N, M, K, H, W, L, R;

vector<int> Prime(int num) {
	vector<int>ret;
	ret.push_back(2);
	ret.push_back(3);
	for (int i = 5; i <= num; i += 6) {
		bool flag = true;
		for (int j = 2; j < ret.size(); j++) {
			if (ret[j] * ret[j] > i)break;
			if (i%ret[j] == 0) {
				flag = false;
				break;
			}
		}
		if (flag)ret.push_back(i);
		flag = true;
		for (int j = 2; j < ret.size(); j++) {
			if (ret[j] * ret[j] > i + 2)break;
			if ((i + 2) % ret[j] == 0) {
				flag = false;
				break;
			}
		}
		if (flag)ret.push_back(i + 2);
	}
	return ret;
}

void Search(vector<vector<int>>&edge, vector<int>&dis, int &ans, int node) {
	for (auto i : edge[node]) {
		if (dis[i] == MOD) {
			dis[i] = dis[node] + 1;
			Search(edge,dis,ans,i);
		}
		else {
			if(dis[i]<dis[node]-1)ans = min(ans, dis[node] - dis[i]+1);
		}
	}
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	auto P = Prime(1000000);
	vector<int>conv(1000001, -1);
	for (int i = 0; i < P.size(); i++) {
		conv[P[i]] = i;
	}
	conv[1] = P.size();
	vector<vector<int>>edge(P.size() + 1);
	cin >> N;
	int ans = MOD;
	for (int i = 0; i < N; i++) {
		cin >> M;
		for (int j = 0; P[j]*P[j] <= M; j++) {
			if (M%P[j] == 0) {
				int cnt = 0;
				while (M%P[j] == 0) {
					M /= P[j];
					cnt++;
				}
				if (cnt & 1) {
					edge[j].push_back(conv[M]);
					edge[conv[M]].push_back(j);
				}
				else {
					edge[conv[1]].push_back(conv[M]);
					edge[conv[M]].push_back(conv[1]);
				}
				M = 0;
				break;
			}
		}
		if (M) {
			if (M == 1) {
				cout << 1 << endl;
				return 0;
			}
			edge[conv[1]].push_back(conv[M]);
			edge[conv[M]].push_back(conv[1]);
		}
	}
	for (int i = 0; i <= P.size(); i++) {
		sort(edge[i].begin(), edge[i].end());
		for (int j = 1; j < edge[i].size(); j++) {
			if (edge[i][j] == edge[i][j - 1]) {
				cout << 2 << endl;
				return 0;
			}
		}
	}
	for (int i = 0; i < 200; i++) {
		vector<int>dis(P.size()+1, MOD);
		dis[i] = 0;
		Search(edge,dis,ans,i);
	}
	vector<int>dis(P.size()+1, MOD);
	dis[P.size()] = 0;
	Search(edge, dis, ans, P.size());
	if (ans == MOD)ans = -1;
	cout << ans << endl;
}


#include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;

//constexpr long long int MOD = 1000000007;
//constexpr int MOD = 1000000007;
//constexpr int MOD = 998244353;
constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-9;

//int N, M, K, H, W, L, R;
long long int N, M, K, H, W, L, R;
int ans = MOD;

vector<int> Prime(int num) {
	vector<int>ret;
	ret.push_back(2);
	ret.push_back(3);
	for (int i = 5; i <= num; i += 6) {
		bool flag = true;
		for (int j = 2; j < ret.size(); j++) {
			if (ret[j] * ret[j] > i)break;
			if (i%ret[j] == 0) {
				flag = false;
				break;
			}
		}
		if (flag)ret.push_back(i);
		flag = true;
		for (int j = 2; j < ret.size(); j++) {
			if (ret[j] * ret[j] > i + 2)break;
			if ((i + 2) % ret[j] == 0) {
				flag = false;
				break;
			}
		}
		if (flag)ret.push_back(i + 2);
	}
	return ret;
}

void Calculate_Depth(vector<vector<int>>&edge, vector<int>&depth, int stnode) {
	depth[stnode] = 0;
	queue<int>Q;
	Q.push(stnode);
	while (!Q.empty()) {
		int cn = Q.front();
		Q.pop();
		for (auto i : edge[cn]) {
			if (depth[i] > depth[cn] + 1) {
				depth[i] = depth[cn] + 1;
				Q.push(i);
			}
			else if(depth[i]>=depth[cn]) {
				ans = min(depth[i] + depth[cn] + 1,ans);
			}
		}
	}
	return;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	auto P = Prime(1000000);
	vector<int>conv(1000001, -1);
	for (int i = 0; i < P.size(); i++) {
		conv[P[i]] = i;
	}
	conv[1] = P.size();
	vector<vector<int>>edge(P.size() + 1);
	cin >> N;
	for (int i = 0; i < N; i++) {
		cin >> M;
		vector<int>box;
		for (int j = 0; P[j] * P[j] <= M; j++) {
			while (M%P[j]==0) {
				if (box.size() && box.back() == j)box.pop_back();
				else box.push_back(j);
				M /= P[j];
			}
		}
		if (M > 1)box.push_back(conv[M]);
		if (box.size() == 0) {
			cout << 1 << endl;
			return 0;
		}
		else if (box.size() == 1) {
			edge[conv[1]].push_back(box.back());
			edge[box.back()].push_back(conv[1]);
		}
		else {
			edge[box.front()].push_back(box.back());
			edge[box.back()].push_back(box.front());
		}

	}
	for (int i = 0; i <= P.size(); i++) {
		sort(edge[i].begin(), edge[i].end());
		for (int j = 1; j < edge[i].size(); j++) {
			if (edge[i][j] == edge[i][j - 1]) {
				cout << 2 << endl;
				return 0;
			}
		}
	}
	for (int i = 0; i < 200; i++) {
	//	cout << i << endl;
		vector<int>dis(P.size()+1, MOD);
		Calculate_Depth(edge, dis, i);
	}
	vector<int>dis(P.size()+1, MOD);
	Calculate_Depth(edge, dis, P.size());
	if (ans == MOD)ans = -1;
	cout << ans << endl;
}


#include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;

//constexpr long long int MOD = 1000000007;
//constexpr int MOD = 1000000007;
//constexpr int MOD = 998244353;
constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-9;

//int N, M, K, H, W, L, R;
long long int N, M, K, H, W, L, R;

vector<int> Prime(int num) {
	vector<int>ret;
	ret.push_back(2);
	ret.push_back(3);
	for (int i = 5; i <= num; i += 6) {
		bool flag = true;
		for (int j = 2; j < ret.size(); j++) {
			if (ret[j] * ret[j] > i)break;
			if (i%ret[j] == 0) {
				flag = false;
				break;
			}
		}
		if (flag)ret.push_back(i);
		flag = true;
		for (int j = 2; j < ret.size(); j++) {
			if (ret[j] * ret[j] > i + 2)break;
			if ((i + 2) % ret[j] == 0) {
				flag = false;
				break;
			}
		}
		if (flag)ret.push_back(i + 2);
	}
	return ret;
}

template< unsigned mod >
struct RollingHash {
	vector< unsigned > hashed, power;

	inline unsigned mul(unsigned a, unsigned b) const {
		unsigned long long x = (unsigned long long) a * b;
		unsigned xh = (unsigned)(x >> 32), xl = (unsigned)x, d, m;
		asm("divl %4; \n\t" : "=a" (d), "=d" (m) : "d" (xh), "a" (xl), "r" (mod));
		return m;
	}

	RollingHash(const string &s, unsigned base = 10007) {
		int sz = (int)s.size();
		hashed.assign(sz + 1, 0);
		power.assign(sz + 1, 0);
		power[0] = 1;
		for (int i = 0; i < sz; i++) {
			power[i + 1] = mul(power[i], base);
			hashed[i + 1] = mul(hashed[i], base) + s[i];
			if (hashed[i + 1] >= mod) hashed[i + 1] -= mod;
		}
	}

	unsigned get(int l, int r) const {
		unsigned ret = hashed[r] + mod - mul(hashed[l], power[r - l]);
		if (ret >= mod) ret -= mod;
		return ret;
	}

	unsigned connect(unsigned h1, int h2, int h2len) const {
		unsigned ret = mul(h1, power[h2len]) + h2;
		if (ret >= mod) ret -= mod;
		return ret;
	}

	int LCP(const RollingHash< mod > &b, int l1, int r1, int l2, int r2) {
		int len = min(r1 - l1, r2 - l2);
		int low = -1, high = len + 1;
		while (high - low > 1) {
			int mid = (low + high) / 2;
			if (get(l1, l1 + mid) == b.get(l2, l2 + mid)) low = mid;
			else high = mid;
		}
		return (low);
	}
};

using RH = RollingHash< 1000000007 >;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	auto P = Prime(1000000);
	vector<int>conv(1000001, -1);
	for (int i = 0; i < P.size(); i++) {
		conv[P[i]] = i;
	}
	cin >> N;
	bitset<78500>bs;
	int ans = MOD;
	unordered_map<long long , int>mp;
	RH a(bs.to_string());
	mp[a.get(0,78500)] = 0;
	for (int i = 1; i <= N; i++) {
		cin >> M;
		for (int j = 0; P[j] * P[j] <= M; j++) {
			while (M%P[j] == 0) {
				bs.flip(j);
				M /= P[j];
			}
		}
		if (M > 1) {
			bs.flip(conv[M]);
		}
		RH b(bs.to_string());
		if (mp.find(b.get(0,78500)) != mp.end()) {
			ans = min(ans, i - mp[b.get(0,78500)]);
		}
		mp[b.get(0, 78500)] = i;
	}
	if (ans == MOD)ans = -1;
	cout << ans << endl;
}


#include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;

//constexpr long long int MOD = 1000000007;
//constexpr int MOD = 1000000007;
//constexpr int MOD = 998244353;
constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-9;

//int N, M, K, H, W, L, R;
long long int N, M, K, H, W, L, R;

vector<int> Prime(int num) {
	vector<int>ret;
	ret.push_back(2);
	ret.push_back(3);
	for (int i = 5; i <= num; i += 6) {
		bool flag = true;
		for (int j = 2; j < ret.size(); j++) {
			if (ret[j] * ret[j] > i)break;
			if (i%ret[j] == 0) {
				flag = false;
				break;
			}
		}
		if (flag)ret.push_back(i);
		flag = true;
		for (int j = 2; j < ret.size(); j++) {
			if (ret[j] * ret[j] > i + 2)break;
			if ((i + 2) % ret[j] == 0) {
				flag = false;
				break;
			}
		}
		if (flag)ret.push_back(i + 2);
	}
	return ret;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	auto P = Prime(1000000);
	vector<int>conv(1000001, -1);
	for (int i = 0; i < P.size(); i++) {
		conv[P[i]] = i;
	}
	vector<int>box(78500);
	for (int i = 0; i < 78500; i++)box[i] = i;
	random_device rd;
	mt19937_64 mt(rd());
	shuffle(box.begin(), box.end(),mt);
	cin >> N;
	bitset<78500>bs;
	int ans = MOD;
	unordered_map<long long , int>mp;
	hash<bitset<78500>>h;
	mp[h(bs)] = 0;
	for (int i = 1; i <= N; i++) {
		cin >> M;
		for (int j = 0; P[j] * P[j] <= M; j++) {
			while (M%P[j] == 0) {
				bs.flip(box[j]);
				M /= P[j];
			}
		}
		if (M > 1) {
			bs.flip(box[conv[M]]);
		}
		if (mp.find(h(bs)) != mp.end()) {
			ans = min(ans, i - mp[h(bs)]);
		}
		mp[h(bs)] = i;
	}
	if (ans == MOD)ans = -1;
	cout << ans << endl;
}


#include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;

//constexpr long long int MOD = 1000000007;
//constexpr int MOD = 1000000007;
//constexpr int MOD = 998244353;
constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-9;

//int N, M, K, H, W, L, R;
long long int N, M, K, H, W, L, R;

vector<int> Prime(int num) {
	vector<int>ret;
	ret.push_back(2);
	ret.push_back(3);
	for (int i = 5; i <= num; i += 6) {
		bool flag = true;
		for (int j = 2; j < ret.size(); j++) {
			if (ret[j] * ret[j] > i)break;
			if (i%ret[j] == 0) {
				flag = false;
				break;
			}
		}
		if (flag)ret.push_back(i);
		flag = true;
		for (int j = 2; j < ret.size(); j++) {
			if (ret[j] * ret[j] > i + 2)break;
			if ((i + 2) % ret[j] == 0) {
				flag = false;
				break;
			}
		}
		if (flag)ret.push_back(i + 2);
	}
	return ret;
}

void Search(vector<vector<int>>&edge, vector<int>&dis, int &ans, int node) {
	for (auto i : edge[node]) {
		if (dis[i] == MOD) {
			dis[i] = dis[node] + 1;
			Search(edge,dis,ans,i);
		}
		else {
			if(dis[i]<dis[node]-1)ans = min(ans, dis[node] - dis[i]+1);
		}
	}
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	auto P = Prime(1000000);
	vector<int>conv(1000001, -1);
	for (int i = 0; i < P.size(); i++) {
		conv[P[i]] = i;
	}
	conv[1] = P.size();
	vector<vector<int>>edge(P.size() + 1);
	cin >> N;
	int ans = MOD;
	for (int i = 0; i < N; i++) {
		cin >> M;
		vector<int>box;
		for (int j = 0; P[j] * P[j] <= M; j++) {
			while (M%P[j]==0) {
				if (box.size() && box.back() == j)box.pop_back();
				else box.push_back(j);
				M /= P[j];
			}
		}
		if (M > 1)box.push_back(conv[M]);
		if (box.size() == 0) {
			cout << 1 << endl;
			return 0;
		}
		else if (box.size() == 1) {
			edge[conv[1]].push_back(box.back());
			edge[box.back()].push_back(conv[1]);
		}
		else {
			edge[box.front()].push_back(box.back());
			edge[box.back()].push_back(box.front());
		}

	}
	for (int i = 0; i <= P.size(); i++) {
		sort(edge[i].begin(), edge[i].end());
		for (int j = 1; j < edge[i].size(); j++) {
			if (edge[i][j] == edge[i][j - 1]) {
				cout << 2 << endl;
				return 0;
			}
		}
	}
	for (int i = 0; i < 200; i++) {
	//	cout << i << endl;
		vector<int>dis(P.size()+1, MOD);
		dis[i] = 0;
		Search(edge,dis,ans,i);
	}
	vector<int>dis(P.size()+1, MOD);
	dis[P.size()] = 0;
	Search(edge, dis, ans, P.size());
	if (ans == MOD)ans = -1;
	cout << ans << endl;
}


#include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;

//constexpr long long int MOD = 1000000007;
//constexpr int MOD = 1000000007;
//constexpr int MOD = 998244353;
constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-9;

//int N, M, K, H, W, L, R;
long long int N, M, K, H, W, L, R;

vector<int> Prime(int num) {
	vector<int>ret;
	ret.push_back(2);
	ret.push_back(3);
	for (int i = 5; i <= num; i += 6) {
		bool flag = true;
		for (int j = 2; j < ret.size(); j++) {
			if (ret[j] * ret[j] > i)break;
			if (i%ret[j] == 0) {
				flag = false;
				break;
			}
		}
		if (flag)ret.push_back(i);
		flag = true;
		for (int j = 2; j < ret.size(); j++) {
			if (ret[j] * ret[j] > i + 2)break;
			if ((i + 2) % ret[j] == 0) {
				flag = false;
				break;
			}
		}
		if (flag)ret.push_back(i + 2);
	}
	return ret;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	auto P = Prime(1000000);
	vector<int>conv(1000001, -1);
	for (int i = 0; i < P.size(); i++) {
		conv[P[i]] = i;
	}
	cin >> N;
	bitset<78500>bs;
	int ans = MOD;
	unordered_map<long long , int>mp;
	hash<bitset<78500>>h;
	mp[h(bs)] = 0;
	for (int i = 1; i <= N; i++) {
		cin >> M;
		for (int j = 0; P[j] * P[j] <= M; j++) {
			while (M%P[j] == 0) {
				bs.flip(j);
				M /= P[j];
			}
		}
		if (M > 1) {
			bs.flip(conv[M]);
		}
		if (mp.find(h(bs)) != mp.end()) {
			ans = min(ans, i - mp[h(bs)]);
		}
		mp[h(bs)] = i;
	}
	if (ans == MOD)ans = -1;
	cout << ans << endl;
}


// by david942j
// {{{
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <deque>
#include <cassert>
#include <queue>
#include <stack>
#include <cstdlib>
// #ifndef DAVID
// #include <bits/stdc++.h>
// #endif
#define openfile(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout)
#define mpr std::make_pair
#define lg(x) (31-__builtin_clz(x))
#define lgll(x) (63-__builtin_clzll(x))
#define __count __builtin_popcount
#define __countll __builtin_popcountll
#define X first
#define Y second
#define mst(x) memset(x,0,sizeof(x))
#define mst1(x) memset(x,-1,sizeof(x))
#define ALL(c) (c).begin(),(c).end()
#define FOR(i,n) for(int i=0;i<n;i++)
#define FOR1(i,n) for(int i=1;i<=n;i++)
#define FORit(it,c) for(__typeof(c.begin()) it=c.begin();it!=c.end();++it)
#define pb push_back
#define RI(x) scanf("%d",&x)
#define RID(x) int x;RI(x)

#define IOS do {ios_base::sync_with_stdio(false); cin.tie(0); }while(0)
using namespace std;
template<typename T>
void _R( T &x ) { cin>>x; }
void _R( int &x ) { scanf("%d",&x); }
#ifdef PRId64
void _R( long long &x ) { scanf("%" PRId64,&x); }
#else
void _R( long long &x) {cin >> x;}
#endif
void _R( double &x ) { scanf("%lf",&x); }
void _R( char &x ) { scanf(" %c",&x); }
void _R( char *x ) { scanf("%s",x); }

void R() {}
template<typename T, typename... U>
void R( T& head, U&... tail ) {
  _R(head);
  R(tail...);
}

template<typename T>
void _W( const T &x ) { cout<<x; }
void _W( const int &x ) { printf("%d",x); }
template<typename T>
void _W( const vector<T> &x ) {
  for ( auto i=x.cbegin(); i!=x.cend(); i++ ) {
    if ( i!=x.cbegin() ) putchar(' ');
    _W(*i);
  }
}

void W() {}
template<typename T, typename... U>
void W( const T& head, const U&... tail ) {
  _W(head);
  putchar(sizeof...(tail)?' ':'\n');
  W(tail...);
}
#ifdef DAVID
#define debug(format, ...) fprintf(stderr, format, ##__VA_ARGS__)
#else
#define debug(...)
#endif
#define caset RID(T);FOR1(cas,T)
typedef long long LL;
typedef double LD;
typedef vector<int> VI;
typedef std::pair<int,int> PII;
template<class T>inline void maz(T &a,T b){if(a<b)a=b;}
template<class T>inline void miz(T &a,T b){if(a>b)a=b;}
template<class T>inline T abs(T a){return a>0?a:-a;}
// }}}

const int N = 1e5+10;
const int INF = 1e9+7;
const int MOD = 1e9+7;
int n;
int A[N];
VI pr;

set<int> S;
set<PII> E;

void prime() {
  static bool a[1000];
  for(int i=2;i<1000;i++) {
    if (!a[i]) {
      pr.pb(i);
      for (int j=i*i;j < 1000; j+=i)
        a[j]=1;
    }
  }
}

int ana(int v, int &a, int &b) {
  a = b = 0;
  for (auto p: pr)
    if (v % p == 0) {
      int k = 0;
      do {
        v /= p;
        k++;
      } while (v % p == 0);
      if (k & 1) {
        if (a == 0) a = p;
        else { assert(b == 0); b = p; }
      }
    }
    else if (v == 1) break;

  if (v != 1) {
    if (a == 0) a = v;
    else { assert(b == 0); b = v; }
  }
  if (a == 0) return 0;
  if (b == 0) return 1;
  return 2;
}

map<int, int> M;
int m[169][169];
VI G[100000];
void discrete() {
  FOR(i, pr.size())
    M[pr[i]] = i;

  int cur = pr.size();
  for(auto s: S)
    if (s > 1000 && M.count(s) == 0)
      M[s] = cur++;
  for(auto e: E) {
    assert(!(e.X > 1000));
    if (e.Y > 1000 && M.count(e.Y) == 0)
      M[e.Y] = cur++;
  }
  assert(cur < 100000);
  assert(cur == M.size());
}

void ggraph() {
  for(auto e: E)
    if (e.Y > 1000) {
      G[M[e.Y]].pb(M[e.X]);
    }
}

int Ans = INF;
void mgraph() {
  const int n = pr.size();

  FOR(i, n) {
    FOR(j, i)
      m[i][j] = m[j][i] = INF;
    m[i][i] = 0;
  }
  for(auto e: E) {
    const int &x = M[e.X], &y = M[e.Y];
    if (x < n && y < n)
      m[x][y] = m[y][x] = 1;
  }
  FOR(x, M.size())
    FOR(i, G[x].size())
      FOR(j, i) {
        miz(Ans, 2 + m[G[x][i]][G[x][j]]);
        miz(m[G[x][i]][G[x][j]], 2);
        miz(m[G[x][j]][G[x][i]], 2);
      }
}

int minimum_cycle() {
  const int n = pr.size();
  int ans = INF;
  int d[169][169];
  memcpy(d, m, sizeof(m));
  FOR(k, n) {
    FOR(i, k)
      if (d[k][i] != INF)
        FOR(j, i)
          miz(ans, d[k][i] + m[i][j] + d[j][k]);
    FOR(i, n)
      if (m[i][k] != INF)
        FOR(j, n)
          if (m[k][j] != INF)
            miz(m[i][j], m[i][k] + m[k][j]);
  }
  return ans;
}

int small_endpoint() {
  VI v;
  for(auto s: S)
    if (s < 1000)
      v.pb(M[s]);
  int ans = INF;
  FOR(i, v.size())
    FOR(j, i)
      miz(ans, 2 + m[v[j]][v[i]]);
  return ans;
}

int best_end[170];
int big_small_endpoint() {
  const int n = pr.size();
  FOR(i, n)
    best_end[i] = INF;
  VI V;
  for(auto s: S)
    if (s < 1000)
      V.pb(M[s]);
  FOR(i, n)
    for(auto v: V)
      miz(best_end[i], 1 + m[i][v]);

  int ans = INF;
  for(auto s: S)
    if (s > 1000)
      for(auto y: G[M[s]])
        miz(ans, 2 + best_end[y]);

  return ans;
}

int big_big_endpoint() {
  int ans = INF;
  static int has_bee[170];
  for(auto e: E)
    if (e.Y > 1000 && S.count(e.Y))
      has_bee[M[e.X]]++;
  const int n = pr.size();
  FOR(i, n)
    if (has_bee[i] > 1)
      miz(ans, 4);
  FOR(i, n)
      if (has_bee[i])
        FOR(j, i)
          if (has_bee[j])
            miz(ans, m[i][j] + 4);
  return ans;
}

int solve() {
  int a, b;
  FOR(i, n) {
    if (A[i] == 1) return 1;

    int t = ana(A[i], a, b);
    // printf("~%d %d %d\n", t, a, b);
    if (t == 0) return 1;
    if (t == 1) {
      if (S.find(a) != S.end())
        return 2;
      else S.insert(a);
    }
    else {
      assert(a < b && a && b);
      if (E.find(mpr(a, b)) != E.end())
        return 2;
      else E.insert(mpr(a,b));
    }
  }
  discrete();
  ggraph();
  mgraph();
  int ans = Ans;
  miz(ans, minimum_cycle());
  miz(ans, small_endpoint());
  miz(ans, big_small_endpoint());
  miz(ans, big_big_endpoint());

  if (ans == INF)
    return -1;
  return ans;
}

int main() {
  prime();
  R(n);
  FOR(i,n)
    R(A[i]);
  printf("%d\n", solve());
  return 0;
}

/*
4 2 2006 1003 17
3 2 2018 1009
3 2018 5045 10
5 1009 1013 3027 15 5065
5 2 2018 3027 3039 1013
3 6 2018 3027
4 2018 3027 3039 2026
4 1009 2018 3 3027 # 3
5 2018 1009 3039 1013 6
4 2018 2026 1009 1013
2 1009 2018
 */


// by david942j
// {{{
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <deque>
#include <cassert>
#include <queue>
#include <stack>
#include <cstdlib>
// #ifndef DAVID
// #include <bits/stdc++.h>
// #endif
#define openfile(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout)
#define mpr std::make_pair
#define lg(x) (31-__builtin_clz(x))
#define lgll(x) (63-__builtin_clzll(x))
#define __count __builtin_popcount
#define __countll __builtin_popcountll
#define X first
#define Y second
#define mst(x) memset(x,0,sizeof(x))
#define mst1(x) memset(x,-1,sizeof(x))
#define ALL(c) (c).begin(),(c).end()
#define FOR(i,n) for(int i=0;i<n;i++)
#define FOR1(i,n) for(int i=1;i<=n;i++)
#define FORit(it,c) for(__typeof(c.begin()) it=c.begin();it!=c.end();++it)
#define pb push_back
#define RI(x) scanf("%d",&x)
#define RID(x) int x;RI(x)

#define IOS do {ios_base::sync_with_stdio(false); cin.tie(0); }while(0)
using namespace std;
template<typename T>
void _R( T &x ) { cin>>x; }
void _R( int &x ) { scanf("%d",&x); }
#ifdef PRId64
void _R( long long &x ) { scanf("%" PRId64,&x); }
#else
void _R( long long &x) {cin >> x;}
#endif
void _R( double &x ) { scanf("%lf",&x); }
void _R( char &x ) { scanf(" %c",&x); }
void _R( char *x ) { scanf("%s",x); }

void R() {}
template<typename T, typename... U>
void R( T& head, U&... tail ) {
  _R(head);
  R(tail...);
}

template<typename T>
void _W( const T &x ) { cout<<x; }
void _W( const int &x ) { printf("%d",x); }
template<typename T>
void _W( const vector<T> &x ) {
  for ( auto i=x.cbegin(); i!=x.cend(); i++ ) {
    if ( i!=x.cbegin() ) putchar(' ');
    _W(*i);
  }
}

void W() {}
template<typename T, typename... U>
void W( const T& head, const U&... tail ) {
  _W(head);
  putchar(sizeof...(tail)?' ':'\n');
  W(tail...);
}
#ifdef DAVID
#define debug(format, ...) fprintf(stderr, format, ##__VA_ARGS__)
#else
#define debug(...)
#endif
#define caset RID(T);FOR1(cas,T)
typedef long long LL;
typedef double LD;
typedef vector<int> VI;
typedef std::pair<int,int> PII;
template<class T>inline void maz(T &a,T b){if(a<b)a=b;}
template<class T>inline void miz(T &a,T b){if(a>b)a=b;}
template<class T>inline T abs(T a){return a>0?a:-a;}
// }}}

const int N = 1e5+10;
const int INF = 1e9+7;
const int MOD = 1e9+7;
int n;
int A[N];
VI pr;

set<int> S;
set<PII> E;

void prime() {
  static bool a[1000];
  for(int i=2;i<1000;i++) {
    if (!a[i]) {
      pr.pb(i);
      for (int j=i*i;j < 1000; j+=i)
        a[j]=1;
    }
  }
  // W(pr.size());
  // W(pr);
}

int ana(int v, int &a, int &b) {
  a = b = 0;
  for (auto p: pr)
    if (v % p == 0) {
      int k = 0;
      do {
        v /= p;
        k++;
      } while (v % p == 0);
      if (k & 1) {
        if (a == 0) a = p;
        else b = p;
      }
    }
    else if (v == 1) break;

  if (v != 1) {
    if (a == 0) a = v;
    else b = v;
  }
  if (a == 0) return 0;
  if (b == 0) return 1;
  return 2;
}

map<int, int> M;
int m[169][169];
VI G[100000];
void discrete() {
  FOR(i, pr.size())
    M[pr[i]] = i;

  int cur = pr.size();
  for(auto s: S)
    if (s > 1000 && M.count(s) == 0)
      M[s] = cur++;
  for(auto e: E) {
    assert(! (e.X > 1000 && M.count(e.X) == 0));
    if (e.Y > 1000 && M.count(e.Y) == 0)
      M[e.Y] = cur++;
  }
  assert(cur < 100000);
}

void ggraph() {
  for(auto e: E)
    if (e.Y > 1000) {
      G[M[e.Y]].pb(M[e.X]);
    }
}

int Ans = INF;
void mgraph() {
  const int n = pr.size();

  FOR(i, n) {
    FOR(j, i)
      m[i][j] = m[j][i] = INF;
    m[i][i] = 0;
  }
  for(auto e: E) {
    const int &x = M[e.X], &y = M[e.Y];
    if (x < n && y < n)
      m[x][y] = m[y][x] = 1;
  }
  FOR(x, M.size())
    FOR(i, G[x].size())
      FOR(j, i) {
        if (m[G[x][i]][G[x][j]] != INF) {
          miz(Ans, 2 + m[G[x][i]][G[x][j]]);
          return;
        }
        m[G[x][i]][G[x][j]] = 2;
        m[G[x][j]][G[x][i]] = 2;
      }
}

void floyd() {
  mgraph();
  const int n = pr.size();

  FOR(k, n)
    FOR(i, n)
      FOR(j, n)
        if (m[i][k] != INF && m[k][j] != INF)
          miz(m[i][j], m[i][k] + m[k][j]);
}

int minimum_cycle() {
  mgraph();
  if (Ans != INF) return Ans;
  const int n = pr.size();
  int ans = INF;
  int d[169][169];
  memcpy(d, m, sizeof(m));
  FOR(k, n) {
    FOR(i, k)
      if (m[k][i] != INF)
        FOR(j, k)
          if (i != j)
            miz(ans, m[k][i] + d[i][j] + m[j][k]);
    FOR(i, n)
      FOR(j, n)
        if (d[i][k] != INF && d[k][j] != INF)
          miz(d[i][j], d[i][k] + d[k][j]);
  }
  return ans;
}

int small_endpoint() {
  VI v;
  for(auto s: S)
    if (s < 1000)
      v.pb(M[s]);
  int ans = INF;
  FOR(i, v.size())
    FOR(j, i)
      miz(ans, 2 + m[v[j]][v[i]]);
  return ans;
}

int big_cycle() {
  int ans = INF;
  FOR(x, M.size())
    FOR(i, G[x].size())
      FOR(j, i)
        miz(ans, m[G[x][i]][G[x][j]] + 2);
  return ans;
}

int best_end[170];
int big_small_endpoint() {
  const int n = pr.size();
  FOR(i, n)
    best_end[i] = INF;
  VI V;
  for(auto s: S)
    if (s < 1000)
      V.pb(M[s]);
  FOR(i, n)
    for(auto v: V)
      miz(best_end[i], 1 + m[i][v]);

  int ans = INF;
  for(auto s: S)
    if (s > 1000)
      for(auto y: G[M[s]])
        miz(ans, 2 + best_end[y]);

  return ans;
}

int big_big_endpoint() {
  int ans = INF;
  static bool has_bee[170];
  for(auto e: E)
    if (e.Y > 1000 && S.count(e.Y))
      has_bee[M[e.X]] = true;
  const int n = pr.size();
  FOR(i, n)
      if (has_bee[i])
        FOR(j, i)
          if (has_bee[j])
            miz(ans, m[i][j] + 4);
  return ans;
}

int solve() {
  int a, b;
  FOR(i, n) {
    if (A[i] == 1) return 1;

    int t = ana(A[i], a, b);
    // printf("~%d %d %d\n", t, a, b);
    if (t == 0) return 1;
    if (t == 1) {
      if (S.find(a) != S.end())
        return 2;
      else S.insert(a);
    }
    else {
      if (E.find(mpr(a, b)) != E.end())
        return 2;
      else E.insert(mpr(a,b));
    }
  }
  discrete();
  ggraph();
  int ans = INF;
  miz(ans, minimum_cycle());
  floyd();
  miz(ans, small_endpoint());
  miz(ans, big_small_endpoint());
  miz(ans, big_big_endpoint());
  // miz(ans, big_cycle());

  if (ans == INF)
    return -1;
  return ans;
}

int main() {
  prime();
  R(n);
  FOR(i,n)
    R(A[i]);
  printf("%d\n", solve());
  return 0;
}

/*
4 2 2006 1003 17
3 2 2018 1009
3 2018 5045 10
5 1009 1013 3027 15 5065
5 2 2018 3027 3039 1013
3 6 2018 3027
4 2018 3027 3039 2026
 */


// by david942j
// {{{
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <deque>
#include <cassert>
#include <queue>
#include <stack>
#include <cstdlib>
// #ifndef DAVID
// #include <bits/stdc++.h>
// #endif
#define openfile(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout)
#define mpr std::make_pair
#define lg(x) (31-__builtin_clz(x))
#define lgll(x) (63-__builtin_clzll(x))
#define __count __builtin_popcount
#define __countll __builtin_popcountll
#define X first
#define Y second
#define mst(x) memset(x,0,sizeof(x))
#define mst1(x) memset(x,-1,sizeof(x))
#define ALL(c) (c).begin(),(c).end()
#define FOR(i,n) for(int i=0;i<n;i++)
#define FOR1(i,n) for(int i=1;i<=n;i++)
#define FORit(it,c) for(__typeof(c.begin()) it=c.begin();it!=c.end();++it)
#define pb push_back
#define RI(x) scanf("%d",&x)
#define RID(x) int x;RI(x)

#define IOS do {ios_base::sync_with_stdio(false); cin.tie(0); }while(0)
using namespace std;
template<typename T>
void _R( T &x ) { cin>>x; }
void _R( int &x ) { scanf("%d",&x); }
#ifdef PRId64
void _R( long long &x ) { scanf("%" PRId64,&x); }
#else
void _R( long long &x) {cin >> x;}
#endif
void _R( double &x ) { scanf("%lf",&x); }
void _R( char &x ) { scanf(" %c",&x); }
void _R( char *x ) { scanf("%s",x); }

void R() {}
template<typename T, typename... U>
void R( T& head, U&... tail ) {
  _R(head);
  R(tail...);
}

template<typename T>
void _W( const T &x ) { cout<<x; }
void _W( const int &x ) { printf("%d",x); }
template<typename T>
void _W( const vector<T> &x ) {
  for ( auto i=x.cbegin(); i!=x.cend(); i++ ) {
    if ( i!=x.cbegin() ) putchar(' ');
    _W(*i);
  }
}

void W() {}
template<typename T, typename... U>
void W( const T& head, const U&... tail ) {
  _W(head);
  putchar(sizeof...(tail)?' ':'\n');
  W(tail...);
}
#ifdef DAVID
#define debug(format, ...) fprintf(stderr, format, ##__VA_ARGS__)
#else
#define debug(...)
#endif
#define caset RID(T);FOR1(cas,T)
typedef long long LL;
typedef double LD;
typedef vector<int> VI;
typedef std::pair<int,int> PII;
template<class T>inline void maz(T &a,T b){if(a<b)a=b;}
template<class T>inline void miz(T &a,T b){if(a>b)a=b;}
template<class T>inline T abs(T a){return a>0?a:-a;}
// }}}

const int N = 1e5+10;
const int INF = 1e9+7;
const int MOD = 1e9+7;
int n;
int A[N];
VI pr;

set<int> S;
set<PII> E;

void prime() {
  static bool a[1000];
  for(int i=2;i<1000;i++) {
    if (!a[i]) {
      pr.pb(i);
      for (int j=i*i;j < 1000; j+=i)
        a[j]=1;
    }
  }
}

int ana(int v, int &a, int &b) {
  a = b = 0;
  for (auto p: pr)
    if (v % p == 0) {
      int k = 0;
      do {
        v /= p;
        k++;
      } while (v % p == 0);
      if (k & 1) {
        if (a == 0) a = p;
        else { assert(b == 0); b = p; }
      }
    }
    else if (v == 1) break;

  if (v != 1) {
    if (a == 0) a = v;
    else { assert(b == 0); b = v; }
  }
  if (a == 0) return 0;
  if (b == 0) return 1;
  return 2;
}

map<int, int> M;
int m[169][169];
VI G[100000];
void discrete() {
  FOR(i, pr.size())
    M[pr[i]] = i;

  int cur = pr.size();
  for(auto s: S)
    if (s > 1000 && M.count(s) == 0)
      M[s] = cur++;
  for(auto e: E) {
    assert(!(e.X > 1000));
    if (e.Y > 1000 && M.count(e.Y) == 0)
      M[e.Y] = cur++;
  }
  assert(cur < 100000);
  assert(cur == M.size());
}

void ggraph() {
  for(auto e: E)
    if (e.Y > 1000) {
      G[M[e.Y]].pb(M[e.X]);
    }
}

int Ans = INF;
int se[169][169];
void mgraph() {
  const int n = pr.size();

  FOR(i, n) {
    FOR(j, i)
      m[i][j] = m[j][i] = INF;
    m[i][i] = 0;
  }
  for(auto e: E) {
    const int &x = M[e.X], &y = M[e.Y];
    if (x < n && y < n)
      m[x][y] = m[y][x] = 1;
  }
  FOR(x, M.size())
    FOR(i, G[x].size())
      FOR(j, i) {
        int &v = m[G[x][i]][G[x][j]];
        miz(Ans, 2 + v);
        if (v == INF)
          se[G[x][i]][G[x][j]] = se[G[x][j]][G[x][i]] = x;
        miz(v, 2);
        miz(m[G[x][j]][G[x][i]], 2);
      }
}

int minimum_cycle() {
  const int n = pr.size();
  int ans = INF;
  int d[169][169];
  memcpy(d, m, sizeof(m));
  FOR(k, n) {
    FOR(i, k)
      if (d[k][i] != INF)
        FOR(j, i) {
          if (d[k][i] == 2 && d[j][k] == 2 && se[k][i] == se[j][k]) continue;
          miz(ans, d[k][i] + m[i][j] + d[j][k]);
        }
    FOR(i, n)
      if (m[i][k] != INF)
        FOR(j, n)
          if (m[k][j] != INF)
            miz(m[i][j], m[i][k] + m[k][j]);
  }
  return ans;
}

int small_endpoint() {
  VI v;
  for(auto s: S)
    if (s < 1000)
      v.pb(M[s]);
  int ans = INF;
  FOR(i, v.size())
    FOR(j, i)
      miz(ans, 2 + m[v[j]][v[i]]);
  return ans;
}

int best_end[170];
int big_small_endpoint() {
  const int n = pr.size();
  FOR(i, n)
    best_end[i] = INF;
  VI V;
  for(auto s: S)
    if (s < 1000)
      V.pb(M[s]);
  FOR(i, n)
    for(auto v: V)
      miz(best_end[i], 1 + m[i][v]);

  int ans = INF;
  for(auto s: S)
    if (s > 1000)
      for(auto y: G[M[s]])
        miz(ans, 2 + best_end[y]);

  return ans;
}

int big_big_endpoint() {
  int ans = INF;
  static int has_bee[170];
  for(auto e: E)
    if (e.Y > 1000 && S.count(e.Y)) {
      const int &x = M[e.X];
      if (has_bee[x] == 0)
        has_bee[x] = e.Y;
      else if (has_bee[x])
        return 4;
    }
  const int n = pr.size();
  FOR(i, n)
    if (has_bee[i])
      FOR(j, i)
        if (has_bee[j]) {
          if (has_bee[i] == has_bee[j]) continue;
          miz(ans, m[i][j] + 4);
        }
  return ans;
}

int solve() {
  int a, b;
  FOR(i, n) {
    if (A[i] == 1) return 1;

    int t = ana(A[i], a, b);
    // printf("~%d %d %d\n", t, a, b);
    if (t == 0) return 1;
    if (t == 1) {
      if (S.find(a) != S.end())
        return 2;
      else S.insert(a);
    }
    else {
      assert(a < b && a && b);
      if (E.find(mpr(a, b)) != E.end())
        return 2;
      else E.insert(mpr(a,b));
    }
  }
  discrete();
  ggraph();
  mgraph();
  int ans = Ans;
  miz(ans, minimum_cycle());
  miz(ans, small_endpoint());
  miz(ans, big_small_endpoint());
  miz(ans, big_big_endpoint());

  if (ans == INF)
    return -1;
  return ans;
}

int main() {
  prime();
  R(n);
  FOR(i,n)
    R(A[i]);
  printf("%d\n", solve());
  return 0;
}

/*
3 2 2018 1009
3 2018 5045 10
5 1009 1013 3027 15 5065
5 2 2018 3027 3039 1013
3 6 2018 3027
4 2018 3027 3039 2026
4 1009 2018 3 3027 # 3
5 2018 1009 3039 1013 6
4 2018 2026 1009 1013
2 1009 2018
5 3 5 2018 3027 10
3 2018 3027 1009 # -1
6 1009 2018 2026 3039 3057 1019
6 1009 1013 2018 3027 15 5065 # 5
3 2018 3027 5045
 */


// by david942j
// {{{
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <deque>
#include <cassert>
#include <queue>
#include <stack>
#include <cstdlib>
// #ifndef DAVID
// #include <bits/stdc++.h>
// #endif
#define openfile(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout)
#define mpr std::make_pair
#define lg(x) (31-__builtin_clz(x))
#define lgll(x) (63-__builtin_clzll(x))
#define __count __builtin_popcount
#define __countll __builtin_popcountll
#define X first
#define Y second
#define mst(x) memset(x,0,sizeof(x))
#define mst1(x) memset(x,-1,sizeof(x))
#define ALL(c) (c).begin(),(c).end()
#define FOR(i,n) for(int i=0;i<n;i++)
#define FOR1(i,n) for(int i=1;i<=n;i++)
#define FORit(it,c) for(__typeof(c.begin()) it=c.begin();it!=c.end();++it)
#define pb push_back
#define RI(x) scanf("%d",&x)
#define RID(x) int x;RI(x)

#define IOS do {ios_base::sync_with_stdio(false); cin.tie(0); }while(0)
using namespace std;
template<typename T>
void _R( T &x ) { cin>>x; }
void _R( int &x ) { scanf("%d",&x); }
#ifdef PRId64
void _R( long long &x ) { scanf("%" PRId64,&x); }
#else
void _R( long long &x) {cin >> x;}
#endif
void _R( double &x ) { scanf("%lf",&x); }
void _R( char &x ) { scanf(" %c",&x); }
void _R( char *x ) { scanf("%s",x); }

void R() {}
template<typename T, typename... U>
void R( T& head, U&... tail ) {
  _R(head);
  R(tail...);
}

template<typename T>
void _W( const T &x ) { cout<<x; }
void _W( const int &x ) { printf("%d",x); }
template<typename T>
void _W( const vector<T> &x ) {
  for ( auto i=x.cbegin(); i!=x.cend(); i++ ) {
    if ( i!=x.cbegin() ) putchar(' ');
    _W(*i);
  }
}

void W() {}
template<typename T, typename... U>
void W( const T& head, const U&... tail ) {
  _W(head);
  putchar(sizeof...(tail)?' ':'\n');
  W(tail...);
}
#ifdef DAVID
#define debug(format, ...) fprintf(stderr, format, ##__VA_ARGS__)
#else
#define debug(...)
#endif
#define caset RID(T);FOR1(cas,T)
typedef long long LL;
typedef double LD;
typedef vector<int> VI;
typedef std::pair<int,int> PII;
template<class T>inline void maz(T &a,T b){if(a<b)a=b;}
template<class T>inline void miz(T &a,T b){if(a>b)a=b;}
template<class T>inline T abs(T a){return a>0?a:-a;}
// }}}

const int N = 1e5+10;
const int INF = 1e9+7;
const int MOD = 1e9+7;
int n;
int A[N];
VI pr;

set<int> S;
set<PII> E;

void prime() {
  static bool a[1000];
  for(int i=2;i<1000;i++) {
    if (!a[i]) {
      pr.pb(i);
      for (int j=i*i;j < 1000; j+=i)
        a[j]=1;
    }
  }
  // W(pr.size());
  // W(pr);
}

int ana(int v, int &a, int &b) {
  a = b = 0;
  for (auto p: pr)
    if (v % p == 0) {
      int k = 0;
      do {
        v /= p;
        k++;
      } while (v % p == 0);
      if (k & 1) {
        if (a == 0) a = p;
        else b = p;
      }
    }
    else if (v == 1) break;

  if (v != 1) {
    if (a == 0) a = v;
    else b = v;
  }
  if (a == 0) return 0;
  if (b == 0) return 1;
  return 2;
}

map<int, int> M;
int m[169][169];
VI G[100000];
void discrete() {
  FOR(i, pr.size())
    M[pr[i]] = i;

  int cur = pr.size();
  for(auto s: S)
    if (s > 1000 && M.count(s) == 0)
      M[s] = cur++;
  for(auto e: E) {
    assert(! (e.X > 1000 && M.count(e.X) == 0));
    if (e.Y > 1000 && M.count(e.Y) == 0)
      M[e.Y] = cur++;
  }
  assert(cur < 100000);
}

void ggraph() {
  for(auto e: E)
    if (e.Y > 1000) {
      G[M[e.Y]].pb(M[e.X]);
    }
}

int Ans = INF;
void mgraph() {
  const int n = pr.size();

  FOR(i, n) {
    FOR(j, i)
      m[i][j] = m[j][i] = INF;
    m[i][i] = 0;
  }
  for(auto e: E) {
    const int &x = M[e.X], &y = M[e.Y];
    if (x < n && y < n)
      m[x][y] = m[y][x] = 1;
  }
  FOR(x, M.size())
    FOR(i, G[x].size())
      FOR(j, i) {
        miz(Ans, 2 + m[G[x][i]][G[x][j]]);
        miz(m[G[x][i]][G[x][j]], 2);
        miz(m[G[x][j]][G[x][i]], 2);
      }
}

void floyd() {
  mgraph();
  const int n = pr.size();

  FOR(k, n)
    FOR(i, n)
      FOR(j, n)
        if (m[i][k] != INF && m[k][j] != INF)
          miz(m[i][j], m[i][k] + m[k][j]);
}

int minimum_cycle() {
  mgraph();
  const int n = pr.size();
  int ans = INF;
  int d[169][169];
  memcpy(d, m, sizeof(m));
  FOR(k, n) {
    FOR(i, k)
      if (m[k][i] != INF)
        FOR(j, k)
          if (i != j)
            miz(ans, m[k][i] + d[i][j] + m[j][k]);
    FOR(i, n)
      FOR(j, n)
        if (d[i][k] != INF && d[k][j] != INF)
          miz(d[i][j], d[i][k] + d[k][j]);
  }
  return ans;
}

int small_endpoint() {
  VI v;
  for(auto s: S)
    if (s < 1000)
      v.pb(M[s]);
  int ans = INF;
  FOR(i, v.size())
    FOR(j, i)
      miz(ans, 2 + m[v[j]][v[i]]);
  return ans;
}

int best_end[170];
int big_small_endpoint() {
  const int n = pr.size();
  FOR(i, n)
    best_end[i] = INF;
  VI V;
  for(auto s: S)
    if (s < 1000)
      V.pb(M[s]);
  FOR(i, n)
    for(auto v: V)
      miz(best_end[i], 1 + m[i][v]);

  int ans = INF;
  for(auto s: S)
    if (s > 1000)
      for(auto y: G[M[s]])
        miz(ans, 2 + best_end[y]);

  return ans;
}

int big_big_endpoint() {
  int ans = INF;
  static int has_bee[170];
  for(auto e: E)
    if (e.Y > 1000 && S.count(e.Y))
      has_bee[M[e.X]]++;
  const int n = pr.size();
  FOR(i, n)
    if (has_bee[i] > 1)
      miz(ans, 4);
  FOR(i, n)
      if (has_bee[i])
        FOR(j, i)
          if (has_bee[j])
            miz(ans, m[i][j] + 4);
  return ans;
}

int solve() {
  int a, b;
  FOR(i, n) {
    if (A[i] == 1) return 1;

    int t = ana(A[i], a, b);
    // printf("~%d %d %d\n", t, a, b);
    if (t == 0) return 1;
    if (t == 1) {
      if (S.find(a) != S.end())
        return 2;
      else S.insert(a);
    }
    else {
      if (E.find(mpr(a, b)) != E.end())
        return 2;
      else E.insert(mpr(a,b));
    }
  }
  discrete();
  ggraph();
  int ans = INF;
  miz(ans, minimum_cycle());
  floyd();
  miz(ans, small_endpoint());
  miz(ans, big_small_endpoint());
  miz(ans, big_big_endpoint());
  miz(ans, Ans);

  if (ans == INF)
    return -1;
  return ans;
}

int main() {
  prime();
  R(n);
  FOR(i,n)
    R(A[i]);
  printf("%d\n", solve());
  return 0;
}

/*
4 2 2006 1003 17
3 2 2018 1009
3 2018 5045 10
5 1009 1013 3027 15 5065
5 2 2018 3027 3039 1013
3 6 2018 3027
4 2018 3027 3039 2026
4 1009 2018 3 3027
5 2018 1009 3039 1013 6
4 2018 2026 1009 1013
2 1009 2018
 */


// by david942j
// {{{
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <deque>
#include <cassert>
#include <queue>
#include <stack>
#include <cstdlib>
// #ifndef DAVID
// #include <bits/stdc++.h>
// #endif
#define openfile(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout)
#define mpr std::make_pair
#define lg(x) (31-__builtin_clz(x))
#define lgll(x) (63-__builtin_clzll(x))
#define __count __builtin_popcount
#define __countll __builtin_popcountll
#define X first
#define Y second
#define mst(x) memset(x,0,sizeof(x))
#define mst1(x) memset(x,-1,sizeof(x))
#define ALL(c) (c).begin(),(c).end()
#define FOR(i,n) for(int i=0;i<n;i++)
#define FOR1(i,n) for(int i=1;i<=n;i++)
#define FORit(it,c) for(__typeof(c.begin()) it=c.begin();it!=c.end();++it)
#define pb push_back
#define RI(x) scanf("%d",&x)
#define RID(x) int x;RI(x)

#define IOS do {ios_base::sync_with_stdio(false); cin.tie(0); }while(0)
using namespace std;
template<typename T>
void _R( T &x ) { cin>>x; }
void _R( int &x ) { scanf("%d",&x); }
#ifdef PRId64
void _R( long long &x ) { scanf("%" PRId64,&x); }
#else
void _R( long long &x) {cin >> x;}
#endif
void _R( double &x ) { scanf("%lf",&x); }
void _R( char &x ) { scanf(" %c",&x); }
void _R( char *x ) { scanf("%s",x); }

void R() {}
template<typename T, typename... U>
void R( T& head, U&... tail ) {
  _R(head);
  R(tail...);
}

template<typename T>
void _W( const T &x ) { cout<<x; }
void _W( const int &x ) { printf("%d",x); }
template<typename T>
void _W( const vector<T> &x ) {
  for ( auto i=x.cbegin(); i!=x.cend(); i++ ) {
    if ( i!=x.cbegin() ) putchar(' ');
    _W(*i);
  }
}

void W() {}
template<typename T, typename... U>
void W( const T& head, const U&... tail ) {
  _W(head);
  putchar(sizeof...(tail)?' ':'\n');
  W(tail...);
}
#ifdef DAVID
#define debug(format, ...) fprintf(stderr, format, ##__VA_ARGS__)
#else
#define debug(...)
#endif
#define caset RID(T);FOR1(cas,T)
typedef long long LL;
typedef double LD;
typedef vector<int> VI;
typedef std::pair<int,int> PII;
template<class T>inline void maz(T &a,T b){if(a<b)a=b;}
template<class T>inline void miz(T &a,T b){if(a>b)a=b;}
template<class T>inline T abs(T a){return a>0?a:-a;}
// }}}

const int N = 1e5+10;
const int INF = 1e9+7;
const int MOD = 1e9+7;
int n;
int A[N];
VI pr;

set<int> S;
set<PII> E;

void prime() {
  static bool a[1000];
  for(int i=2;i<1000;i++) {
    if (!a[i]) {
      pr.pb(i);
      for (int j=i*i;j < 1000; j+=i)
        a[j]=1;
    }
  }
  // W(pr.size());
  // W(pr);
}

int ana(int v, int &a, int &b) {
  a = b = 0;
  for (auto p: pr)
    if (v % p == 0) {
      int k = 0;
      do {
        v /= p;
        k++;
      } while (v % p == 0);
      if (k & 1) {
        if (a == 0) a = p;
        else b = p;
      }
    }
    else if (v == 1) break;

  if (v != 1) {
    if (a == 0) a = v;
    else b = v;
  }
  if (a == 0) return 0;
  if (b == 0) return 1;
  return 2;
}

map<int, int> M;
int m[169][169];
VI G[100000];
void discrete() {
  FOR(i, pr.size())
    M[pr[i]] = i;

  int cur = pr.size();
  for(auto s: S)
    if (s > 1000 && M.count(s) == 0)
      M[s] = cur++;
  for(auto e: E) {
    assert(! (e.X > 1000 && M.count(e.X) == 0));
    if (e.Y > 1000 && M.count(e.Y) == 0)
      M[e.Y] = cur++;
  }
  assert(cur < 100000);
}

void ggraph() {
  for(auto e: E)
    if (e.Y > 1000) {
      G[M[e.Y]].pb(M[e.X]);
    }
}

int Ans = INF;
void mgraph() {
  const int n = pr.size();

  FOR(i, n) {
    FOR(j, i)
      m[i][j] = m[j][i] = INF;
    m[i][i] = 0;
  }
  for(auto e: E) {
    const int &x = M[e.X], &y = M[e.Y];
    if (x < n && y < n)
      m[x][y] = m[y][x] = 1;
  }
  FOR(x, M.size())
    FOR(i, G[x].size())
      FOR(j, i) {
        miz(Ans, 2 + m[G[x][i]][G[x][j]]);
        miz(m[G[x][i]][G[x][j]], 2);
        miz(m[G[x][j]][G[x][i]], 2);
      }
}

void floyd() {
  mgraph();
  const int n = pr.size();

  FOR(k, n)
    FOR(i, n)
      FOR(j, n)
        if (m[i][k] != INF && m[k][j] != INF)
          miz(m[i][j], m[i][k] + m[k][j]);
}

int minimum_cycle() {
  mgraph();
  const int n = pr.size();
  int ans = INF;
  int d[169][169];
  memcpy(d, m, sizeof(m));
  FOR(k, n) {
    FOR(i, k)
      if (m[k][i] != INF)
        FOR(j, k)
          if (i != j)
            miz(ans, m[k][i] + d[i][j] + m[j][k]);
    FOR(i, n)
      FOR(j, n)
        if (d[i][k] != INF && d[k][j] != INF)
          miz(d[i][j], d[i][k] + d[k][j]);
  }
  return ans;
}

int small_endpoint() {
  VI v;
  for(auto s: S)
    if (s < 1000)
      v.pb(M[s]);
  int ans = INF;
  FOR(i, v.size())
    FOR(j, i)
      miz(ans, 2 + m[v[j]][v[i]]);
  return ans;
}

int big_cycle() {
  int ans = INF;
  FOR(x, M.size())
    FOR(i, G[x].size())
      FOR(j, i)
        miz(ans, m[G[x][i]][G[x][j]] + 2);
  return ans;
}

int best_end[170];
int big_small_endpoint() {
  const int n = pr.size();
  FOR(i, n)
    best_end[i] = INF;
  VI V;
  for(auto s: S)
    if (s < 1000)
      V.pb(M[s]);
  FOR(i, n)
    for(auto v: V)
      miz(best_end[i], 1 + m[i][v]);

  int ans = INF;
  for(auto s: S)
    if (s > 1000)
      for(auto y: G[M[s]])
        miz(ans, 2 + best_end[y]);

  return ans;
}

int big_big_endpoint() {
  int ans = INF;
  static bool has_bee[170];
  for(auto e: E)
    if (e.Y > 1000 && S.count(e.Y))
      has_bee[M[e.X]] = true;
  const int n = pr.size();
  FOR(i, n)
      if (has_bee[i])
        FOR(j, i)
          if (has_bee[j])
            miz(ans, m[i][j] + 4);
  return ans;
}

int solve() {
  int a, b;
  FOR(i, n) {
    if (A[i] == 1) return 1;

    int t = ana(A[i], a, b);
    // printf("~%d %d %d\n", t, a, b);
    if (t == 0) return 1;
    if (t == 1) {
      if (S.find(a) != S.end())
        return 2;
      else S.insert(a);
    }
    else {
      if (E.find(mpr(a, b)) != E.end())
        return 2;
      else E.insert(mpr(a,b));
    }
  }
  discrete();
  ggraph();
  int ans = INF;
  miz(ans, minimum_cycle());
  floyd();
  miz(ans, small_endpoint());
  miz(ans, big_small_endpoint());
  miz(ans, big_big_endpoint());
  miz(ans, Ans);
  // miz(ans, big_cycle());

  if (ans == INF)
    return -1;
  return ans;
}

int main() {
  prime();
  R(n);
  FOR(i,n)
    R(A[i]);
  printf("%d\n", solve());
  return 0;
}

/*
4 2 2006 1003 17
3 2 2018 1009
3 2018 5045 10
5 1009 1013 3027 15 5065
5 2 2018 3027 3039 1013
3 6 2018 3027
4 2018 3027 3039 2026
 */


// by david942j
// {{{
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <deque>
#include <cassert>
#include <queue>
#include <stack>
#include <cstdlib>
// #ifndef DAVID
// #include <bits/stdc++.h>
// #endif
#define openfile(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout)
#define mpr std::make_pair
#define lg(x) (31-__builtin_clz(x))
#define lgll(x) (63-__builtin_clzll(x))
#define __count __builtin_popcount
#define __countll __builtin_popcountll
#define X first
#define Y second
#define mst(x) memset(x,0,sizeof(x))
#define mst1(x) memset(x,-1,sizeof(x))
#define ALL(c) (c).begin(),(c).end()
#define FOR(i,n) for(int i=0;i<n;i++)
#define FOR1(i,n) for(int i=1;i<=n;i++)
#define FORit(it,c) for(__typeof(c.begin()) it=c.begin();it!=c.end();++it)
#define pb push_back
#define RI(x) scanf("%d",&x)
#define RID(x) int x;RI(x)

#define IOS do {ios_base::sync_with_stdio(false); cin.tie(0); }while(0)
using namespace std;
template<typename T>
void _R( T &x ) { cin>>x; }
void _R( int &x ) { scanf("%d",&x); }
#ifdef PRId64
void _R( long long &x ) { scanf("%" PRId64,&x); }
#else
void _R( long long &x) {cin >> x;}
#endif
void _R( double &x ) { scanf("%lf",&x); }
void _R( char &x ) { scanf(" %c",&x); }
void _R( char *x ) { scanf("%s",x); }

void R() {}
template<typename T, typename... U>
void R( T& head, U&... tail ) {
  _R(head);
  R(tail...);
}

template<typename T>
void _W( const T &x ) { cout<<x; }
void _W( const int &x ) { printf("%d",x); }
template<typename T>
void _W( const vector<T> &x ) {
  for ( auto i=x.cbegin(); i!=x.cend(); i++ ) {
    if ( i!=x.cbegin() ) putchar(' ');
    _W(*i);
  }
}

void W() {}
template<typename T, typename... U>
void W( const T& head, const U&... tail ) {
  _W(head);
  putchar(sizeof...(tail)?' ':'\n');
  W(tail...);
}
#ifdef DAVID
#define debug(format, ...) fprintf(stderr, format, ##__VA_ARGS__)
#else
#define debug(...)
#endif
#define caset RID(T);FOR1(cas,T)
typedef long long LL;
typedef double LD;
typedef vector<int> VI;
typedef std::pair<int,int> PII;
template<class T>inline void maz(T &a,T b){if(a<b)a=b;}
template<class T>inline void miz(T &a,T b){if(a>b)a=b;}
template<class T>inline T abs(T a){return a>0?a:-a;}
// }}}

const int N = 1e5+10;
const int INF = 1e9+7;
const int MOD = 1e9+7;
int n;
int A[N];
VI pr;

set<int> S;
set<PII> E;

void prime() {
  static bool a[1000];
  for(int i=2;i<1000;i++) {
    if (!a[i]) {
      pr.pb(i);
      for (int j=i*i;j < 1000; j+=i)
        a[j]=1;
    }
  }
  // W(pr.size());
  // W(pr);
}

int ana(int v, int &a, int &b) {
  a = b = 0;
  for (auto p: pr)
    if (v % p == 0) {
      int k = 0;
      do {
        v /= p;
        k++;
      } while (v % p == 0);
      if (k & 1) {
        if (a == 0) a = p;
        else b = p;
      }
    }
    else if (v == 1) break;

  if (v != 1) {
    if (a == 0) a = v;
    else b = v;
  }
  if (a == 0) return 0;
  if (b == 0) return 1;
  return 2;
}

map<int, int> M;
int m[169][169];
VI G[100000];
void discrete() {
  FOR(i, pr.size())
    M[pr[i]] = i;

  int cur = pr.size();
  for(auto s: S)
    if (s > 1000 && M.count(s) == 0)
      M[s] = cur++;
  for(auto e: E) {
    assert(! (e.X > 1000 && M.count(e.X) == 0));
    if (e.Y > 1000 && M.count(e.Y) == 0)
      M[e.Y] = cur++;
  }
  assert(cur < 100000);
}

void ggraph() {
  for(auto e: E)
    if (e.Y > 1000) {
      G[M[e.Y]].pb(M[e.X]);
    }
}

int Ans = INF;
void mgraph() {
  const int n = pr.size();

  FOR(i, n) {
    FOR(j, i)
      m[i][j] = m[j][i] = INF;
    m[i][i] = 0;
  }
  for(auto e: E) {
    const int &x = M[e.X], &y = M[e.Y];
    if (x < n && y < n)
      m[x][y] = m[y][x] = 1;
  }
  FOR(x, M.size())
    FOR(i, G[x].size())
      FOR(j, i) {
        if (m[G[x][i]][G[x][j]] != INF)
          miz(Ans, 2 + m[G[x][i]][G[x][j]]);
        miz(m[G[x][i]][G[x][j]], 2);
        miz(m[G[x][j]][G[x][i]], 2);
      }
}

void floyd() {
  mgraph();
  const int n = pr.size();

  FOR(k, n)
    FOR(i, n)
      FOR(j, n)
        if (m[i][k] != INF && m[k][j] != INF)
          miz(m[i][j], m[i][k] + m[k][j]);
}

int minimum_cycle() {
  mgraph();
  if (Ans != INF) return Ans;
  const int n = pr.size();
  int ans = INF;
  int d[169][169];
  memcpy(d, m, sizeof(m));
  FOR(k, n) {
    FOR(i, k)
      if (m[k][i] != INF)
        FOR(j, k)
          if (i != j)
            miz(ans, m[k][i] + d[i][j] + m[j][k]);
    FOR(i, n)
      FOR(j, n)
        if (d[i][k] != INF && d[k][j] != INF)
          miz(d[i][j], d[i][k] + d[k][j]);
  }
  return ans;
}

int small_endpoint() {
  VI v;
  for(auto s: S)
    if (s < 1000)
      v.pb(M[s]);
  int ans = INF;
  FOR(i, v.size())
    FOR(j, i)
      miz(ans, 2 + m[v[j]][v[i]]);
  return ans;
}

int big_cycle() {
  int ans = INF;
  FOR(x, M.size())
    FOR(i, G[x].size())
      FOR(j, i)
        miz(ans, m[G[x][i]][G[x][j]] + 2);
  return ans;
}

int best_end[170];
int big_small_endpoint() {
  const int n = pr.size();
  FOR(i, n)
    best_end[i] = INF;
  VI V;
  for(auto s: S)
    if (s < 1000)
      V.pb(M[s]);
  FOR(i, n)
    for(auto v: V)
      miz(best_end[i], 1 + m[i][v]);

  int ans = INF;
  for(auto s: S)
    if (s > 1000)
      for(auto y: G[M[s]])
        miz(ans, 2 + best_end[y]);

  return ans;
}

int big_big_endpoint() {
  int ans = INF;
  static bool has_bee[170];
  for(auto e: E)
    if (e.Y > 1000 && S.count(e.Y))
      has_bee[M[e.X]] = true;
  const int n = pr.size();
  FOR(i, n)
      if (has_bee[i])
        FOR(j, i)
          if (has_bee[j])
            miz(ans, m[i][j] + 4);
  return ans;
}

int solve() {
  int a, b;
  FOR(i, n) {
    if (A[i] == 1) return 1;

    int t = ana(A[i], a, b);
    // printf("~%d %d %d\n", t, a, b);
    if (t == 0) return 1;
    if (t == 1) {
      if (S.find(a) != S.end())
        return 2;
      else S.insert(a);
    }
    else {
      if (E.find(mpr(a, b)) != E.end())
        return 2;
      else E.insert(mpr(a,b));
    }
  }
  discrete();
  ggraph();
  int ans = INF;
  miz(ans, minimum_cycle());
  floyd();
  miz(ans, small_endpoint());
  miz(ans, big_small_endpoint());
  miz(ans, big_big_endpoint());
  // miz(ans, big_cycle());

  if (ans == INF)
    return -1;
  return ans;
}

int main() {
  prime();
  R(n);
  FOR(i,n)
    R(A[i]);
  printf("%d\n", solve());
  return 0;
}

/*
4 2 2006 1003 17
3 2 2018 1009
3 2018 5045 10
5 1009 1013 3027 15 5065
5 2 2018 3027 3039 1013
3 6 2018 3027
4 2018 3027 3039 2026
 */


// by david942j
// {{{
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <deque>
#include <cassert>
#include <queue>
#include <stack>
#include <cstdlib>
// #ifndef DAVID
// #include <bits/stdc++.h>
// #endif
#define openfile(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout)
#define mpr std::make_pair
#define lg(x) (31-__builtin_clz(x))
#define lgll(x) (63-__builtin_clzll(x))
#define __count __builtin_popcount
#define __countll __builtin_popcountll
#define X first
#define Y second
#define mst(x) memset(x,0,sizeof(x))
#define mst1(x) memset(x,-1,sizeof(x))
#define ALL(c) (c).begin(),(c).end()
#define FOR(i,n) for(int i=0;i<n;i++)
#define FOR1(i,n) for(int i=1;i<=n;i++)
#define FORit(it,c) for(__typeof(c.begin()) it=c.begin();it!=c.end();++it)
#define pb push_back
#define RI(x) scanf("%d",&x)
#define RID(x) int x;RI(x)

#define IOS do {ios_base::sync_with_stdio(false); cin.tie(0); }while(0)
using namespace std;
template<typename T>
void _R( T &x ) { cin>>x; }
void _R( int &x ) { scanf("%d",&x); }
#ifdef PRId64
void _R( long long &x ) { scanf("%" PRId64,&x); }
#else
void _R( long long &x) {cin >> x;}
#endif
void _R( double &x ) { scanf("%lf",&x); }
void _R( char &x ) { scanf(" %c",&x); }
void _R( char *x ) { scanf("%s",x); }

void R() {}
template<typename T, typename... U>
void R( T& head, U&... tail ) {
  _R(head);
  R(tail...);
}

template<typename T>
void _W( const T &x ) { cout<<x; }
void _W( const int &x ) { printf("%d",x); }
template<typename T>
void _W( const vector<T> &x ) {
  for ( auto i=x.cbegin(); i!=x.cend(); i++ ) {
    if ( i!=x.cbegin() ) putchar(' ');
    _W(*i);
  }
}

void W() {}
template<typename T, typename... U>
void W( const T& head, const U&... tail ) {
  _W(head);
  putchar(sizeof...(tail)?' ':'\n');
  W(tail...);
}
#ifdef DAVID
#define debug(format, ...) fprintf(stderr, format, ##__VA_ARGS__)
#else
#define debug(...)
#endif
#define caset RID(T);FOR1(cas,T)
typedef long long LL;
typedef double LD;
typedef vector<int> VI;
typedef std::pair<int,int> PII;
template<class T>inline void maz(T &a,T b){if(a<b)a=b;}
template<class T>inline void miz(T &a,T b){if(a>b)a=b;}
template<class T>inline T abs(T a){return a>0?a:-a;}
// }}}

const int N = 1e5+10;
const int INF = 1e9+7;
const int MOD = 1e9+7;
int n;
int A[N];
VI pr;

set<int> S;
set<PII> E;

void prime() {
  static bool a[1000];
  for(int i=2;i<1000;i++) {
    if (!a[i]) {
      pr.pb(i);
      for (int j=i*i;j < 1000; j+=i)
        a[j]=1;
    }
  }
  // W(pr.size());
  // W(pr);
}

int ana(int v, int &a, int &b) {
  a = b = 0;
  for (auto p: pr)
    if (v % p == 0) {
      int k = 0;
      do {
        v /= p;
        k++;
      } while (v % p == 0);
      if (k & 1) {
        if (a == 0) a = p;
        else b = p;
      }
    }
    else if (v == 1) break;

  if (v != 1) {
    if (a == 0) a = v;
    else b = v;
  }
  if (a == 0) return 0;
  if (b == 0) return 1;
  return 2;
}

map<int, int> M;
int m[169][169];
VI G[200000];
void discrete() {
  FOR(i, pr.size())
    M[pr[i]] = i;

  int cur = pr.size();
  for(auto s: S)
    if (s > 1000 && M.count(s) == 0)
      M[s] = cur++;
  for(auto e: E) {
    assert(! (e.X > 1000 && M.count(e.X) == 0));
    if (e.Y > 1000 && M.count(e.Y) == 0)
      M[e.Y] = cur++;
  }
}

void ggraph() {
  for(auto e: E)
    if (e.Y > 1000) {
      G[M[e.Y]].pb(M[e.X]);
    }
}

void mgraph() {
  const int n = pr.size();

  FOR(i, n) {
    FOR(j, i)
      m[i][j] = m[j][i] = INF;
    m[i][i] = 0;
  }
  for(auto e: E) {
    const int &x = M[e.X], &y = M[e.Y];
    if (x < n && y < n)
      m[x][y] = m[y][x] = 1;
  }
}

void floyd() {
  mgraph();
  const int n = pr.size();

  FOR(k, n)
    FOR(i, n)
      FOR(j, n)
        if (m[i][k] != INF && m[k][j] != INF)
          miz(m[i][j], m[i][k] + m[k][j]);
}

int BFS(int x, int y) {
  queue<int> Q;
  const int n = pr.size();
  int dis[170];
  FOR(i, n)
    dis[i] = INF;
  Q.push(x); dis[x] = 0;
  while (!Q.empty()) {
    auto a = Q.front(); Q.pop();
    FOR(i, n)
      if (m[a][i] == 1 && dis[i] == INF) {
        dis[i] = dis[a] + 1;
        if (y == i)
          return dis[y];
        Q.push(i);
      }
  }

  return INF;
}

int small_cycle() {
  mgraph();
  const int n = pr.size();
  int ans = INF;
  FOR(i, n)
    FOR(j, i)
      if (m[j][i] == 1) {
        m[j][i] = m[i][j] = INF;
        int len = BFS(i, j);
        m[j][i] = m[i][j] = 1;
        miz(ans, len + 1);
      }
  return ans;
}

int small_endpoint() {
  VI v;
  for(auto s: S)
    if (s < 1000)
      v.pb(M[s]);
  int ans = INF;
  FOR(i, v.size())
    FOR(j, i)
      miz(ans, 2 + m[v[j]][v[i]]);
  return ans;
}

int big_cycle() {
  int ans = INF;
  FOR(x, M.size())
    FOR(i, G[x].size())
      FOR(j, i)
        miz(ans, m[G[x][i]][G[x][j]] + 2);
  return ans;
}

int big_endpoint() {
  static int best_end[170];
  const int n = pr.size();
  FOR(i, n)
    best_end[i] = INF;
  VI V;
  for(auto s: S)
    if (s < 1000)
      V.pb(M[s]);
  FOR(i, n)
    for(auto v: V)
      miz(best_end[i], 1 + m[i][v]);

  int ans = INF;
  for(auto s: S)
    if (s > 1000)
      for(auto y: G[M[s]])
        miz(ans, 2 + best_end[y]);

  return ans;
}

int solve() {
  int a, b;
  FOR(i, n) {
    if (A[i] == 1) return 1;

    int t = ana(A[i], a, b);
    // printf("~%d %d %d\n", t, a, b);
    if (t == 0) return 1;
    if (t == 1) {
      if (S.find(a) != S.end())
        return 2;
      else S.insert(a);
    }
    else {
      if (E.find(mpr(a, b)) != E.end())
        return 2;
      else E.insert(mpr(a,b));
    }
  }
  discrete();
  int ans = INF;
  miz(ans, small_cycle());
  floyd();
  miz(ans, small_endpoint());
  ggraph();
  miz(ans, big_endpoint());
  miz(ans, big_cycle());

  if (ans == INF)
    return -1;
  return ans;
}

int main() {
  prime();
  R(n);
  FOR(i,n)
    R(A[i]);
  printf("%d\n", solve());
  return 0;
}

/*
3 2 2006 1003
4 2 2006 1003 17
3 2 2018 1009
3 2018 5045 10
 */


// by david942j
// {{{
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <deque>
#include <cassert>
#include <queue>
#include <stack>
#include <cstdlib>
// #ifndef DAVID
// #include <bits/stdc++.h>
// #endif
#define openfile(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout)
#define mpr std::make_pair
#define lg(x) (31-__builtin_clz(x))
#define lgll(x) (63-__builtin_clzll(x))
#define __count __builtin_popcount
#define __countll __builtin_popcountll
#define X first
#define Y second
#define mst(x) memset(x,0,sizeof(x))
#define mst1(x) memset(x,-1,sizeof(x))
#define ALL(c) (c).begin(),(c).end()
#define FOR(i,n) for(int i=0;i<n;i++)
#define FOR1(i,n) for(int i=1;i<=n;i++)
#define FORit(it,c) for(__typeof(c.begin()) it=c.begin();it!=c.end();++it)
#define pb push_back
#define RI(x) scanf("%d",&x)
#define RID(x) int x;RI(x)

#define IOS do {ios_base::sync_with_stdio(false); cin.tie(0); }while(0)
using namespace std;
template<typename T>
void _R( T &x ) { cin>>x; }
void _R( int &x ) { scanf("%d",&x); }
#ifdef PRId64
void _R( long long &x ) { scanf("%" PRId64,&x); }
#else
void _R( long long &x) {cin >> x;}
#endif
void _R( double &x ) { scanf("%lf",&x); }
void _R( char &x ) { scanf(" %c",&x); }
void _R( char *x ) { scanf("%s",x); }

void R() {}
template<typename T, typename... U>
void R( T& head, U&... tail ) {
  _R(head);
  R(tail...);
}

template<typename T>
void _W( const T &x ) { cout<<x; }
void _W( const int &x ) { printf("%d",x); }
template<typename T>
void _W( const vector<T> &x ) {
  for ( auto i=x.cbegin(); i!=x.cend(); i++ ) {
    if ( i!=x.cbegin() ) putchar(' ');
    _W(*i);
  }
}

void W() {}
template<typename T, typename... U>
void W( const T& head, const U&... tail ) {
  _W(head);
  putchar(sizeof...(tail)?' ':'\n');
  W(tail...);
}
#ifdef DAVID
#define debug(format, ...) fprintf(stderr, format, ##__VA_ARGS__)
#else
#define debug(...)
#endif
#define caset RID(T);FOR1(cas,T)
typedef long long LL;
typedef double LD;
typedef vector<int> VI;
typedef std::pair<int,int> PII;
template<class T>inline void maz(T &a,T b){if(a<b)a=b;}
template<class T>inline void miz(T &a,T b){if(a>b)a=b;}
template<class T>inline T abs(T a){return a>0?a:-a;}
// }}}

const int N = 1e5+10;
const int INF = 1e9+7;
const int MOD = 1e9+7;
int n;
int A[N];
VI pr;

set<int> S;
set<PII> E;

void prime() {
  static bool a[1000];
  for(int i=2;i<1000;i++) {
    if (!a[i]) {
      pr.pb(i);
      for (int j=i*i;j < 1000; j+=i)
        a[j]=1;
    }
  }
}

int ana(int v, int &a, int &b) {
  a = b = 0;
  for (auto p: pr)
    if (v % p == 0) {
      int k = 0;
      do {
        v /= p;
        k++;
      } while (v % p == 0);
      if (k & 1) {
        if (a == 0) a = p;
        else { assert(b == 0); b = p; }
      }
    }
    else if (v == 1) break;

  if (v != 1) {
    if (a == 0) a = v;
    else { assert(b == 0); b = v; }
  }
  if (a == 0) return 0;
  if (b == 0) return 1;
  return 2;
}

map<int, int> M;
int m[169][169];
VI G[100000];
void discrete() {
  FOR(i, pr.size())
    M[pr[i]] = i;

  int cur = pr.size();
  for(auto s: S)
    if (s > 1000 && M.count(s) == 0)
      M[s] = cur++;
  for(auto e: E) {
    assert(!(e.X > 1000));
    if (e.Y > 1000 && M.count(e.Y) == 0)
      M[e.Y] = cur++;
  }
  assert(cur < 100000);
  assert(cur == M.size());
}

void ggraph() {
  for(auto e: E)
    if (e.Y > 1000) {
      G[M[e.Y]].pb(M[e.X]);
    }
}

int Ans = INF;
void mgraph() {
  const int n = pr.size();

  FOR(i, n) {
    FOR(j, i)
      m[i][j] = m[j][i] = INF;
    m[i][i] = 0;
  }
  for(auto e: E) {
    const int &x = M[e.X], &y = M[e.Y];
    if (x < n && y < n)
      m[x][y] = m[y][x] = 1;
  }
  FOR(x, M.size())
    FOR(i, G[x].size())
      FOR(j, i) {
        miz(Ans, 2 + m[G[x][i]][G[x][j]]);
        miz(m[G[x][i]][G[x][j]], 2);
        miz(m[G[x][j]][G[x][i]], 2);
      }
}

int minimum_cycle() {
  const int n = pr.size();
  int ans = INF;
  int d[169][169];
  memcpy(d, m, sizeof(m));
  FOR(k, n) {
    FOR(i, k)
      if (d[k][i] != INF)
        FOR(j, i)
          miz(ans, d[k][i] + m[i][j] + d[j][k]);
    FOR(i, n)
      if (m[i][k] != INF)
        FOR(j, n)
          if (m[k][j] != INF)
            miz(m[i][j], m[i][k] + m[k][j]);
  }
  return ans;
}

int best[170], snd[170];
void update_end(int x, int v) {
  if (best[x] >= v) {
    snd[x] = best[x]; best[x] = v;
  } else if (snd[x] > v)
    snd[x] = v;
}

void good_end() {
  const int n = pr.size();
  FOR(i, n)
    best[i] = snd[i] = INF;
  VI V;
  for(auto s: S)
    if (s < 1000)
      V.pb(M[s]);
  FOR(i, n)
    for(auto v: V)
      update_end(i, 1 + m[i][v]);
  for(auto e: E)
    if (e.Y > 1000 && S.count(e.Y))
      update_end(M[e.X], 2);
}

int endpoint() {
  int ans = INF;
  FOR(i, n)
    miz(ans, best[i] + snd[i]);
  FOR(i, n)
    FOR(j, n)
      if (m[i][j] != INF && i != j)
        miz(ans, best[i] + best[j] + m[i][j]);
  return ans;
}

int solve() {
  int a, b;
  FOR(i, n) {
    if (A[i] == 1) return 1;

    int t = ana(A[i], a, b);
    // printf("~%d %d %d\n", t, a, b);
    if (t == 0) return 1;
    if (t == 1) {
      if (S.find(a) != S.end())
        return 2;
      else S.insert(a);
    }
    else {
      assert(a < b && a && b);
      if (E.find(mpr(a, b)) != E.end())
        return 2;
      else E.insert(mpr(a,b));
    }
  }
  discrete();
  ggraph();
  mgraph();
  int ans = Ans;
  miz(ans, minimum_cycle());
  good_end();
  miz(ans, endpoint());

  if (ans == INF)
    return -1;
  return ans;
}

int main() {
  prime();
  R(n);
  FOR(i,n)
    R(A[i]);
  printf("%d\n", solve());
  return 0;
}

/*
4 2 2006 1003 17
3 2 2018 1009
3 2018 5045 10
5 1009 1013 3027 15 5065
5 2 2018 3027 3039 1013
3 6 2018 3027
4 2018 3027 3039 2026
4 1009 2018 3 3027 # 3
5 2018 1009 3039 1013 6
4 2018 2026 1009 1013
2 1009 2018
 */


// by david942j
// {{{
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <deque>
#include <cassert>
#include <queue>
#include <stack>
#include <cstdlib>
// #ifndef DAVID
// #include <bits/stdc++.h>
// #endif
#define openfile(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout)
#define mpr std::make_pair
#define lg(x) (31-__builtin_clz(x))
#define lgll(x) (63-__builtin_clzll(x))
#define __count __builtin_popcount
#define __countll __builtin_popcountll
#define X first
#define Y second
#define mst(x) memset(x,0,sizeof(x))
#define mst1(x) memset(x,-1,sizeof(x))
#define ALL(c) (c).begin(),(c).end()
#define FOR(i,n) for(int i=0;i<n;i++)
#define FOR1(i,n) for(int i=1;i<=n;i++)
#define FORit(it,c) for(__typeof(c.begin()) it=c.begin();it!=c.end();++it)
#define pb push_back
#define RI(x) scanf("%d",&x)
#define RID(x) int x;RI(x)

#define IOS do {ios_base::sync_with_stdio(false); cin.tie(0); }while(0)
using namespace std;
template<typename T>
void _R( T &x ) { cin>>x; }
void _R( int &x ) { scanf("%d",&x); }
#ifdef PRId64
void _R( long long &x ) { scanf("%" PRId64,&x); }
#else
void _R( long long &x) {cin >> x;}
#endif
void _R( double &x ) { scanf("%lf",&x); }
void _R( char &x ) { scanf(" %c",&x); }
void _R( char *x ) { scanf("%s",x); }

void R() {}
template<typename T, typename... U>
void R( T& head, U&... tail ) {
  _R(head);
  R(tail...);
}

template<typename T>
void _W( const T &x ) { cout<<x; }
void _W( const int &x ) { printf("%d",x); }
template<typename T>
void _W( const vector<T> &x ) {
  for ( auto i=x.cbegin(); i!=x.cend(); i++ ) {
    if ( i!=x.cbegin() ) putchar(' ');
    _W(*i);
  }
}

void W() {}
template<typename T, typename... U>
void W( const T& head, const U&... tail ) {
  _W(head);
  putchar(sizeof...(tail)?' ':'\n');
  W(tail...);
}
#ifdef DAVID
#define debug(format, ...) fprintf(stderr, format, ##__VA_ARGS__)
#else
#define debug(...)
#endif
#define caset RID(T);FOR1(cas,T)
typedef long long LL;
typedef double LD;
typedef vector<int> VI;
typedef std::pair<int,int> PII;
template<class T>inline void maz(T &a,T b){if(a<b)a=b;}
template<class T>inline void miz(T &a,T b){if(a>b)a=b;}
template<class T>inline T abs(T a){return a>0?a:-a;}
// }}}

const int N = 1e5+10;
const int INF = 1e9+7;
const int MOD = 1e9+7;
int n;
int A[N];
VI pr;

set<int> S;
set<PII> E;

void prime() {
  static bool a[1000];
  for(int i=2;i<1000;i++) {
    if (!a[i]) {
      pr.pb(i);
      for (int j=i*i;j < 1000; j+=i)
        a[j]=1;
    }
  }
}

int ana(int v, int &a, int &b) {
  a = b = 0;
  for (auto p: pr)
    if (v % p == 0) {
      int k = 0;
      do {
        v /= p;
        k++;
      } while (v % p == 0);
      if (k & 1) {
        if (a == 0) a = p;
        else { assert(b == 0); b = p; }
      }
    }
    else if (v == 1) break;

  if (v != 1) {
    if (a == 0) a = v;
    else { assert(b == 0); b = v; }
  }
  if (a == 0) return 0;
  if (b == 0) return 1;
  return 2;
}

map<int, int> M;
int m[169][169];
VI G[100000];
void discrete() {
  FOR(i, pr.size())
    M[pr[i]] = i;

  int cur = pr.size();
  for(auto s: S)
    if (s > 1000 && M.count(s) == 0)
      M[s] = cur++;
  for(auto e: E) {
    assert(!(e.X > 1000));
    if (e.Y > 1000 && M.count(e.Y) == 0)
      M[e.Y] = cur++;
  }
  assert(cur < 100000);
  assert(cur == M.size());
}

void ggraph() {
  for(auto e: E)
    if (e.Y > 1000) {
      G[M[e.Y]].pb(M[e.X]);
    }
}

int Ans = INF;
void mgraph() {
  const int n = pr.size();

  FOR(i, n) {
    FOR(j, i)
      m[i][j] = m[j][i] = INF;
    m[i][i] = 0;
  }
  for(auto e: E) {
    const int &x = M[e.X], &y = M[e.Y];
    if (x < n && y < n)
      m[x][y] = m[y][x] = 1;
  }
  FOR(x, M.size())
    FOR(i, G[x].size())
      FOR(j, i) {
        miz(Ans, 2 + m[G[x][i]][G[x][j]]);
        miz(m[G[x][i]][G[x][j]], 2);
        miz(m[G[x][j]][G[x][i]], 2);
      }
}

int minimum_cycle() {
  const int n = pr.size();
  int ans = INF;
  int d[169][169];
  memcpy(d, m, sizeof(m));
  FOR(k, n) {
    FOR(i, k)
      if (d[k][i] != INF)
        FOR(j, i)
          miz(ans, d[k][i] + m[i][j] + d[j][k]);
    FOR(i, n)
      if (m[i][k] != INF)
        FOR(j, n)
          if (m[k][j] != INF)
            miz(m[i][j], m[i][k] + m[k][j]);
  }
  return ans;
}

int small_endpoint() {
  VI v;
  for(auto s: S)
    if (s < 1000)
      v.pb(M[s]);
  int ans = INF;
  FOR(i, v.size())
    FOR(j, i)
      miz(ans, 2 + m[v[j]][v[i]]);
  return ans;
}

int best_end[170];
int big_small_endpoint() {
  const int n = pr.size();
  FOR(i, n)
    best_end[i] = INF;
  VI V;
  for(auto s: S)
    if (s < 1000)
      V.pb(M[s]);
  FOR(i, n)
    for(auto v: V)
      miz(best_end[i], 1 + m[i][v]);

  int ans = INF;
  for(auto s: S)
    if (s > 1000)
      for(auto y: G[M[s]])
        miz(ans, 2 + best_end[y]);

  return ans;
}

int big_big_endpoint() {
  int ans = INF;
  static int has_bee[170];
  for(auto e: E)
    if (e.Y > 1000 && S.count(e.Y)) {
      const int &x = M[e.X];
      if (has_bee[x] == 0)
        has_bee[x] = -e.Y;
      else if (has_bee[x] < 0)
        has_bee[x] = 2;
    }
  const int n = pr.size();
  FOR(i, n)
    if (has_bee[i] == 2)
      miz(ans, 4);
  FOR(i, n)
      if (has_bee[i])
        FOR(j, i)
          if (has_bee[j]) {
            if (has_bee[i] < 0 && has_bee[j] < 0 && has_bee[i] == has_bee[j]) continue;
            miz(ans, m[i][j] + 4);
          }
  return ans;
}

int solve() {
  int a, b;
  FOR(i, n) {
    if (A[i] == 1) return 1;

    int t = ana(A[i], a, b);
    // printf("~%d %d %d\n", t, a, b);
    if (t == 0) return 1;
    if (t == 1) {
      if (S.find(a) != S.end())
        return 2;
      else S.insert(a);
    }
    else {
      assert(a < b && a && b);
      if (E.find(mpr(a, b)) != E.end())
        return 2;
      else E.insert(mpr(a,b));
    }
  }
  discrete();
  ggraph();
  mgraph();
  int ans = Ans;
  miz(ans, minimum_cycle());
  miz(ans, small_endpoint());
  miz(ans, big_small_endpoint());
  miz(ans, big_big_endpoint());

  if (ans == INF)
    return -1;
  return ans;
}

int main() {
  prime();
  R(n);
  FOR(i,n)
    R(A[i]);
  printf("%d\n", solve());
  return 0;
}

/*
3 2 2018 1009
3 2018 5045 10
5 1009 1013 3027 15 5065
5 2 2018 3027 3039 1013
3 6 2018 3027
4 2018 3027 3039 2026
4 1009 2018 3 3027 # 3
5 2018 1009 3039 1013 6
4 2018 2026 1009 1013
2 1009 2018
5 3 5 2018 3027 10
3 2018 3027 1009
 */


// by david942j
// {{{
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <deque>
#include <cassert>
#include <queue>
#include <stack>
#include <cstdlib>
// #ifndef DAVID
// #include <bits/stdc++.h>
// #endif
#define openfile(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout)
#define mpr std::make_pair
#define lg(x) (31-__builtin_clz(x))
#define lgll(x) (63-__builtin_clzll(x))
#define __count __builtin_popcount
#define __countll __builtin_popcountll
#define X first
#define Y second
#define mst(x) memset(x,0,sizeof(x))
#define mst1(x) memset(x,-1,sizeof(x))
#define ALL(c) (c).begin(),(c).end()
#define FOR(i,n) for(int i=0;i<n;i++)
#define FOR1(i,n) for(int i=1;i<=n;i++)
#define FORit(it,c) for(__typeof(c.begin()) it=c.begin();it!=c.end();++it)
#define pb push_back
#define RI(x) scanf("%d",&x)
#define RID(x) int x;RI(x)

#define IOS do {ios_base::sync_with_stdio(false); cin.tie(0); }while(0)
using namespace std;
template<typename T>
void _R( T &x ) { cin>>x; }
void _R( int &x ) { scanf("%d",&x); }
#ifdef PRId64
void _R( long long &x ) { scanf("%" PRId64,&x); }
#else
void _R( long long &x) {cin >> x;}
#endif
void _R( double &x ) { scanf("%lf",&x); }
void _R( char &x ) { scanf(" %c",&x); }
void _R( char *x ) { scanf("%s",x); }

void R() {}
template<typename T, typename... U>
void R( T& head, U&... tail ) {
  _R(head);
  R(tail...);
}

template<typename T>
void _W( const T &x ) { cout<<x; }
void _W( const int &x ) { printf("%d",x); }
template<typename T>
void _W( const vector<T> &x ) {
  for ( auto i=x.cbegin(); i!=x.cend(); i++ ) {
    if ( i!=x.cbegin() ) putchar(' ');
    _W(*i);
  }
}

void W() {}
template<typename T, typename... U>
void W( const T& head, const U&... tail ) {
  _W(head);
  putchar(sizeof...(tail)?' ':'\n');
  W(tail...);
}
#ifdef DAVID
#define debug(format, ...) fprintf(stderr, format, ##__VA_ARGS__)
#else
#define debug(...)
#endif
#define caset RID(T);FOR1(cas,T)
typedef long long LL;
typedef double LD;
typedef vector<int> VI;
typedef std::pair<int,int> PII;
template<class T>inline void maz(T &a,T b){if(a<b)a=b;}
template<class T>inline void miz(T &a,T b){if(a>b)a=b;}
template<class T>inline T abs(T a){return a>0?a:-a;}
// }}}

const int N = 1e5+10;
const int INF = 1e9+7;
const int MOD = 1e9+7;
int n;
int A[N];
VI pr;

set<int> S;
set<PII> E;

void prime() {
  static bool a[1000];
  for(int i=2;i<1000;i++) {
    if (!a[i]) {
      pr.pb(i);
      for (int j=i*i;j < 1000; j+=i)
        a[j]=1;
    }
  }
  // W(pr.size());
  // W(pr);
}

int ana(int v, int &a, int &b) {
  a = b = 0;
  for (auto p: pr)
    if (v % p == 0) {
      int k = 0;
      do {
        v /= p;
        k++;
      } while (v % p == 0);
      if (k & 1) {
        if (a == 0) a = p;
        else { assert(b == 0); b = p; }
      }
    }
    else if (v == 1) break;

  if (v != 1) {
    if (a == 0) a = v;
    else { assert(b == 0); b = v; }
  }
  if (a == 0) return 0;
  if (b == 0) return 1;
  return 2;
}

map<int, int> M;
int m[169][169];
VI G[100000];
void discrete() {
  FOR(i, pr.size())
    M[pr[i]] = i;

  int cur = pr.size();
  for(auto s: S)
    if (s > 1000 && M.count(s) == 0)
      M[s] = cur++;
  for(auto e: E) {
    assert(!(e.X > 1000));
    if (e.Y > 1000 && M.count(e.Y) == 0)
      M[e.Y] = cur++;
  }
  assert(cur < 100000);
}

void ggraph() {
  for(auto e: E)
    if (e.Y > 1000) {
      G[M[e.Y]].pb(M[e.X]);
    }
}

int Ans = INF;
void mgraph() {
  const int n = pr.size();

  FOR(i, n) {
    FOR(j, i)
      m[i][j] = m[j][i] = INF;
    m[i][i] = 0;
  }
  for(auto e: E) {
    const int &x = M[e.X], &y = M[e.Y];
    if (x < n && y < n)
      m[x][y] = m[y][x] = 1;
  }
  FOR(x, M.size())
    FOR(i, G[x].size())
      FOR(j, i) {
        miz(Ans, 2 + m[G[x][i]][G[x][j]]);
        miz(m[G[x][i]][G[x][j]], 2);
        miz(m[G[x][j]][G[x][i]], 2);
      }
}

void floyd() {
  const int n = pr.size();

  FOR(k, n)
    FOR(i, n)
      if (m[i][k] != INF)
        FOR(j, n)
          if (m[k][j] != INF)
            miz(m[i][j], m[i][k] + m[k][j]);
}

int minimum_cycle() {
  const int n = pr.size();
  int ans = INF;
  int d[169][169];
  memcpy(d, m, sizeof(m));
  FOR(k, n) {
    FOR(i, k)
      if (m[k][i] != INF)
        FOR(j, i)
          if (i != j)
            miz(ans, m[k][i] + d[i][j] + m[j][k]);
    FOR(i, n)
      if (d[i][k] != INF)
        FOR(j, n)
          if (d[k][j] != INF)
            miz(d[i][j], d[i][k] + d[k][j]);
  }
  return ans;
}

int small_endpoint() {
  VI v;
  for(auto s: S)
    if (s < 1000)
      v.pb(M[s]);
  int ans = INF;
  FOR(i, v.size())
    FOR(j, i)
      miz(ans, 2 + m[v[j]][v[i]]);
  return ans;
}

int best_end[170];
int big_small_endpoint() {
  const int n = pr.size();
  FOR(i, n)
    best_end[i] = INF;
  VI V;
  for(auto s: S)
    if (s < 1000)
      V.pb(M[s]);
  FOR(i, n)
    for(auto v: V)
      miz(best_end[i], 1 + m[i][v]);

  int ans = INF;
  for(auto s: S)
    if (s > 1000)
      for(auto y: G[M[s]])
        miz(ans, 2 + best_end[y]);

  return ans;
}

int big_big_endpoint() {
  int ans = INF;
  static int has_bee[170];
  for(auto e: E)
    if (e.Y > 1000 && S.count(e.Y))
      has_bee[M[e.X]]++;
  const int n = pr.size();
  FOR(i, n)
    if (has_bee[i] > 1)
      miz(ans, 4);
  FOR(i, n)
      if (has_bee[i])
        FOR(j, i)
          if (has_bee[j])
            miz(ans, m[i][j] + 4);
  return ans;
}

int solve() {
  int a, b;
  FOR(i, n) {
    if (A[i] == 1) return 1;

    int t = ana(A[i], a, b);
    // printf("~%d %d %d\n", t, a, b);
    if (t == 0) return 1;
    if (t == 1) {
      if (S.find(a) != S.end())
        return 2;
      else S.insert(a);
    }
    else {
      assert(a < b && a && b);
      if (E.find(mpr(a, b)) != E.end())
        return 2;
      else E.insert(mpr(a,b));
    }
  }
  discrete();
  ggraph();
  mgraph();
  int ans = Ans;
  miz(ans, minimum_cycle());
  floyd();
  miz(ans, small_endpoint());
  miz(ans, big_small_endpoint());
  miz(ans, big_big_endpoint());

  if (ans == INF)
    return -1;
  return ans;
}

int main() {
  prime();
  R(n);
  FOR(i,n)
    R(A[i]);
  printf("%d\n", solve());
  return 0;
}

/*
4 2 2006 1003 17
3 2 2018 1009
3 2018 5045 10
5 1009 1013 3027 15 5065
5 2 2018 3027 3039 1013
3 6 2018 3027
4 2018 3027 3039 2026
4 1009 2018 3 3027 # 3
5 2018 1009 3039 1013 6
4 2018 2026 1009 1013
2 1009 2018
 */


// by david942j
// {{{
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <deque>
#include <cassert>
#include <queue>
#include <stack>
#include <cstdlib>
// #ifndef DAVID
// #include <bits/stdc++.h>
// #endif
#define openfile(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout)
#define mpr std::make_pair
#define lg(x) (31-__builtin_clz(x))
#define lgll(x) (63-__builtin_clzll(x))
#define __count __builtin_popcount
#define __countll __builtin_popcountll
#define X first
#define Y second
#define mst(x) memset(x,0,sizeof(x))
#define mst1(x) memset(x,-1,sizeof(x))
#define ALL(c) (c).begin(),(c).end()
#define FOR(i,n) for(int i=0;i<n;i++)
#define FOR1(i,n) for(int i=1;i<=n;i++)
#define FORit(it,c) for(__typeof(c.begin()) it=c.begin();it!=c.end();++it)
#define pb push_back
#define RI(x) scanf("%d",&x)
#define RID(x) int x;RI(x)

#define IOS do {ios_base::sync_with_stdio(false); cin.tie(0); }while(0)
using namespace std;
template<typename T>
void _R( T &x ) { cin>>x; }
void _R( int &x ) { scanf("%d",&x); }
#ifdef PRId64
void _R( long long &x ) { scanf("%" PRId64,&x); }
#else
void _R( long long &x) {cin >> x;}
#endif
void _R( double &x ) { scanf("%lf",&x); }
void _R( char &x ) { scanf(" %c",&x); }
void _R( char *x ) { scanf("%s",x); }

void R() {}
template<typename T, typename... U>
void R( T& head, U&... tail ) {
  _R(head);
  R(tail...);
}

template<typename T>
void _W( const T &x ) { cout<<x; }
void _W( const int &x ) { printf("%d",x); }
template<typename T>
void _W( const vector<T> &x ) {
  for ( auto i=x.cbegin(); i!=x.cend(); i++ ) {
    if ( i!=x.cbegin() ) putchar(' ');
    _W(*i);
  }
}

void W() {}
template<typename T, typename... U>
void W( const T& head, const U&... tail ) {
  _W(head);
  putchar(sizeof...(tail)?' ':'\n');
  W(tail...);
}
#ifdef DAVID
#define debug(format, ...) fprintf(stderr, format, ##__VA_ARGS__)
#else
#define debug(...)
#endif
#define caset RID(T);FOR1(cas,T)
typedef long long LL;
typedef double LD;
typedef vector<int> VI;
typedef std::pair<int,int> PII;
template<class T>inline void maz(T &a,T b){if(a<b)a=b;}
template<class T>inline void miz(T &a,T b){if(a>b)a=b;}
template<class T>inline T abs(T a){return a>0?a:-a;}
// }}}

const int N = 1e5+10;
const int INF = 1e9+7;
const int MOD = 1e9+7;
int n;
int A[N];
VI pr;

set<int> S;
set<PII> E;

void prime() {
  static bool a[1000];
  for(int i=2;i<1000;i++) {
    if (!a[i]) {
      pr.pb(i);
      for (int j=i*i;j < 1000; j+=i)
        a[j]=1;
    }
  }
  // W(pr.size());
  // W(pr);
}

int ana(int v, int &a, int &b) {
  a = b = 0;
  for (auto p: pr)
    if (v % p == 0) {
      int k = 0;
      do {
        v /= p;
        k++;
      } while (v % p == 0);
      if (k & 1) {
        if (a == 0) a = p;
        else b = p;
      }
    }
    else if (v == 1) break;

  if (v != 1) {
    if (a == 0) a = v;
    else b = v;
  }
  if (a == 0) return 0;
  if (b == 0) return 1;
  return 2;
}

map<int, int> M;
int m[169][169];
VI G[100000];
void discrete() {
  FOR(i, pr.size())
    M[pr[i]] = i;

  int cur = pr.size();
  for(auto s: S)
    if (s > 1000 && M.count(s) == 0)
      M[s] = cur++;
  for(auto e: E) {
    assert(! (e.X > 1000 && M.count(e.X) == 0));
    if (e.Y > 1000 && M.count(e.Y) == 0)
      M[e.Y] = cur++;
  }
  assert(cur < 100000);
}

void ggraph() {
  for(auto e: E)
    if (e.Y > 1000) {
      G[M[e.Y]].pb(M[e.X]);
    }
}

int Ans = INF;
void mgraph() {
  const int n = pr.size();

  FOR(i, n) {
    FOR(j, i)
      m[i][j] = m[j][i] = INF;
    m[i][i] = 0;
  }
  for(auto e: E) {
    const int &x = M[e.X], &y = M[e.Y];
    if (x < n && y < n)
      m[x][y] = m[y][x] = 1;
  }
  FOR(x, M.size())
    FOR(i, G[x].size())
      FOR(j, i) {
        miz(Ans, 2 + m[G[x][i]][G[x][j]]);
        miz(m[G[x][i]][G[x][j]], 2);
        miz(m[G[x][j]][G[x][i]], 2);
      }
}

void floyd() {
  mgraph();
  const int n = pr.size();

  FOR(k, n)
    FOR(i, n)
      FOR(j, n)
        if (m[i][k] != INF && m[k][j] != INF)
          miz(m[i][j], m[i][k] + m[k][j]);
}

int minimum_cycle() {
  mgraph();
  const int n = pr.size();
  int ans = INF;
  int d[169][169];
  memcpy(d, m, sizeof(m));
  FOR(k, n) {
    FOR(i, k)
      if (m[k][i] != INF)
        FOR(j, k)
          if (i != j)
            miz(ans, m[k][i] + d[i][j] + m[j][k]);
    FOR(i, n)
      FOR(j, n)
        if (d[i][k] != INF && d[k][j] != INF)
          miz(d[i][j], d[i][k] + d[k][j]);
  }
  return ans;
}

int small_endpoint() {
  VI v;
  for(auto s: S)
    if (s < 1000)
      v.pb(M[s]);
  int ans = INF;
  FOR(i, v.size())
    FOR(j, i)
      miz(ans, 2 + m[v[j]][v[i]]);
  return ans;
}

int best_end[170];
int big_small_endpoint() {
  const int n = pr.size();
  FOR(i, n)
    best_end[i] = INF;
  VI V;
  for(auto s: S)
    if (s < 1000)
      V.pb(M[s]);
  FOR(i, n)
    for(auto v: V)
      miz(best_end[i], 1 + m[i][v]);

  int ans = INF;
  for(auto s: S)
    if (s > 1000)
      for(auto y: G[M[s]])
        miz(ans, 2 + best_end[y]);

  return ans;
}

int big_big_endpoint() {
  int ans = INF;
  static bool has_bee[170];
  for(auto e: E)
    if (e.Y > 1000 && S.count(e.Y))
      has_bee[M[e.X]] = true;
  const int n = pr.size();
  FOR(i, n)
      if (has_bee[i])
        FOR(j, i + 1)
          if (has_bee[j])
            miz(ans, m[i][j] + 4);
  return ans;
}

int solve() {
  int a, b;
  FOR(i, n) {
    if (A[i] == 1) return 1;

    int t = ana(A[i], a, b);
    // printf("~%d %d %d\n", t, a, b);
    if (t == 0) return 1;
    if (t == 1) {
      if (S.find(a) != S.end())
        return 2;
      else S.insert(a);
    }
    else {
      if (E.find(mpr(a, b)) != E.end())
        return 2;
      else E.insert(mpr(a,b));
    }
  }
  discrete();
  ggraph();
  int ans = INF;
  miz(ans, minimum_cycle());
  floyd();
  miz(ans, small_endpoint());
  miz(ans, big_small_endpoint());
  miz(ans, big_big_endpoint());
  miz(ans, Ans);

  if (ans == INF)
    return -1;
  return ans;
}

int main() {
  prime();
  R(n);
  FOR(i,n)
    R(A[i]);
  printf("%d\n", solve());
  return 0;
}

/*
4 2 2006 1003 17
3 2 2018 1009
3 2018 5045 10
5 1009 1013 3027 15 5065
5 2 2018 3027 3039 1013
3 6 2018 3027
4 2018 3027 3039 2026
4 1009 2018 3 3027
5 2018 1009 3039 1013 6
4 2018 2026 1009 1013
 */