#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double EPS = 1e-7;
int n;
struct pp {
  double x, y;
  int index;
  pp() {}
  pp(double x, double y, int index) : x(x), y(y), index(index) {}
  bool operator==(const pp &p) const {
    return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;
  }
  bool operator<(const pp &p) const {
    return fabs(x - p.x) < EPS ? y < p.y - EPS : x < p.x - EPS;
  }
} p[2015];
struct hh {
  double x;
  hh() {}
  hh(double x) : x(x) {}
  bool operator==(const hh &h) const { return fabs(x - h.x) < EPS; }
  bool operator<(const hh &h) const { return x < h.x - EPS; }
  hh operator+(const hh &h) const { return hh(h.x + x); }
};
set<pp> s0;
map<hh, int> mmp;
double x_, y_, x_1, y_1, x_3, y_3, x_2, y_2;
hh cal(double x, double y) {
  double x1 = x_, y1 = y_;
  double x2 = x_3, y2 = y_3;
  double x3 = x, y3 = y;
  double tt = (y3 * (x1 - x2) + (y2 - y1) * x3);
  return hh(tt);
}
int flag[2015];
bool check() {
  if (mmp.size() < 2) return true;
  map<hh, int>::iterator it1 = mmp.begin(), it2 = --mmp.end();
  hh H = (*it1).first + (*it2).first;
  for (; ((it1->first) < (it2->first)) || (it1->first == it2->first);
       ++it1, --it2) {
    hh th = it1->first + it2->first;
    if (it1->second != it2->second) return false;
    if (!(th == H)) return false;
  }
  return true;
}
struct pdd {
  double x, y;
  pdd() {}
  pdd(double x, double y) : x(x), y(y) {}
  bool operator<(const pdd &p) const {
    return fabs(x - p.x) < EPS ? y < p.y - EPS : x < p.x < EPS;
  }
};
set<pdd> ss;
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    scanf("%lf%lf", &p[i].x, &p[i].y);
    x_ += p[i].x, y_ += p[i].y;
    p[i].index = i;
    s0.insert(p[i]);
  }
  x_ /= n, y_ /= n;
  for (set<pp>::iterator it = s0.begin(); it != s0.end();) {
    double tx = (*it).x, ty = (*it).y;
    pp tp = pp(tx, ty, 0);
    int id = (*it).index;
    if (tp == pp(x_, y_, 0)) {
      s0.erase(tp);
      flag[id] = -1;
    } else {
      double tx2 = x_ * 2 - tx, ty2 = y_ * 2 - ty;
      pp tp2 = pp(tx2, ty2, 0);
      set<pp>::iterator it1 = s0.lower_bound(tp2);
      set<pp>::iterator it2 = s0.upper_bound(tp2);
      if (it1 != it2) {
        int id2 = it1->index;
        s0.erase(tp);
        s0.erase(*it1);
        flag[id] = flag[id2] = -1;
      }
    }
    it = s0.upper_bound(tp);
  }
  if (s0.empty()) {
    puts("-1");
    return 0;
  }
  int i = 1, ans = 0;
  for (; i <= n; ++i) {
    if (!flag[i]) break;
  }
  x_1 = p[i].x, y_1 = p[i].y;
  for (int j = i; j <= n; ++j) {
    if (flag[j]) continue;
    x_2 = p[j].x, y_2 = p[j].y;
    x_3 = (x_1 + x_2) / 2, y_3 = (y_1 + y_2) / 2;
    pdd pp = pdd(x_3 - x_, y_3 - y_);
    if (fabs(x_3 - x_) < EPS)
      pp = pdd(0, 1);
    else if (fabs(y_3 - y_) < EPS)
      pp = pdd(1, 0);
    else
      pp = pdd(1, (y_3 - y_) / (x_3 - x_));
    if (ss.lower_bound(pp) != ss.upper_bound(pp)) continue;
    ss.insert(pp);
    mmp.clear();
    for (int k = 1; k <= n; ++k) {
      if (flag[k]) continue;
      hh h = cal(p[k].x, p[k].y);
      ++mmp[h];
    }
    if (check()) ++ans;
  }
  printf("%d\n", ans);
  return 0;
}

