100
92 53 86 41 77 68 80 54 17 96 89 53 64 55 2 80 28 58 77 43 70 91 71 71 78 3 25 2 15 47 60 70 95 19 47 58 57 47 91 2 23 80 86 98 98 98 57 98 98 25 98 98 57 98 98 98 98 98 25 98 98 98 98 98 57 98 98 25 98 98 57 98 98 57 98 98 25 98 98 34 98 98 34 98 98 25 98 98 24 98 98 25 89 34 76 71 91 92 22 13
 20
9 2 12 10 2 9 13 14 11 16 9 1 9 13 5 11 12 19 20 1
 100
77 95 91 95 77 54 91 77 77 42 63 48 97 85 54 63 42 70 42 97 75 77 93 64 56 88 91 85 85 64 64 88 54 70 6 3 20 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 18 48 85 75 97 20 54 64 20 85 56 77 75 42
 20
15 12 19 6 5 11 2 5 18 3 17 15 17 7 9 18 19 17 18 15
 100
92 42 58 62 24 59 62 100 92 62 54 100 62 82 91 62 100 100 62 100 100 62 92 92 92 62 92 92 62 92 62 92 88 100 100 36 62 92 16 92 62 100 62 92 35 62 100 92 92 62 93 100 100 62 76 100 62 62 92 62 92 50 100 8 7 62 100 18 92 62 92 92 100 62 32 92 92 62 37 76 100 39 62 92 62 41 62 62 19 57 100 37 92 99 100 47 62 92 62 62
 100
44 80 26 88 24 37 4 96 23 25 5 5 7 41 54 35 25 57 88 91 20 78 98 64 57 60 86 91 67 63 32 100 91 34 26 41 34 98 5 80 3 57 57 25 42 98 25 88 5 5 24 67 98 34 47 84 62 31 71 91 98 57 35 57 24 34 13 79 2 73 38 57 73 5 98 100 4 23 42 7 25 34 18 91 25 26 53 32 57 25 91 8 4 16 23 91 34 53 42 98
 100
6 20 18 88 48 85 77 70 93 90 91 54 97 75 3 56 63 95 64 42 76 19 52 45 83 96 7 60 71 58 34 2 98 66 69 43 67 46 89 13 81 1 59 8 10 26 14 86 99 4 41 32 92 5 84 65 62 50 36 74 16 73 35 27 9 38 72 23 15 17 30 33 11 53 24 82 79 57 49 21 68 22 39 47 25 61 51 31 6 37 78 94 44 100 29 87 12 55 80 40
 20
13 16 6 13 19 7 18 5 17 8 11 13 19 11 19 18 18 13 14 1
 20
2 3 5 4 3 2 1 2 2 2 2 3 2 5 2 1 1 4 5 3
 100
53 53 53 53 53 53 53 53 53 53 53 53 53 53 53 53 53 53 53 53 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 28 28 28 28 28 28 28 28 28 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 57 57 57 57 57 57 57 57 57 57 57 57 57 96 57 94 94 94 94 94 94 94 94 94 94 94 22 22 22 22 22 22 22 22 22 22 22 22 22 22
 100
94 77 52 53 56 88 23 46 33 28 11 96 68 84 4 91 57 20 98 75 89 83 22 67 80 16 54 41 27 34 62 69 5 50 32 42 45 55 36 59 60 18 37 63 90 1 64 7 81 29 39 93 82 48 43 61 17 66 8 79 2 26 6 44 31 86 40 73 3 65 12 78 74 25 87 95 24 92 13 58 85 76 100 70 38 71 10 19 97 14 47 72 99 35 9 21 51 49 30 15

47
 14
 41
 20
 79
 82
 99
 19
 9
 96
 100

//#pragma GCC optimize("Ofast,unroll-loops")
//#pragma GCC target("avx,avx2,sse,sse2")
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <bits/stdc++.h>
using namespace std;
using namespace __gnu_pbds;
template <class T> using Tree = tree<T, null_type, less<T>,
    rb_tree_tag, tree_order_statistics_node_update>;
 
using ll = long long;
using db = long double; // or double, if TL is tight
using str = string; // yay python!

using pi = pair<int,int>;
using pl = pair<ll,ll>;
using pd = pair<db,db>;

using vi = vector<int>;
using vb = vector<bool>;
using vl = vector<ll>;
using vd = vector<db>; 
using vs = vector<str>;
using vpi = vector<pi>;
using vpl = vector<pl>; 
using vpd = vector<pd>;

#define tcT template<class T
#define tcTU tcT, class U
// ^ lol this makes everything look weird but I'll try it
tcT> using V = vector<T>; 
tcT, size_t SZ> using AR = array<T,SZ>; 
tcT> using PR = pair<T,T>;

// pairs
#define mp make_pair
#define f first
#define s second

// vectors
// oops size(x), rbegin(x), rend(x) need C++17
#define sz(x) int((x).size())
#define bg(x) begin(x)
#define all(x) bg(x), end(x)
#define rall(x) x.rbegin(), x.rend() 
#define sor(x) sort(all(x)) 
#define rsz resize
#define ins insert 
#define ft front()
#define bk back()
#define pb push_back
#define eb emplace_back 
#define pf push_front
#define rtn return

