#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;
using cd = complex<ld>;
int brute(vector<int> const &a, int x, int y) {
  unordered_map<int, int> pref;
  int sum = 0;
  int pos = 0;
  int len = 0;
  pref[0] = -1;
  for (int b : a) {
    if (b == x) {
      sum--;
    } else if (b == y) {
      sum++;
    }
    if (!pref.count(sum)) {
      pref[sum] = pos;
    }
    len = max(len, pos - pref[sum]);
    pos++;
  }
  return len;
}
bool inside(pii const &seg, int x) { return seg.first <= x && x <= seg.second; }
pii intersect(pii const &a, pii const &b) {
  return pii(max(a.first, b.first), min(a.second, b.second));
}
int length(pii const &a) { return max(0, a.second - a.first + 1); }
int smart(vector<int> const &posA, vector<int> const &posB, int n) {
  int len = 0;
  for (int i = 0; i < (int)posB.size(); i++) {
    for (int j = 0; j <= i; j++) {
      int left = lower_bound(posA.begin(), posA.end(), posB[j]) - posA.begin();
      int right = lower_bound(posA.begin(), posA.end(), posB[i]) - posA.begin();
      --right;
      int segment = i - j + 1 - max(0, right - left + 1);
      if (segment < 0) {
        continue;
      }
      pii bSeg;
      if (j == 0) {
        bSeg.first = 0;
      } else {
        bSeg.first = posB[j - 1] + 1;
      }
      if (i + 1 == (int)posB.size()) {
        bSeg.second = n - 1;
      } else {
        bSeg.second = posB[i + 1] - 1;
      }
      {
        int tl = left, tr = right;
        int ts = segment;
        int shift = min((int)posA.size() - tr - 1, ts);
        tr += shift;
        ts -= shift;
        shift = min(tl, ts);
        tl -= shift;
        ts -= shift;
        pii aSeg;
        if (ts == 0 && inside(bSeg, posA[tl]) && inside(bSeg, posA[tr])) {
          if (tl == 0) {
            aSeg.first = 0;
          } else {
            aSeg.first = posA[tl - 1] + 1;
          }
          if (tr + 1 == (int)posA.size()) {
            aSeg.second = n - 1;
          } else {
            aSeg.second = posA[tr + 1] - 1;
          }
          len = max(len, length(intersect(aSeg, bSeg)));
        }
      }
      {
        int tl = left, tr = right;
        int ts = segment;
        int shift = min(tl, ts);
        tl -= shift;
        ts -= shift;
        shift = min((int)posA.size() - tr - 1, ts);
        tr += shift;
        ts -= shift;
        pii aSeg;
        if (ts == 0 && inside(bSeg, posA[tl]) && inside(bSeg, posA[tr])) {
          if (tl == 0) {
            aSeg.first = 0;
          } else {
            aSeg.first = posA[tl - 1] + 1;
          }
          if (tr + 1 == (int)posA.size()) {
            aSeg.second = n - 1;
          } else {
            aSeg.second = posA[tr + 1] - 1;
          }
          len = max(len, length(intersect(aSeg, bSeg)));
        }
      }
    }
  }
  return len;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  int n;
  cin >> n;
  map<int, int> freq;
  vector<int> a(n);
  vector<vector<int>> occur(n + 1);
  {
    int pos = 0;
    for (int &x : a) {
      cin >> x;
      freq[x]++;
      occur[x].push_back(pos++);
    }
  }
  int mx = 0;
  for (auto [x, y] : freq) {
    if (y > freq[mx]) {
      mx = x;
    }
  }
  const int K = (int)round(sqrt(n)) * 2;
  int res = 0;
  for (int i = 1; i <= n; i++) {
    if (mx == i) {
      continue;
    }
    if (freq[i] >= K) {
      res = max(res, brute(a, mx, i));
    } else {
      res = max(res, smart(occur[mx], occur[i], n));
    }
  }
  cout << res;
  return 0;
}
