#include <bits/stdc++.h>
using namespace std;
vector<int> vec;
void dijkstra(vector<vector<pair<int, int> > > v, int sursa) {
  for (int i = 0; i <= 4; i++) {
    vec.push_back(10000);
  }
  vec[sursa] = 0;
  queue<int> q;
  q.push(sursa);
  while (!q.empty()) {
    int x;
    x = q.front();
    q.pop();
    for (int i = 0; i < v[x].size(); i++) {
      q.push(v[x][i].first);
      int alt;
      alt = vec[x] + v[x][i].second;
      if (alt < vec[v[x][i].first]) {
        vec[v[x][i].first] = alt;
      }
    }
  }
}
struct str {
  int x, y, z;
};
struct ecuatie {
  int a, b, c, d;
};
bool ecuatia_plan(ecuatie ec, str a1, str a2) {
  if (((ec.a * a1.x + ec.b * a1.y + ec.c * a1.z + ec.d) > 0 &&
       (ec.a * a2.x + ec.b * a2.y + ec.c * a2.z + ec.d) < 0) ||
      ((ec.a * a1.x + ec.b * a1.y + ec.c * a1.z + ec.d) < 0 &&
       (ec.a * a2.x + ec.b * a2.y + ec.c * a2.z + ec.d) > 0))
    return true;
  return false;
}
bool onsegmentxy(str p, str q, str r) {
  if (q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) && q.y <= max(p.y, r.y) &&
      q.y >= min(p.y, r.y))
    return true;
  return false;
}
float orientationxy(str p, str q, str r) {
  int val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
  if (val == 0) return 0;
  return (val > 0) ? 1 : 2;
}
bool dointersectxy(str p1, str q1, str p2, str q2) {
  int o1 = orientationxy(p1, q1, p2);
  int o2 = orientationxy(p1, q1, q2);
  int o3 = orientationxy(p2, q2, p1);
  int o4 = orientationxy(p2, q2, q1);
  if (o1 != o2 && o3 != o4) return true;
  if (o1 == 0 && onsegmentxy(p1, p2, q1)) return true;
  if (o2 == 0 && onsegmentxy(p1, q2, q1)) return true;
  if (o3 == 0 && onsegmentxy(p2, p1, q2)) return true;
  if (o4 == 0 && onsegmentxy(p2, q1, q2)) return true;
  return false;
}
bool insidexy(vector<str> v, str p) {
  if (v.size() < 3) {
    return false;
  }
  str extrem = {1000001, p.y, 0};
  int count = 0, i = 0;
  int n = v.size();
  do {
    int next = (i + 1) % n;
    if (dointersectxy(v[i], v[next], p, extrem)) {
      if (orientationxy(v[i], p, v[next]) == 0) {
        return onsegmentxy(v[i], p, v[next]);
      }
      count++;
    }
    i = next;
  } while (i != 0);
  if (count % 2 == 1) {
    return true;
  }
  return false;
}
bool onsegmentxz(str p, str q, str r) {
  if (q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) && q.z <= max(p.z, r.z) &&
      q.z >= min(p.z, r.z))
    return true;
  return false;
}
float orientationxz(str p, str q, str r) {
  int val = (q.z - p.z) * (r.x - q.x) - (q.x - p.x) * (r.z - q.z);
  if (val == 0) return 0;
  return (val > 0) ? 1 : 2;
}
bool dointersectxz(str p1, str q1, str p2, str q2) {
  int o1 = orientationxz(p1, q1, p2);
  int o2 = orientationxz(p1, q1, q2);
  int o3 = orientationxz(p2, q2, p1);
  int o4 = orientationxz(p2, q2, q1);
  if (o1 != o2 && o3 != o4) return true;
  if (o1 == 0 && onsegmentxz(p1, p2, q1)) return true;
  if (o2 == 0 && onsegmentxz(p1, q2, q1)) return true;
  if (o3 == 0 && onsegmentxz(p2, p1, q2)) return true;
  if (o4 == 0 && onsegmentxz(p2, q1, q2)) return true;
  return false;
}
bool insidexz(vector<str> v, str p) {
  if (v.size() < 3) {
    return false;
  }
  str extrem = {1000001, 0, p.z};
  int count = 0, i = 0;
  int n = v.size();
  do {
    int next = (i + 1) % n;
    if (dointersectxy(v[i], v[next], p, extrem)) {
      if (orientationxy(v[i], p, v[next]) == 0) {
        return onsegmentxy(v[i], p, v[next]);
      }
      count++;
    }
    i = next;
  } while (i != 0);
  return count & 1;
}
bool onsegmentyz(str p, str q, str r) {
  if (q.y <= max(p.y, r.y) && q.y >= min(p.y, r.y) && q.z <= max(p.z, r.z) &&
      q.z >= min(p.z, r.z))
    return true;
  return false;
}
float orientationyz(str p, str q, str r) {
  int val = (q.y - p.y) * (r.z - q.z) - (q.z - p.z) * (r.y - q.y);
  if (val == 0) return 0;
  return (val > 0) ? 1 : 2;
}
bool dointersectyz(str p1, str q1, str p2, str q2) {
  int o1 = orientationyz(p1, q1, p2);
  int o2 = orientationyz(p1, q1, q2);
  int o3 = orientationyz(p2, q2, p1);
  int o4 = orientationyz(p2, q2, q1);
  if (o1 != o2 && o3 != o4) return true;
  if (o1 == 0 && onsegmentyz(p1, p2, q1)) return true;
  if (o2 == 0 && onsegmentyz(p1, q2, q1)) return true;
  if (o3 == 0 && onsegmentyz(p2, p1, q2)) return true;
  if (o4 == 0 && onsegmentyz(p2, q1, q2)) return true;
  return false;
}
bool insideyz(vector<str> v, str p) {
  if (v.size() < 3) {
    return false;
  }
  str extrem = {p.x, 1000001, p.z};
  int count = 0, i = 0;
  int n = v.size();
  do {
    int next = (i + 1) % n;
    if (dointersectyz(v[i], v[next], p, extrem)) {
      if (orientationyz(v[i], p, v[next]) == 0) {
        return onsegmentyz(v[i], p, v[next]);
      }
      count++;
    }
    i = next;
  } while (i != 0);
  return count & 1;
}
int main() {
  int n, m;
  cin >> n;
  vector<int> v;
  for (int i = 0; i < n; i++) {
    int x;
    cin >> x;
    v.push_back(x);
  }
  vector<int> vec(2 * 1e5 + 1, 0);
  for (int i = 0; i < n - 1; i++) {
    for (int j = i + 1; j < n; j++) {
      vec[v[i] + v[j]] += 1;
    }
  }
  int maxx = 0;
  for (int i = 0; i <= 2 * 1e5; i++) {
    if (vec[i] > maxx) {
      maxx = vec[i];
    }
  }
  cout << maxx;
}
