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.
#include <bits/stdc++.h>
using namespace std;
inline int cmp(double a, double b) {
  return fabs(a - b) < 1e-7 ? 0 : (a - b > 0) ? 1 : -1;
}
class vec {
 public:
  double x, y;
  vec() {}
  vec(double tx, double ty) { x = tx, y = ty; }
  vec operator+(const vec &t) { return vec(x + t.x, y + t.y); }
  vec operator-(const vec &t) { return vec(x - t.x, y - t.y); }
  double operator*(const vec &t) { return x * t.x + y * t.y; }
  vec operator*(const double &t) { return vec(x * t, y * t); }
  vec operator/(const double &t) { return vec(x / t, y / t); }
  bool operator==(const vec &t) { return cmp(x, t.x) == 0 && cmp(y, t.y) == 0; }
  double len() { return sqrt(x * x + y * y); }
  vec sing() { return *this / len(); }
} v[2010];
int n, bcnt = 0;
vec cet;
bool ban[2010];
double val[2010];
vector<vec> v2;
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++)
    scanf("%lf%lf", &v[i].x, &v[i].y), cet = cet + v[i];
  cet = cet / n;
  for (int i = 1; i <= n; i++) {
    if (v[i] == cet) {
      ban[i] = 1;
      bcnt++;
      continue;
    }
    if (!ban[i])
      for (int j = i + 1; j <= n; j++) {
        if (ban[j]) continue;
        if (v[i] + v[j] == cet * 2) {
          ban[i] = ban[j] = 1;
          bcnt += 2;
          break;
        }
      }
  }
  for (int i = 1; i <= n; i++)
    if (!ban[i]) v2.push_back(v[i]);
  if (!v2.size()) {
    puts("-1");
    return 0;
  }
  vector<vec> lans;
  int ans = 0;
  for (int i = 0; i < v2.size(); i++) {
    vec mid = (v2[0] + v2[i]) / 2;
    vec l1 = cet - mid;
    vec l2 = vec(-l1.y, l1.x).sing();
    for (int j = 0; j < v2.size(); j++) val[j] = v2[j] * l2;
    sort(val, val + v2.size());
    double vc = cet * l2;
    bool flag = 1;
    for (int j = 0; j < lans.size(); j++) {
      if (l2 == lans[j] || l2 == lans[j] * (-1)) {
        flag = 0;
        break;
      }
    }
    if (!flag) continue;
    lans.push_back(l2);
    for (int l = 0, r = v2.size() - 1; l <= r; l++, r--) {
      if (cmp(val[l] + val[r], vc * 2)) {
        flag = 0;
        break;
      }
    }
    ans += flag;
  }
  printf("%d\n", ans);
  return 0;
}