### 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>
using namespace std;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double EPS = 1e-7;
int n;
struct pp {
  double x, y;
  int index;
  pp() {}
  pp(double x, double y, int index) : x(x), y(y), index(index) {}
  bool operator==(const pp &p) const {
    return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;
  }
  bool operator<(const pp &p) const {
    return fabs(x - p.x) < EPS ? y < p.y - EPS : x < p.x - EPS;
  }
} p[2015];
struct hh {
  double x;
  hh() {}
  hh(double x) : x(x) {}
  bool operator==(const hh &h) const { return fabs(x - h.x) < EPS; }
  bool operator<(const hh &h) const { return x < h.x - EPS; }
  hh operator+(const hh &h) const { return hh(h.x + x); }
};
set<pp> s0;
map<hh, int> mmp;
double x_, y_, x_1, y_1, x_3, y_3, x_2, y_2;
hh cal(double x, double y) {
  double x1 = x_, y1 = y_;
  double x2 = x_3, y2 = y_3;
  double x3 = x, y3 = y;
  double tt = (y3 * (x1 - x2) + (y2 - y1) * x3);
  return hh(tt);
}
int flag[2015];
bool check() {
  if (mmp.size() < 2) return true;
  map<hh, int>::iterator it1 = mmp.begin(), it2 = --mmp.end();
  hh H = (*it1).first + (*it2).first;
  for (; ((it1->first) < (it2->first)) || (it1->first == it2->first);
       ++it1, --it2) {
    hh th = it1->first + it2->first;
    if (it1->second != it2->second) return false;
    if (!(th == H)) return false;
  }
  return true;
}
struct pdd {
  double x, y;
  pdd() {}
  pdd(double x, double y) : x(x), y(y) {}
  bool operator<(const pdd &p) const {
    return fabs(x - p.x) < EPS ? y < p.y - EPS : x < p.x < EPS;
  }
};
set<pdd> ss;
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    scanf("%lf%lf", &p[i].x, &p[i].y);
    x_ += p[i].x, y_ += p[i].y;
    p[i].index = i;
    s0.insert(p[i]);
  }
  x_ /= n, y_ /= n;
  for (set<pp>::iterator it = s0.begin(); it != s0.end();) {
    double tx = (*it).x, ty = (*it).y;
    pp tp = pp(tx, ty, 0);
    int id = (*it).index;
    if (tp == pp(x_, y_, 0)) {
      s0.erase(tp);
      flag[id] = -1;
    } else {
      double tx2 = x_ * 2 - tx, ty2 = y_ * 2 - ty;
      pp tp2 = pp(tx2, ty2, 0);
      set<pp>::iterator it1 = s0.lower_bound(tp2);
      set<pp>::iterator it2 = s0.upper_bound(tp2);
      if (it1 != it2) {
        int id2 = it1->index;
        s0.erase(tp);
        s0.erase(*it1);
        flag[id] = flag[id2] = -1;
      }
    }
    it = s0.upper_bound(tp);
  }
  if (s0.empty()) {
    puts("-1");
    return 0;
  }
  int i = 1, ans = 0;
  for (; i <= n; ++i) {
    if (!flag[i]) break;
  }
  x_1 = p[i].x, y_1 = p[i].y;
  for (int j = i; j <= n; ++j) {
    if (flag[j]) continue;
    x_2 = p[j].x, y_2 = p[j].y;
    x_3 = (x_1 + x_2) / 2, y_3 = (y_1 + y_2) / 2;
    pdd pp = pdd(x_3 - x_, y_3 - y_);
    if (fabs(x_3 - x_) < EPS)
      pp = pdd(0, 1);
    else if (fabs(y_3 - y_) < EPS)
      pp = pdd(1, 0);
    else
      pp = pdd(1, (y_3 - y_) / (x_3 - x_));
    if (ss.lower_bound(pp) != ss.upper_bound(pp)) continue;
    ss.insert(pp);
    mmp.clear();
    for (int k = 1; k <= n; ++k) {
      if (flag[k]) continue;
      hh h = cal(p[k].x, p[k].y);
      ++mmp[h];
    }
    if (check()) ++ans;
  }
  printf("%d\n", ans);
  return 0;
}

```