#include <bits/stdc++.h>
using namespace std;
const int N = 2002;
const double EPS = 1e-7;
double d[N];
int vis[N];
struct Point {
  double x, y;
  Point() {}
  Point(double x_, double y_) {
    x = x_;
    y = y_;
  }
  void read() { scanf("%lf %lf", &x, &y); }
  void print() { printf("%.5f %.5f\n", x, y); }
  Point operator+(const Point &other) const {
    return Point(x + other.x, y + other.y);
  }
  Point operator-(const Point &other) const {
    return Point(x - other.x, y - other.y);
  }
  Point operator/(const double &val) const { return Point(x / val, y / val); }
  double operator*(const Point &other) const {
    return x * other.x + y * other.y;
  }
  double operator^(const Point &other) const {
    return x * other.y - y * other.x;
  }
} p[N];
struct Line {
  Point start, direct;
  Line() {}
  Line(Point start_, Point direct_) {
    start = start_;
    direct = direct_;
  }
  double dis(Point P) { return (direct ^ (P - start)) / sqrt(direct * direct); }
  bool same(Line L) {
    if (abs(direct ^ L.direct) > EPS) return 0;
    if (abs(direct ^ (L.start - start)) > EPS) return 0;
    return 1;
  }
} l[N];
int cnt = 0;
int n;
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) p[i].read();
  if (n <= 2) {
    printf("-1\n");
    return 0;
  }
  if (p[1] * p[1] < EPS) swap(p[1], p[2]);
  Point M(0, 0);
  for (int i = 1; i <= n; i++) M = M + p[i];
  M = M / n;
  int sym = 0, pos;
  for (int i = 1; i <= n; i++) {
    int flag = 0;
    for (int j = 1; j <= n; j++) {
      if ((p[j] + p[i]) * (p[j] + p[i]) < EPS ||
          ((p[j] + p[i]) / 2 - M) * ((p[j] + p[i]) / 2 - M) < EPS)
        flag = 1;
    }
    if (flag)
      sym++;
    else
      pos = i;
  }
  if (sym == n) {
    printf("%d\n", -1);
    return 0;
  }
  swap(p[1], p[pos]);
  for (int i = 1; i <= n; i++) {
    if ((p[1] + p[i]) * (p[1] + p[i]) < EPS) continue;
    if (((p[1] + p[i]) / 2 - M) * ((p[1] + p[i]) / 2 - M) < EPS) continue;
    Point P = (p[1] + p[i]) / 2;
    Line L = Line(P, P - M);
    for (int j = 1; j <= n; j++) {
      d[j] = L.dis(p[j]);
    }
    sort(d + 1, d + 1 + n);
    bool ok = 1;
    for (int i = 1; i <= n; i++) {
      if (d[i] + d[n + 1 - i] > EPS) {
        ok = 0;
        break;
      }
    }
    if (ok) l[++cnt] = L;
  }
  int ans = 0;
  for (int i = 1; i <= cnt; i++) {
    int flag = 1;
    for (int j = 1; j < i; j++) {
      if (l[i].same(l[j])) flag = 0;
    }
    if (flag) ans++;
  }
  printf("%d\n", ans);
}

### Prompt

Develop a solution in cpp to the problem described below:

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 = 2002;
const double EPS = 1e-7;
double d[N];
int vis[N];
struct Point {
  double x, y;
  Point() {}
  Point(double x_, double y_) {
    x = x_;
    y = y_;
  }
  void read() { scanf("%lf %lf", &x, &y); }
  void print() { printf("%.5f %.5f\n", x, y); }
  Point operator+(const Point &other) const {
    return Point(x + other.x, y + other.y);
  }
  Point operator-(const Point &other) const {
    return Point(x - other.x, y - other.y);
  }
  Point operator/(const double &val) const { return Point(x / val, y / val); }
  double operator*(const Point &other) const {
    return x * other.x + y * other.y;
  }
  double operator^(const Point &other) const {
    return x * other.y - y * other.x;
  }
} p[N];
struct Line {
  Point start, direct;
  Line() {}
  Line(Point start_, Point direct_) {
    start = start_;
    direct = direct_;
  }
  double dis(Point P) { return (direct ^ (P - start)) / sqrt(direct * direct); }
  bool same(Line L) {
    if (abs(direct ^ L.direct) > EPS) return 0;
    if (abs(direct ^ (L.start - start)) > EPS) return 0;
    return 1;
  }
} l[N];
int cnt = 0;
int n;
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) p[i].read();
  if (n <= 2) {
    printf("-1\n");
    return 0;
  }
  if (p[1] * p[1] < EPS) swap(p[1], p[2]);
  Point M(0, 0);
  for (int i = 1; i <= n; i++) M = M + p[i];
  M = M / n;
  int sym = 0, pos;
  for (int i = 1; i <= n; i++) {
    int flag = 0;
    for (int j = 1; j <= n; j++) {
      if ((p[j] + p[i]) * (p[j] + p[i]) < EPS ||
          ((p[j] + p[i]) / 2 - M) * ((p[j] + p[i]) / 2 - M) < EPS)
        flag = 1;
    }
    if (flag)
      sym++;
    else
      pos = i;
  }
  if (sym == n) {
    printf("%d\n", -1);
    return 0;
  }
  swap(p[1], p[pos]);
  for (int i = 1; i <= n; i++) {
    if ((p[1] + p[i]) * (p[1] + p[i]) < EPS) continue;
    if (((p[1] + p[i]) / 2 - M) * ((p[1] + p[i]) / 2 - M) < EPS) continue;
    Point P = (p[1] + p[i]) / 2;
    Line L = Line(P, P - M);
    for (int j = 1; j <= n; j++) {
      d[j] = L.dis(p[j]);
    }
    sort(d + 1, d + 1 + n);
    bool ok = 1;
    for (int i = 1; i <= n; i++) {
      if (d[i] + d[n + 1 - i] > EPS) {
        ok = 0;
        break;
      }
    }
    if (ok) l[++cnt] = L;
  }
  int ans = 0;
  for (int i = 1; i <= cnt; i++) {
    int flag = 1;
    for (int j = 1; j < i; j++) {
      if (l[i].same(l[j])) flag = 0;
    }
    if (flag) ans++;
  }
  printf("%d\n", ans);
}

```