#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f2f1f0f;
const long long LINF = 1ll * INF * INF;
const int MAX_N = 2e3 + 10;
struct PT {
  long long x, y;
  PT() : x(0), y(0) {}
  PT(long long xx, long long yy) : x(xx), y(yy) {}
  const bool operator<(const PT &o) const {
    if (x != o.x) return x < o.x;
    return y < o.y;
  }
};
int N;
set<PT> Pset;
vector<PT> Ps;
long long gcd(long long x, long long y) {
  if (y == 0) return x;
  return gcd(y, x % y);
}
int main() {
  cin >> N;
  long long sx = 0, sy = 0;
  for (int i = 0; i < N; i++) {
    long long x, y;
    scanf("%lld%lld", &x, &y);
    x *= 2;
    y *= 2;
    sx += x;
    sy += y;
    x *= N;
    y *= N;
    Pset.insert(PT(x, y));
  }
  vector<PT> EList;
  for (PT p : Pset) {
    long long ox = 2 * sx - p.x, oy = 2 * sy - p.y;
    if (Pset.find(PT(ox, oy)) != Pset.end()) EList.push_back(p);
  }
  for (PT &p : EList) Pset.erase(p);
  for (PT p : Pset) Ps.push_back(p);
  if (((int)(Pset).size()) == 0) {
    puts("-1");
    return 0;
  }
  int ans = 0;
  vector<pair<long long, long long> > plls;
  for (int p = 0; p < ((int)(Ps).size()); p++) {
    long long mx = (Ps[0].x + Ps[p].x) / 2, my = (Ps[0].y + Ps[p].y) / 2;
    long long dx = (mx - sx), dy = (my - sy);
    swap(dx, dy);
    dx *= -1;
    long long g = gcd(abs(dx), abs(dy));
    dx /= g;
    dy /= g;
    if (dx < 0) dx *= -1, dy *= -1;
    plls.push_back(pair<long long, long long>(dx, dy));
  }
  sort((plls).begin(), (plls).end());
  plls.erase(unique((plls).begin(), (plls).end()), plls.end());
  for (pair<long long, long long> &pls : plls) {
    long long dx, dy;
    tie(dx, dy) = pls;
    vector<long long> vals;
    for (int i = 0; i < ((int)(Ps).size()); i++)
      vals.push_back(dy * Ps[i].y + dx * Ps[i].x);
    sort((vals).begin(), (vals).end());
    long long sum = vals.front() + vals.back();
    bool isCan = true;
    for (int i = 0; i < ((int)(Ps).size()); i++)
      if (sum != vals[i] + vals[((int)(Ps).size()) - 1 - i]) {
        isCan = false;
        break;
      }
    if (isCan) {
      ans++;
    }
  }
  printf("%d\n", ans);
  return 0;
}

### Prompt

Please formulate a Cpp solution to the following problem:

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 INF = 0x3f2f1f0f;
const long long LINF = 1ll * INF * INF;
const int MAX_N = 2e3 + 10;
struct PT {
  long long x, y;
  PT() : x(0), y(0) {}
  PT(long long xx, long long yy) : x(xx), y(yy) {}
  const bool operator<(const PT &o) const {
    if (x != o.x) return x < o.x;
    return y < o.y;
  }
};
int N;
set<PT> Pset;
vector<PT> Ps;
long long gcd(long long x, long long y) {
  if (y == 0) return x;
  return gcd(y, x % y);
}
int main() {
  cin >> N;
  long long sx = 0, sy = 0;
  for (int i = 0; i < N; i++) {
    long long x, y;
    scanf("%lld%lld", &x, &y);
    x *= 2;
    y *= 2;
    sx += x;
    sy += y;
    x *= N;
    y *= N;
    Pset.insert(PT(x, y));
  }
  vector<PT> EList;
  for (PT p : Pset) {
    long long ox = 2 * sx - p.x, oy = 2 * sy - p.y;
    if (Pset.find(PT(ox, oy)) != Pset.end()) EList.push_back(p);
  }
  for (PT &p : EList) Pset.erase(p);
  for (PT p : Pset) Ps.push_back(p);
  if (((int)(Pset).size()) == 0) {
    puts("-1");
    return 0;
  }
  int ans = 0;
  vector<pair<long long, long long> > plls;
  for (int p = 0; p < ((int)(Ps).size()); p++) {
    long long mx = (Ps[0].x + Ps[p].x) / 2, my = (Ps[0].y + Ps[p].y) / 2;
    long long dx = (mx - sx), dy = (my - sy);
    swap(dx, dy);
    dx *= -1;
    long long g = gcd(abs(dx), abs(dy));
    dx /= g;
    dy /= g;
    if (dx < 0) dx *= -1, dy *= -1;
    plls.push_back(pair<long long, long long>(dx, dy));
  }
  sort((plls).begin(), (plls).end());
  plls.erase(unique((plls).begin(), (plls).end()), plls.end());
  for (pair<long long, long long> &pls : plls) {
    long long dx, dy;
    tie(dx, dy) = pls;
    vector<long long> vals;
    for (int i = 0; i < ((int)(Ps).size()); i++)
      vals.push_back(dy * Ps[i].y + dx * Ps[i].x);
    sort((vals).begin(), (vals).end());
    long long sum = vals.front() + vals.back();
    bool isCan = true;
    for (int i = 0; i < ((int)(Ps).size()); i++)
      if (sum != vals[i] + vals[((int)(Ps).size()) - 1 - i]) {
        isCan = false;
        break;
      }
    if (isCan) {
      ans++;
    }
  }
  printf("%d\n", ans);
  return 0;
}

```