#include <bits/stdc++.h>
const int MAXN = 2000 + 10;
const double EPS = 1e-6;
int sgn(double x) { return x < -EPS ? -1 : x > EPS; }
struct Vector {
  double x, y;
  Vector(double x = 0, double y = 0) : x(x), y(y) {}
  Vector operator+(const Vector &rhs) const {
    return (Vector){x + rhs.x, y + rhs.y};
  }
  Vector operator-(const Vector &rhs) const {
    return (Vector){x - rhs.x, y - rhs.y};
  }
  Vector operator*(const double rhs) const {
    return (Vector){x * rhs, y * rhs};
  }
  Vector operator/(const double rhs) const {
    return (Vector){x / rhs, y / rhs};
  }
  bool operator==(const Vector rhs) const {
    return sgn(x - rhs.x) == 0 && sgn(y - rhs.y) == 0;
  }
} pts[MAXN];
double cross(Vector a, Vector b) { return a.x * b.y - a.y * b.x; }
int n;
namespace solver1 {
struct Data {
  Vector v;
  int a, b;
  bool operator<(const Data &rhs) const { return cross(v, rhs.v) < 0; }
};
void main() {
  Vector o;
  for (int i = 1; i <= n; i++) {
    o = o + pts[i];
  }
  o = o / n;
  static bool visit[MAXN];
  memset(visit, 0, sizeof visit);
  int tot = n;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j < i; j++) {
      if (visit[j]) continue;
      if (pts[i] + pts[j] == o * 2) {
        visit[i] = visit[j] = 1;
        tot -= 2;
        break;
      }
    }
  }
  if (tot <= 2) {
    puts("-1");
    return;
  }
  int cnt = 0;
  for (int i = 1; i <= n; i++) {
    if (!visit[i]) {
      pts[++cnt] = pts[i];
    }
  }
  std::vector<Data> vec;
  for (int i = 1; i <= cnt; i++) {
    for (int j = i + 1; j <= cnt; j++) {
      Vector a = (pts[i] + pts[j]) / 2;
      double y = a.x - o.x;
      double x = a.y - o.y;
      if (y < 0) {
        y = -y;
        x = -x;
      }
      if (sgn(y) == 0 && sgn(x) < 0) {
        y = -y;
        x = -x;
      }
      vec.push_back((Data){Vector(x, y), i, j});
    }
  }
  n = cnt;
  std::sort(vec.begin(), vec.end());
  int ans = 0;
  int last = 0;
  cnt = 1;
  for (int i = 0; i < (int)vec.size(); i++) {
    if (i == (int)vec.size() - 1 || cross(vec[i].v, vec[i + 1].v) != 0) {
      if (cnt >= n / 2) {
        static bool vis[MAXN];
        memset(vis, 0, sizeof vis);
        for (int j = last; j <= i; j++) {
          if (vis[vec[j].a] || vis[vec[j].b]) continue;
          vis[vec[j].a] = vis[vec[j].b] = 1;
        }
        int flag = 0;
        for (int i = 1; i <= n; i++) {
          if (!vis[i]) flag++;
        }
        if (flag <= 1) ans++;
      }
      last = i + 1;
      cnt = 1;
    } else {
      cnt++;
    }
  }
  printf("%d\n", ans);
}
}  // namespace solver1
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    pts[i] = Vector(x, y);
  }
  solver1::main();
}

### 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>
const int MAXN = 2000 + 10;
const double EPS = 1e-6;
int sgn(double x) { return x < -EPS ? -1 : x > EPS; }
struct Vector {
  double x, y;
  Vector(double x = 0, double y = 0) : x(x), y(y) {}
  Vector operator+(const Vector &rhs) const {
    return (Vector){x + rhs.x, y + rhs.y};
  }
  Vector operator-(const Vector &rhs) const {
    return (Vector){x - rhs.x, y - rhs.y};
  }
  Vector operator*(const double rhs) const {
    return (Vector){x * rhs, y * rhs};
  }
  Vector operator/(const double rhs) const {
    return (Vector){x / rhs, y / rhs};
  }
  bool operator==(const Vector rhs) const {
    return sgn(x - rhs.x) == 0 && sgn(y - rhs.y) == 0;
  }
} pts[MAXN];
double cross(Vector a, Vector b) { return a.x * b.y - a.y * b.x; }
int n;
namespace solver1 {
struct Data {
  Vector v;
  int a, b;
  bool operator<(const Data &rhs) const { return cross(v, rhs.v) < 0; }
};
void main() {
  Vector o;
  for (int i = 1; i <= n; i++) {
    o = o + pts[i];
  }
  o = o / n;
  static bool visit[MAXN];
  memset(visit, 0, sizeof visit);
  int tot = n;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j < i; j++) {
      if (visit[j]) continue;
      if (pts[i] + pts[j] == o * 2) {
        visit[i] = visit[j] = 1;
        tot -= 2;
        break;
      }
    }
  }
  if (tot <= 2) {
    puts("-1");
    return;
  }
  int cnt = 0;
  for (int i = 1; i <= n; i++) {
    if (!visit[i]) {
      pts[++cnt] = pts[i];
    }
  }
  std::vector<Data> vec;
  for (int i = 1; i <= cnt; i++) {
    for (int j = i + 1; j <= cnt; j++) {
      Vector a = (pts[i] + pts[j]) / 2;
      double y = a.x - o.x;
      double x = a.y - o.y;
      if (y < 0) {
        y = -y;
        x = -x;
      }
      if (sgn(y) == 0 && sgn(x) < 0) {
        y = -y;
        x = -x;
      }
      vec.push_back((Data){Vector(x, y), i, j});
    }
  }
  n = cnt;
  std::sort(vec.begin(), vec.end());
  int ans = 0;
  int last = 0;
  cnt = 1;
  for (int i = 0; i < (int)vec.size(); i++) {
    if (i == (int)vec.size() - 1 || cross(vec[i].v, vec[i + 1].v) != 0) {
      if (cnt >= n / 2) {
        static bool vis[MAXN];
        memset(vis, 0, sizeof vis);
        for (int j = last; j <= i; j++) {
          if (vis[vec[j].a] || vis[vec[j].b]) continue;
          vis[vec[j].a] = vis[vec[j].b] = 1;
        }
        int flag = 0;
        for (int i = 1; i <= n; i++) {
          if (!vis[i]) flag++;
        }
        if (flag <= 1) ans++;
      }
      last = i + 1;
      cnt = 1;
    } else {
      cnt++;
    }
  }
  printf("%d\n", ans);
}
}  // namespace solver1
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    pts[i] = Vector(x, y);
  }
  solver1::main();
}

```