#include <bits/stdc++.h>
using namespace std;
const long long MOD = 998244353;
const int INF = 0x3f3f3f3f;
long long qpow(long long x, long long n) {
  long long res = 1;
  while (n) {
    if (n & 1) res = res * x % MOD;
    x = x * x % MOD;
    n >>= 1;
  }
  return res;
}
long long fac[200005];
long long ifac[200005];
long long C(long long n, long long m) {
  if (n < 0 || m < 0 || m > n) return 0;
  return fac[n] * ifac[n - m] % MOD * fac[m] % MOD;
}
void init_C(int n) {
  fac[0] = 1;
  for (int i = 1; i <= n; ++i) fac[i] = fac[i - 1] * i % MOD;
  ifac[n] = qpow(fac[n], MOD - 2);
  for (int i = n - 1; i >= 0; --i) ifac[i] = ifac[i + 1] * (i + 1) % MOD;
}
int n;
int a[200005];
int cnt[200005];
struct SegmentTree {
  int mx[200005 << 2];
  int mi[200005 << 2];
  int lz[200005 << 2];
  void PushUp(int o) {
    mx[o] = max(mx[(o << 1)], mx[(o << 1 | 1)]);
    mi[o] = min(mi[(o << 1)], mi[(o << 1 | 1)]);
  }
  void PushDown(int o, int l, int r) {
    if (lz[o]) {
      mx[(o << 1)] += lz[o];
      mx[(o << 1 | 1)] += lz[o];
      mi[(o << 1)] += lz[o];
      mi[(o << 1 | 1)] += lz[o];
      lz[(o << 1)] += lz[o];
      lz[(o << 1 | 1)] += lz[o];
      lz[o] = 0;
    }
  }
  void Update(int o, int l, int r, int ql, int qr, int v) {
    if (ql <= l && r <= qr) {
      mx[o] += v;
      mi[o] += v;
      lz[o] += v;
      return;
    }
    PushDown(o, l, r);
    int m = (l + r) >> 1;
    if (ql <= m) Update((o << 1), l, m, ql, qr, v);
    if (qr >= m + 1) Update((o << 1 | 1), m + 1, r, ql, qr, v);
    PushUp(o);
  }
  int QueryValue(int o, int l, int r, int p) {
    if (l == r) return mx[o];
    PushDown(o, l, r);
    int m = (l + r) >> 1;
    if (p <= m) return QueryValue((o << 1), l, m, p);
    return QueryValue((o << 1 | 1), m + 1, r, p);
  }
  int QueryFirst(int o, int l, int r, int value) {
    if (value == 0) return 0;
    if (l == r) return l;
    PushDown(o, l, r);
    int m = (l + r) >> 1;
    if (mi[(o << 1)] <= value && value <= mx[(o << 1)])
      return QueryFirst((o << 1), l, m, value);
    return QueryFirst((o << 1 | 1), m + 1, r, value);
  }
  int QueryLast(int o, int l, int r, int value) {
    if (l == r) return l;
    PushDown(o, l, r);
    int m = (l + r) >> 1;
    if (mi[(o << 1 | 1)] <= value && value <= mx[(o << 1 | 1)])
      return QueryLast((o << 1 | 1), m + 1, r, value);
    return QueryLast((o << 1), l, m, value);
  }
} st;
int ans;
vector<int> oc[200005];
int helphelp(int pos) {
  int tmp = ans;
  int Value = st.QueryValue(1, 0, n, pos);
  int LastPos = st.QueryLast(1, 0, n, Value);
  int FirstPos = st.QueryFirst(1, 0, n, Value);
  tmp = max(tmp, LastPos - FirstPos);
  return tmp;
}
int tmpidy[700005], top;
int help(int x, int y) {
  for (int idy : oc[y]) st.Update(1, 0, n, idy, n, -1);
  int tmp = ans;
  top = 0;
  for (int idy : oc[y]) {
    tmpidy[++top] = idy - 1;
    tmpidy[++top] = idy;
    if (idy + 1 <= n) tmpidy[++top] = idy + 1;
  }
  sort(tmpidy + 1, tmpidy + 1 + top);
  top = unique(tmpidy + 1, tmpidy + 1 + top) - (tmpidy + 1);
  for (int i = 1; i <= top; ++i) tmp = max(tmp, helphelp(tmpidy[i]));
  for (int idy : oc[y]) st.Update(1, 0, n, idy, n, 1);
  return tmp;
}
void solve() {
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &a[i]);
    oc[a[i]].push_back(i);
    ++cnt[a[i]];
  }
  int x = max_element(cnt + 1, cnt + 1 + 200000) - cnt;
  for (int idx : oc[x]) st.Update(1, 0, n, idx, n, 1);
  ans = 0;
  for (int y = 1; y <= 200000; ++y) {
    if (y == x) continue;
    if (cnt[y] == 0) continue;
    ans = max(ans, help(x, y));
  }
  printf("%d\n", ans);
  return;
}
int main() {
  int T = 1;
  for (int ti = 1; ti <= T; ++ti) {
    solve();
  }
  return 0;
}
