#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:46777216")
using namespace std;
struct intervalTree {
  int n;
  long long *t;
  void init(int m) {
    n = m;
    t = new long long[4 * n];
  }
  void build(long long a[], int v, int tl, int tr);
  long long elem_query(int pos, int v, int tl, int tr);
  long long sum_query(int l, int r, int v, int tl, int tr);
  void update(int l, int r, long long new_val, int v, int tl, int tr);
};
void intervalTree::build(long long a[], int v = 1, int tl = 0, int tr = -1) {
  if (tr == -1) tr = n - 1;
  if (tl == tr)
    t[v] = a[tl];
  else {
    int tm = (tl + tr) / 2;
    build(a, v * 2, tl, tm);
    build(a, v * 2 + 1, tm + 1, tr);
    t[v] = t[v * 2] + t[v * 2 + 1];
  }
}
long long intervalTree::elem_query(int pos, int v = 1, int tl = 0,
                                   int tr = -1) {
  if (tr == -1) tr = n - 1;
  if (tl == tr) return t[v];
  int tm = (tl + tr) / 2;
  if (pos <= tm)
    return t[v] + elem_query(pos, v * 2, tl, tm);
  else
    return t[v] + elem_query(pos, v * 2 + 1, tm + 1, tr);
}
long long intervalTree::sum_query(int l, int r, int v = 1, int tl = 0,
                                  int tr = -1) {
  if (tr == -1) tr = n - 1;
  if (l > r) return 0;
  if (l == tl && r == tr) return t[v];
  int tm = (tl + tr) / 2;
  return sum_query(l, min(r, tm), v * 2, tl, tm) +
         sum_query(max(l, tm + 1), r, v * 2 + 1, tm + 1, tr);
}
void intervalTree::update(int l, int r, long long add, int v = 1, int tl = 0,
                          int tr = -1) {
  if (tr == -1) tr = n - 1;
  if (tl == tr)
    t[v] += add;
  else {
    int tm = (tl + tr) / 2;
    if (r <= tm)
      update(l, r, add, v * 2, tl, tm);
    else if (l > tm)
      update(l, r, add, v * 2 + 1, tm + 1, tr);
    else {
      update(l, tm, add, v * 2, tl, tm);
      update(tm + 1, r, add, v * 2 + 1, tm + 1, tr);
    }
    t[v] = t[v * 2] + t[v * 2 + 1];
  }
}
vector<int> poses[4000];
int process_vectors(int a, int b) {
  int it_a = 0, it_b = 0;
  bool cur_vector = 0;
  if (poses[b][0] < poses[a][0]) cur_vector = 1;
  int count = 1;
  while (it_a != poses[a].size() && it_b != poses[b].size()) {
    if (cur_vector == 0) {
      if (poses[b][it_b] > poses[a][it_a]) {
        count++;
        cur_vector = 1;
        continue;
      }
      it_b++;
    } else {
      if (poses[b][it_b] < poses[a][it_a]) {
        count++;
        cur_vector = 0;
        continue;
      }
      it_a++;
    }
  }
  return count;
}
int main() {
  int N;
  cin >> N;
  if (N == 1) {
    cout << 1;
    return 0;
  }
  int A[4000];
  int id[1000001];
  for (int i = 0; i < 1000001; i++) id[i] = -1;
  int K = 0;
  for (int i = 0; i < N; i++) {
    scanf("%d", &A[i]);
    if (id[A[i]] == -1) id[A[i]] = K++;
    poses[id[A[i]]].push_back(i);
  }
  int ans = 0;
  for (int i = 0; i < K; i++)
    for (int j = i; j < K; j++) {
      int cnt = process_vectors(i, j);
      if (cnt > ans) ans = cnt;
    }
  cout << ans;
  return 0;
}