#define lb lower_bound
#define ub upper_bound 
tcT> int lwb(V<T>& a, const T& b) { return int(lb(all(a),b)-bg(a)); }

// loops
#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define ROF(i,a,b) for (int i = (b)-1; i >= (a); --i)
#define R0F(i,a) ROF(i,0,a)
#define each(a,x) for (auto& a: x)

const int MOD = 998244353; // 1e9+7; // 998244353;
const int MX = 2e5+5;
const ll INF = 1e18; // not too close to LLONG_MAX
const int IINF = 1e9;
const db PI = acos((db)-1);
const int dx[4] = {1,0,-1,0}, dy[4] = {0,1,0,-1}; // for every grid problem!!
mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count()); 
template<class T> using pqg = priority_queue<T,vector<T>,greater<T>>;

// bitwise ops
// also see https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
constexpr int pct(int x) { return __builtin_popcount(x); } // # of bits set
constexpr int bits(int x) { // assert(x >= 0); // make C++11 compatible until USACO updates ...
	return x == 0 ? 0 : 31-__builtin_clz(x); } // floor(log2(x)) 
constexpr int p2(int x) { return 1<<x; }
constexpr int msk2(int x) { return p2(x)-1; }

ll cdiv(ll a, ll b) { return a/b+((a^b)>0&&a%b); } // divide a by b rounded up
ll fdiv(ll a, ll b) { return a/b-((a^b)<0&&a%b); } // divide a by b rounded down

tcT> bool ckmin(T& a, const T& b) {
	return b < a ? a = b, 1 : 0; } // set a = min(a,b)
tcT> bool ckmax(T& a, const T& b) {
	return a < b ? a = b, 1 : 0; }

tcTU> T fstTrue(T lo, T hi, U f) {
	hi ++; assert(lo <= hi); // assuming f is increasing
	while (lo < hi) { // find first index such that f is true 
		T mid = lo+(hi-lo)/2;
		f(mid) ? hi = mid : lo = mid+1; 
	} 
	return lo;
}
tcTU> T lstTrue(T lo, T hi, U f) {
	lo --; assert(lo <= hi); // assuming f is decreasing
	while (lo < hi) { // find first index such that f is true 
		T mid = lo+(hi-lo+1)/2;
		f(mid) ? lo = mid : hi = mid-1;
	} 
	return lo;
}
tcT> void remDup(vector<T>& v) { // sort and remove duplicates
	sort(all(v)); v.erase(unique(all(v)),end(v)); }
tcTU> void erase(T& t, const U& u) { // don't erase
	auto it = t.find(u); assert(it != end(t));
	t.erase(it); } // element that doesn't exist from (multi)set

// INPUT
#define tcTUU tcT, class ...U
tcT> void re(complex<T>& c);
tcTU> void re(pair<T,U>& p);
tcT> void re(V<T>& v);
tcT, size_t SZ> void re(AR<T,SZ>& a);

tcT> void re(T& x) { cin >> x; }
void re(double& d) { str t; re(t); d = stod(t); }
void re(long double& d) { str t; re(t); d = stold(t); }
tcTUU> void re(T& t, U&... u) { re(t); re(u...); }

tcT> void re(complex<T>& c) { T a,b; re(a,b); c = {a,b}; }
tcTU> void re(pair<T,U>& p) { re(p.f,p.s); }
tcT> void re(V<T>& x) { each(a,x) re(a); }
tcT, size_t SZ> void re(AR<T,SZ>& x) { each(a,x) re(a); }
tcT> void rv(int n, V<T>& x) { x.rsz(n); re(x); }

// TO_STRING
#define ts to_string
str ts(char c) { return str(1,c); }
str ts(const char* s) { return (str)s; }
str ts(str s) { return s; }
str ts(bool b) { 
	// #ifdef LOCAL
	// 	return b ? "true" : "false"; 
	// #else 
	return ts((int)b);
	// #endif
}
tcT> str ts(complex<T> c) { 
	stringstream ss; ss << c; return ss.str(); }
str ts(V<bool> v) {
	str res = "{"; F0R(i,sz(v)) res += char('0'+v[i]);
	res += "}"; return res; }
template<size_t SZ> str ts(bitset<SZ> b) {
	str res = ""; F0R(i,SZ) res += char('0'+b[i]);
	return res; }
tcTU> str ts(pair<T,U> p);
tcT> str ts(T v) { // containers with begin(), end()
	#ifdef LOCAL
		bool fst = 1; str res = "{";
		for (const auto& x: v) {
			if (!fst) res += ", ";
			fst = 0; res += ts(x);
		}
		res += "}"; return res;
	#else
		bool fst = 1; str res = "";
		for (const auto& x: v) {
			if (!fst) res += " ";
			fst = 0; res += ts(x);
		}
		return res;

	#endif
}
tcTU> str ts(pair<T,U> p) {
	#ifdef LOCAL
		return "("+ts(p.f)+", "+ts(p.s)+")"; 
	#else
		return ts(p.f)+" "+ts(p.s);
	#endif
}

