#include <bits/stdc++.h>
using namespace std;
const int maxn = 2010;
const double eps = 1e-4;
const long long M1 = 998244353;
const long long M2 = 1000000007;
const long long M = 1333331;
struct Hash_data {
  int vX, vY, id;
} Hash[M];
struct data {
  double X, Y;
} point[maxn];
data mid;
double len[maxn];
bool vis[maxn];
data temp[maxn];
int n;
void Push(long long x, long long y, int Id) {
  long long v = ((x * M1 + y * M2) % M + M) % M;
  while (Hash[v].vX != M1) v = (v + 1) % M;
  Hash[v].vX = x;
  Hash[v].vY = y;
  Hash[v].id = Id;
}
double Abs(double x) {
  if (x > 0.0) return x;
  return -x;
}
Hash_data Judge(double x, double y) {
  Hash_data z;
  z.vX = M1;
  double valX = floor(x + eps), valY = floor(y + eps);
  if (Abs(valX - x) > eps || Abs(valY - y) > eps) return z;
  z.vX = (int)floor(valX + eps);
  z.vY = (int)floor(valY + eps);
  return z;
}
bool Check(long long x, long long y) {
  long long v = ((x * M1 + y * M2) % M + M) % M;
  while (Hash[v].vX != M1 && (Hash[v].vX != x || Hash[v].vY != y))
    v = (v + 1) % M;
  if (Hash[v].vX == M1) return false;
  Hash[v].vX = M2;
  vis[Hash[v].id] = true;
  return true;
}
double CJ(data x, data y, data z) {
  data a;
  a.X = y.X - x.X;
  a.Y = y.Y - x.Y;
  data b;
  b.X = z.X - x.X;
  b.Y = z.Y - x.Y;
  return (a.X * b.Y - a.Y * b.X);
}
int main() {
  for (int i = 0; i < M; i++) Hash[i].vX = M1;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    Push(x, y, i);
    point[i].X = (double)x;
    point[i].Y = (double)y;
  }
  mid.X = mid.Y = 0.0;
  for (int i = 1; i <= n; i++) mid.X += point[i].X, mid.Y += point[i].Y;
  mid.X /= ((double)n), mid.Y /= ((double)n);
  for (int i = 1; i <= n; i++)
    if (!vis[i]) {
      double x = mid.X * 2.0 - point[i].X;
      double y = mid.Y * 2.0 - point[i].Y;
      if (Abs(x - point[i].X) <= eps && Abs(y - point[i].Y) <= eps) {
        vis[i] = true;
        continue;
      }
      Hash_data z = Judge(x, y);
      if (z.vX != M1 && Check(z.vX, z.vY))
        Check((int)floor(point[i].X + eps), (int)floor(point[i].Y + eps));
    }
  int num = 0, x = 0;
  for (int i = 1; i <= n; i++)
    if (!vis[i]) num++, x = i;
  if (num <= 2) {
    printf("-1\n");
    return 0;
  }
  int ans = 0;
  for (int y = 1; y <= n; y++)
    if (!vis[y]) {
      data z;
      z.X = (point[x].X + point[y].X) / 2.0;
      z.Y = (point[x].Y + point[y].Y) / 2.0;
      int now = 0;
      for (int k = 1; k <= n; k++)
        if (!vis[k] && k != x && k != y) len[++now] = CJ(point[k], mid, z);
      sort(len + 1, len + now + 1);
      bool sol = true;
      for (int i = 1; i <= (now + 1) / 2; i++) {
        int j = now - i + 1;
        if (Abs(len[i] + len[j]) > eps) {
          sol = false;
          break;
        }
      }
      if (sol) ans++, temp[ans] = z;
    }
  int sum = ans;
  for (int i = 2; i <= sum; i++)
    for (int j = 1; j < i; j++)
      if (Abs(CJ(mid, temp[j], temp[i])) <= eps) {
        ans--;
        break;
      }
  printf("%d\n", ans);
  return 0;
}

