#include <bits/stdc++.h>
using namespace std;
const int N = 2010;
int T, n, ans, vn;
struct NODE {
  int x, y;
  bool operator==(const NODE &u) const { return (x == u.x && y == u.y); }
  bool operator<(const NODE &v) const {
    if (x != v.x) return x < v.x;
    return y < v.y;
  }
  void clear() { x = y = 0; }
  void print() { cout << x << " " << y << endl; }
} nd[N], ctr, vec[N * N];
bool out[N];
bool check(NODE u, NODE v) {
  return (1ll * u.x - ctr.x == 1ll * ctr.x - v.x &&
          1ll * u.y - ctr.y == 1ll * ctr.y - v.y);
}
int gcd(int x, int y) {
  int r;
  while (y) {
    r = x % y;
    x = y;
    y = r;
  }
  return x;
}
NODE GgG(NODE u) {
  int x = u.x;
  int y = u.y;
  if (x < 0)
    x *= -1, y *= -1;
  else if (x == 0 && y < 0)
    y *= -1;
  int d = gcd(x, y);
  x /= d;
  y /= d;
  return (NODE){x, y};
}
long long cross(NODE u, NODE v) { return 1ll * v.x * u.y - 1ll * u.x * v.y; }
bool check1(NODE u) {
  long long dis[N];
  for (int i = 1; i <= n; ++i) dis[i] = cross(nd[i], u);
  sort(dis + 1, dis + n + 1);
  for (int i = 1, sz = n / 2; i <= sz; ++i)
    if (dis[i] != -dis[n - i + 1]) return false;
  return true;
}
signed main() {
  scanf("%d", &n);
  ctr.clear();
  for (int i = 1; i <= n; ++i) {
    scanf("%d%d", &nd[i].x, &nd[i].y);
    ctr.x += nd[i].x;
    ctr.y += nd[i].y;
    nd[i].x *= n;
    nd[i].y *= n;
  }
  memset(out, 0, sizeof(out));
  for (int i = 1; i <= n; ++i)
    if (!out[i]) {
      for (int j = i + 1; j <= n; ++j) {
        bool fl = 0;
        if (!out[j] && check(nd[i], nd[j])) {
          out[i] = out[j] = 1;
          fl = 1;
        }
        if (fl) break;
      }
    }
  int rem = 0;
  for (int i = 1; i <= n; ++i)
    if (!out[i]) {
      nd[++rem] = nd[i];
      nd[rem].x -= ctr.x;
      nd[rem].y -= ctr.y;
    }
  n = rem;
  if (n <= 2) {
    printf("-1\n");
    return 0;
  }
  vn = 0;
  for (int i = 1; i <= n; ++i)
    for (int j = i + 1; j <= n; ++j)
      vec[++vn] = GgG((NODE){nd[i].x + nd[j].x, nd[i].y + nd[j].y});
  sort(vec + 1, vec + vn + 1);
  vec[++vn] = (NODE){-1, -1};
  ans = 0;
  int cnt = 1;
  for (int i = 2; i <= vn; ++i) {
    if (vec[i] == vec[i - 1])
      ++cnt;
    else {
      if (cnt >= n / 2 && check1(vec[i - 1])) ++ans;
      cnt = 1;
    }
  }
  printf("%d\n", ans);
  return 0;
}

### Prompt

Please formulate a CPP solution to the following problem:

You are given a set of n points on the plane. A line containing the origin is called good, if projection of the given set to this line forms a symmetric multiset of points. Find the total number of good lines.

Multiset is a set where equal elements are allowed.

Multiset is called symmetric, if there is a point P on the plane such that the multiset is [centrally symmetric](https://en.wikipedia.org/wiki/Point_reflection) in respect of point P.

Input

The first line contains a single integer n (1 ≤ n ≤ 2000) — the number of points in the set.

Each of the next n lines contains two integers xi and yi ( - 106 ≤ xi, yi ≤ 106) — the coordinates of the points. It is guaranteed that no two points coincide.

Output

If there are infinitely many good lines, print -1.

Otherwise, print single integer — the number of good lines.

Examples

Input

3
1 2
2 1
3 3


Output

3


Input

2
4 3
1 2


Output

-1

Note

Picture to the first sample test:

<image>

In the second sample, any line containing the origin is good.

### Response

```cpp
#include <bits/stdc++.h>
using namespace std;
const int N = 2010;
int T, n, ans, vn;
struct NODE {
  int x, y;
  bool operator==(const NODE &u) const { return (x == u.x && y == u.y); }
  bool operator<(const NODE &v) const {
    if (x != v.x) return x < v.x;
    return y < v.y;
  }
  void clear() { x = y = 0; }
  void print() { cout << x << " " << y << endl; }
} nd[N], ctr, vec[N * N];
bool out[N];
bool check(NODE u, NODE v) {
  return (1ll * u.x - ctr.x == 1ll * ctr.x - v.x &&
          1ll * u.y - ctr.y == 1ll * ctr.y - v.y);
}
int gcd(int x, int y) {
  int r;
  while (y) {
    r = x % y;
    x = y;
    y = r;
  }
  return x;
}
NODE GgG(NODE u) {
  int x = u.x;
  int y = u.y;
  if (x < 0)
    x *= -1, y *= -1;
  else if (x == 0 && y < 0)
    y *= -1;
  int d = gcd(x, y);
  x /= d;
  y /= d;
  return (NODE){x, y};
}
long long cross(NODE u, NODE v) { return 1ll * v.x * u.y - 1ll * u.x * v.y; }
bool check1(NODE u) {
  long long dis[N];
  for (int i = 1; i <= n; ++i) dis[i] = cross(nd[i], u);
  sort(dis + 1, dis + n + 1);
  for (int i = 1, sz = n / 2; i <= sz; ++i)
    if (dis[i] != -dis[n - i + 1]) return false;
  return true;
}
signed main() {
  scanf("%d", &n);
  ctr.clear();
  for (int i = 1; i <= n; ++i) {
    scanf("%d%d", &nd[i].x, &nd[i].y);
    ctr.x += nd[i].x;
    ctr.y += nd[i].y;
    nd[i].x *= n;
    nd[i].y *= n;
  }
  memset(out, 0, sizeof(out));
  for (int i = 1; i <= n; ++i)
    if (!out[i]) {
      for (int j = i + 1; j <= n; ++j) {
        bool fl = 0;
        if (!out[j] && check(nd[i], nd[j])) {
          out[i] = out[j] = 1;
          fl = 1;
        }
        if (fl) break;
      }
    }
  int rem = 0;
  for (int i = 1; i <= n; ++i)
    if (!out[i]) {
      nd[++rem] = nd[i];
      nd[rem].x -= ctr.x;
      nd[rem].y -= ctr.y;
    }
  n = rem;
  if (n <= 2) {
    printf("-1\n");
    return 0;
  }
  vn = 0;
  for (int i = 1; i <= n; ++i)
    for (int j = i + 1; j <= n; ++j)
      vec[++vn] = GgG((NODE){nd[i].x + nd[j].x, nd[i].y + nd[j].y});
  sort(vec + 1, vec + vn + 1);
  vec[++vn] = (NODE){-1, -1};
  ans = 0;
  int cnt = 1;
  for (int i = 2; i <= vn; ++i) {
    if (vec[i] == vec[i - 1])
      ++cnt;
    else {
      if (cnt >= n / 2 && check1(vec[i - 1])) ++ans;
      cnt = 1;
    }
  }
  printf("%d\n", ans);
  return 0;
}

```