#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
const int MAXN = 2000;
typedef struct P {
  long long x, y;
  P() {}
  P(long long x, long long y) : x(x), y(y) {}
} P;
bool operator<(const P &a, const P &b) {
  if (a.x != b.x) return a.x < b.x;
  return a.y < b.y;
}
bool operator==(const P &a, const P &b) { return a.x == b.x && a.y == b.y; }
P operator-(const P &a, const P &b) { return P(a.x - b.x, a.y - b.y); }
long long operator*(const P &a, const P &b) { return a.x * b.x + a.y * b.y; }
int n;
P p[MAXN];
P c;
int mlt;
long long v[MAXN];
bool ok(const P &dir) {
  for (int i = (0); i < (n); ++i) v[i] = p[i] * dir;
  sort(v, v + n);
  long long sum = v[0] + v[n - 1];
  for (int i = (0); i < (n); ++i)
    if (v[i] + v[n - i - 1] != sum) return false;
  return true;
}
void run() {
  scanf("%d", &n);
  for (int i = (0); i < (n); ++i) scanf("%lld%lld", &p[i].x, &p[i].y);
  mlt = n;
  c.x = c.y = 0;
  for (int i = (0); i < (n); ++i) c.x += p[i].x, c.y += p[i].y;
  set<P> have;
  for (int i = (0); i < (n); ++i) {
    P cur = P(mlt * p[i].x, mlt * p[i].y);
    P opp = c - (cur - c);
    if (cur == opp)
      continue;
    else if (have.count(opp))
      have.erase(opp);
    else
      have.insert(cur);
  }
  n = 0;
  for (auto it = have.begin(); it != have.end(); ++it)
    p[n++] = P(it->x / mlt, it->y / mlt);
  if (n == 0) {
    printf("-1\n");
    return;
  }
  set<P> ptest;
  for (int j = (0); j < (n); ++j) {
    P a = P(2 * c.x, 2 * c.y),
      b = P(mlt * (p[0].x + p[j].x), mlt * (p[0].y + p[j].y));
    P dir = P((b - a).y, -(b - a).x);
    if (dir.x < 0 || dir.x == 0 && dir.y < 0) dir.x = -dir.x, dir.y = -dir.y;
    long long g = gcd(dir.x, abs(dir.y));
    dir.x /= g, dir.y /= g;
    ptest.insert(dir);
  }
  int ret = 0;
  for (auto it = ptest.begin(); it != ptest.end(); ++it)
    if (ok(*it)) ++ret;
  printf("%d\n", ret);
}
int main() {
  run();
  return 0;
}

### Prompt

Construct a cpp code solution to the problem outlined:

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;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
const int MAXN = 2000;
typedef struct P {
  long long x, y;
  P() {}
  P(long long x, long long y) : x(x), y(y) {}
} P;
bool operator<(const P &a, const P &b) {
  if (a.x != b.x) return a.x < b.x;
  return a.y < b.y;
}
bool operator==(const P &a, const P &b) { return a.x == b.x && a.y == b.y; }
P operator-(const P &a, const P &b) { return P(a.x - b.x, a.y - b.y); }
long long operator*(const P &a, const P &b) { return a.x * b.x + a.y * b.y; }
int n;
P p[MAXN];
P c;
int mlt;
long long v[MAXN];
bool ok(const P &dir) {
  for (int i = (0); i < (n); ++i) v[i] = p[i] * dir;
  sort(v, v + n);
  long long sum = v[0] + v[n - 1];
  for (int i = (0); i < (n); ++i)
    if (v[i] + v[n - i - 1] != sum) return false;
  return true;
}
void run() {
  scanf("%d", &n);
  for (int i = (0); i < (n); ++i) scanf("%lld%lld", &p[i].x, &p[i].y);
  mlt = n;
  c.x = c.y = 0;
  for (int i = (0); i < (n); ++i) c.x += p[i].x, c.y += p[i].y;
  set<P> have;
  for (int i = (0); i < (n); ++i) {
    P cur = P(mlt * p[i].x, mlt * p[i].y);
    P opp = c - (cur - c);
    if (cur == opp)
      continue;
    else if (have.count(opp))
      have.erase(opp);
    else
      have.insert(cur);
  }
  n = 0;
  for (auto it = have.begin(); it != have.end(); ++it)
    p[n++] = P(it->x / mlt, it->y / mlt);
  if (n == 0) {
    printf("-1\n");
    return;
  }
  set<P> ptest;
  for (int j = (0); j < (n); ++j) {
    P a = P(2 * c.x, 2 * c.y),
      b = P(mlt * (p[0].x + p[j].x), mlt * (p[0].y + p[j].y));
    P dir = P((b - a).y, -(b - a).x);
    if (dir.x < 0 || dir.x == 0 && dir.y < 0) dir.x = -dir.x, dir.y = -dir.y;
    long long g = gcd(dir.x, abs(dir.y));
    dir.x /= g, dir.y /= g;
    ptest.insert(dir);
  }
  int ret = 0;
  for (auto it = ptest.begin(); it != ptest.end(); ++it)
    if (ok(*it)) ++ret;
  printf("%d\n", ret);
}
int main() {
  run();
  return 0;
}

```