// OUTPUT
tcT> void pr(T x) { cout << ts(x); }
tcTUU> void pr(const T& t, const U&... u) { 
	pr(t); pr(u...); }
void ps() { pr("\n"); } // print w/ spaces
tcTUU> void ps(const T& t, const U&... u) { 
	pr(t); if (sizeof...(u)) pr(" "); ps(u...); }

// DEBUG
void DBG() { cerr << "]" << endl; }
tcTUU> void DBG(const T& t, const U&... u) {
	cerr << ts(t); if (sizeof...(u)) cerr << ", ";
	DBG(u...); }
#ifdef LOCAL // compile with -DLOCAL, chk -> fake assert
	#define dbg(...) cerr << "Line(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "]: [", DBG(__VA_ARGS__)
	#define chk(...) if (!(__VA_ARGS__)) cerr << "Line(" << __LINE__ << ") -> function(" \
		 << __FUNCTION__  << ") -> CHK FAILED: (" << #__VA_ARGS__ << ")" << "\n", exit(0);
#else
	#define dbg(...) 0
	#define chk(...) 0
#endif

void setPrec() { cout << fixed << setprecision(15); }
void unsyncIO() { cin.tie(0)->sync_with_stdio(0); }
// FILE I/O
void setIn(str s) { freopen(s.c_str(),"r",stdin); }
void setOut(str s) { freopen(s.c_str(),"w",stdout); }
void setIO(str s = "") {
	unsyncIO(); setPrec();
	// cin.exceptions(cin.failbit); 
	// throws exception when do smth illegal
	// ex. try to read letter into int
	if (sz(s)) setIn(s+".in"), setOut(s+".out"); // for USACO
}

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

vector<vi> oc;
int ans = 0;
int SZ = 0;
int n;
vi A;
set<int> pos;

void solve(int D, int cur){
	if(sz(oc[cur]) > SZ){
		vi arr(n + 1);
		F0R(a, n)
			if(A[a] == cur)
				arr[a + 1] = arr[a] + 1; 
			else if(A[a] == D)
				arr[a + 1] = arr[a] - 1;
			else
				arr[a + 1] = arr[a];
		unordered_map<int, int, custom_hash> fst;
		F0R(a, n + 1)
			if(fst.count(arr[a]) == 0)
				fst[arr[a]] = a;
			else
				ckmax(ans, a - fst[arr[a]]);
		return;
	}
	deque<pi> g;
	F0R(a, sz(oc[cur])){
		auto temp = pos.lb(oc[cur][a]);
		auto stor = temp;
		F0R(i, sz(oc[cur]) + 1)
			if(temp != pos.begin())
				temp--;
		while(temp != stor){
			if(sz(g) == 0 || *temp > g.back().f)
				g.pb(mp(*temp, -1));
			temp++;
		}
		g.pb(mp(oc[cur][a], 1));
		temp = pos.lb(oc[cur][a]);
		F0R(i, sz(oc[cur]) + 1){
			if(temp == pos.end())
				break;
			if(a + 1 != sz(oc[cur]) - 1 && oc[cur][a + 1] <= *temp)
				break;
			g.pb(mp(*temp, -1));
			temp++;
		}
	}
	int m = sz(g);
	vi pre(m);
	pre[0] = g[0].s;
	F0R(a, m - 1)
		pre[a + 1] = pre[a] + g[a + 1].s;
	unordered_map<int, int, custom_hash> fst;
	F0R(a, m){
		if(fst.count(pre[a]) != 0)
			ckmax(ans, (a + 1 == sz(g) ? n : g[a + 1].f) - (fst[pre[a]] - 1 == -1 ? -1 : g[fst[pre[a]] - 1].f) - 1);
		if(fst.count(pre[a] - g[a].s) == 0)
			fst[pre[a] - g[a].s] = a;
	}
}

int main() {
	setIO();
	cin >> n;
	SZ = sqrt(n);
	A.rsz(n);
	re(A);
	each(a, A)
		a--;
	oc.rsz(n);
	F0R(a, n)
		oc[A[a]].pb(a);
	int num = 0;
	vi idx;
	F0R(a, n)
		if(ckmax(num, sz(oc[a])))
			idx.clear(), idx.pb(a);
		else if(num == sz(oc[a]))
			idx.pb(a);
	if(sz(idx) > 1){
		cout << num << endl;
		return 0;
	}
	int D = idx[0];
	each(a, oc[D])
		pos.insert(a);
	F0R(a, n)
		if(a != D && sz(oc[a]) > 0)
			solve(D, a);
	cout << ans << endl;
	// you should actually read the stuff at the bottom
}

/* stuff you should look for
	* int overflow, array bounds
	* special cases (n=1?)
	* do smth instead of nothing and stay organized
	* WRITE STUFF DOWN
	* DON'T GET STUCK ON ONE APPROACH
*/
