#include <bits/stdc++.h>
struct Point;
const double EPS = 1e-7;
const double INF = 1e14;
const int MAXN = 2005;
inline bool eql(double a, double b) { return fabs(a - b) < EPS; }
inline double sqr(double x) { return x * x; }
struct Point {
  double x, y;
  Point(double x_ = 0, double y_ = 0) : x(x_), y(y_) {}
  Point operator+(const Point& v) const { return Point(x + v.x, y + v.y); }
  Point operator*(double k) const { return Point(x * k, y * k); }
  Point operator/(double k) const { return Point(x / k, y / k); }
  bool operator==(const Point& p) const { return eql(x, p.x) && eql(y, p.y); }
  double prjc(double k) const { return (x + k * y) / (1 + sqr(k)); }
  friend void scan(Point& p) { scanf("%lf%lf", &p.x, &p.y); }
  friend bool symmetric(const Point& p1, const Point& p2, const Point& m) {
    return p1 + p2 == m * 2;
  }
} cntr, A[MAXN], B[MAXN];
int N, totp, ans, flag[MAXN];
double X[MAXN];
std::vector<double> L;
void check_y();
void check_line(double k);
int main() {
  scanf("%d", &N);
  for (int i = 0; i < N; i++) {
    scan(A[i]);
    cntr = cntr + A[i];
  }
  cntr = cntr / N;
  for (int i = 0; i < N; i++)
    for (int j = i + 1; j < N; j++)
      if (symmetric(A[i], A[j], cntr)) flag[i] = flag[j] = 1;
  for (int i = 0; i < N; i++)
    if (!flag[i]) B[totp++] = A[i];
  if (totp <= 2) return puts("-1"), 0;
  0;
  check_y();
  for (int i = 0; i < totp; i++)
    for (int j = i + 1; j < totp; j++) {
      if (eql(2 * cntr.y - B[i].y - B[j].y, 0)) continue;
      L.push_back((B[i].x + B[j].x - 2 * cntr.x) /
                  (2 * cntr.y - B[i].y - B[j].y));
    }
  std::sort(L.begin(), L.end());
  L.push_back(INF);
  double now = INF;
  int cnt = 0;
  for (auto k : L) {
    if (eql(k, now)) {
      ++cnt;
      continue;
    }
    if (cnt && cnt * 2 + 1 >= totp) check_line(now);
    now = k, cnt = 1;
  }
  printf("%d\n", ans);
  return 0;
}
void check_y() {
  for (int i = 0; i < totp; i++) X[i] = B[i].y;
  std::sort(X, X + totp);
  double mid = cntr.y * 2;
  for (int i = 0; i + i < totp; i++)
    if (!eql(X[i] + X[totp - i - 1], mid)) return;
  ++ans;
}
void check_line(double k) {
  0;
  for (int i = 0; i < totp; i++) X[i] = B[i].prjc(k);
  std::sort(X, X + totp);
  double mid = cntr.prjc(k) * 2;
  for (int i = 0; i + i < totp; i++)
    if (!eql(X[i] + X[totp - i - 1], mid)) return;
  ++ans;
}

### Prompt

Please provide a cpp coded solution 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>
struct Point;
const double EPS = 1e-7;
const double INF = 1e14;
const int MAXN = 2005;
inline bool eql(double a, double b) { return fabs(a - b) < EPS; }
inline double sqr(double x) { return x * x; }
struct Point {
  double x, y;
  Point(double x_ = 0, double y_ = 0) : x(x_), y(y_) {}
  Point operator+(const Point& v) const { return Point(x + v.x, y + v.y); }
  Point operator*(double k) const { return Point(x * k, y * k); }
  Point operator/(double k) const { return Point(x / k, y / k); }
  bool operator==(const Point& p) const { return eql(x, p.x) && eql(y, p.y); }
  double prjc(double k) const { return (x + k * y) / (1 + sqr(k)); }
  friend void scan(Point& p) { scanf("%lf%lf", &p.x, &p.y); }
  friend bool symmetric(const Point& p1, const Point& p2, const Point& m) {
    return p1 + p2 == m * 2;
  }
} cntr, A[MAXN], B[MAXN];
int N, totp, ans, flag[MAXN];
double X[MAXN];
std::vector<double> L;
void check_y();
void check_line(double k);
int main() {
  scanf("%d", &N);
  for (int i = 0; i < N; i++) {
    scan(A[i]);
    cntr = cntr + A[i];
  }
  cntr = cntr / N;
  for (int i = 0; i < N; i++)
    for (int j = i + 1; j < N; j++)
      if (symmetric(A[i], A[j], cntr)) flag[i] = flag[j] = 1;
  for (int i = 0; i < N; i++)
    if (!flag[i]) B[totp++] = A[i];
  if (totp <= 2) return puts("-1"), 0;
  0;
  check_y();
  for (int i = 0; i < totp; i++)
    for (int j = i + 1; j < totp; j++) {
      if (eql(2 * cntr.y - B[i].y - B[j].y, 0)) continue;
      L.push_back((B[i].x + B[j].x - 2 * cntr.x) /
                  (2 * cntr.y - B[i].y - B[j].y));
    }
  std::sort(L.begin(), L.end());
  L.push_back(INF);
  double now = INF;
  int cnt = 0;
  for (auto k : L) {
    if (eql(k, now)) {
      ++cnt;
      continue;
    }
    if (cnt && cnt * 2 + 1 >= totp) check_line(now);
    now = k, cnt = 1;
  }
  printf("%d\n", ans);
  return 0;
}
void check_y() {
  for (int i = 0; i < totp; i++) X[i] = B[i].y;
  std::sort(X, X + totp);
  double mid = cntr.y * 2;
  for (int i = 0; i + i < totp; i++)
    if (!eql(X[i] + X[totp - i - 1], mid)) return;
  ++ans;
}
void check_line(double k) {
  0;
  for (int i = 0; i < totp; i++) X[i] = B[i].prjc(k);
  std::sort(X, X + totp);
  double mid = cntr.prjc(k) * 2;
  for (int i = 0; i + i < totp; i++)
    if (!eql(X[i] + X[totp - i - 1], mid)) return;
  ++ans;
}

```