### Prompt

Your challenge is to write 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 maxn = 2010;
const double eps = 1e-4;
const long long M1 = 998244353;
const long long M2 = 1000000007;
const long long M = 1333331;
struct Hash_data {
  int vX, vY, id;
} Hash[M];
struct data {
  double X, Y;
} point[maxn];
data mid;
double len[maxn];
bool vis[maxn];
data temp[maxn];
int n;
void Push(long long x, long long y, int Id) {
  long long v = ((x * M1 + y * M2) % M + M) % M;
  while (Hash[v].vX != M1) v = (v + 1) % M;
  Hash[v].vX = x;
  Hash[v].vY = y;
  Hash[v].id = Id;
}
double Abs(double x) {
  if (x > 0.0) return x;
  return -x;
}
Hash_data Judge(double x, double y) {
  Hash_data z;
  z.vX = M1;
  double valX = floor(x + eps), valY = floor(y + eps);
  if (Abs(valX - x) > eps || Abs(valY - y) > eps) return z;
  z.vX = (int)floor(valX + eps);
  z.vY = (int)floor(valY + eps);
  return z;
}
bool Check(long long x, long long y) {
  long long v = ((x * M1 + y * M2) % M + M) % M;
  while (Hash[v].vX != M1 && (Hash[v].vX != x || Hash[v].vY != y))
    v = (v + 1) % M;
  if (Hash[v].vX == M1) return false;
  Hash[v].vX = M2;
  vis[Hash[v].id] = true;
  return true;
}
double CJ(data x, data y, data z) {
  data a;
  a.X = y.X - x.X;
  a.Y = y.Y - x.Y;
  data b;
  b.X = z.X - x.X;
  b.Y = z.Y - x.Y;
  return (a.X * b.Y - a.Y * b.X);
}
int main() {
  for (int i = 0; i < M; i++) Hash[i].vX = M1;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    Push(x, y, i);
    point[i].X = (double)x;
    point[i].Y = (double)y;
  }
  mid.X = mid.Y = 0.0;
  for (int i = 1; i <= n; i++) mid.X += point[i].X, mid.Y += point[i].Y;
  mid.X /= ((double)n), mid.Y /= ((double)n);
  for (int i = 1; i <= n; i++)
    if (!vis[i]) {
      double x = mid.X * 2.0 - point[i].X;
      double y = mid.Y * 2.0 - point[i].Y;
      if (Abs(x - point[i].X) <= eps && Abs(y - point[i].Y) <= eps) {
        vis[i] = true;
        continue;
      }
      Hash_data z = Judge(x, y);
      if (z.vX != M1 && Check(z.vX, z.vY))
        Check((int)floor(point[i].X + eps), (int)floor(point[i].Y + eps));
    }
  int num = 0, x = 0;
  for (int i = 1; i <= n; i++)
    if (!vis[i]) num++, x = i;
  if (num <= 2) {
    printf("-1\n");
    return 0;
  }
  int ans = 0;
  for (int y = 1; y <= n; y++)
    if (!vis[y]) {
      data z;
      z.X = (point[x].X + point[y].X) / 2.0;
      z.Y = (point[x].Y + point[y].Y) / 2.0;
      int now = 0;
      for (int k = 1; k <= n; k++)
        if (!vis[k] && k != x && k != y) len[++now] = CJ(point[k], mid, z);
      sort(len + 1, len + now + 1);
      bool sol = true;
      for (int i = 1; i <= (now + 1) / 2; i++) {
        int j = now - i + 1;
        if (Abs(len[i] + len[j]) > eps) {
          sol = false;
          break;
        }
      }
      if (sol) ans++, temp[ans] = z;
    }
  int sum = ans;
  for (int i = 2; i <= sum; i++)
    for (int j = 1; j < i; j++)
      if (Abs(CJ(mid, temp[j], temp[i])) <= eps) {
        ans--;
        break;
      }
  printf("%d\n", ans);
  return 0;
}

```