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;
bool Finish_read;
template <class T>
inline void read(T &x) {
  Finish_read = 0;
  x = 0;
  int f = 1;
  char ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-') f = -1;
    if (ch == EOF) return;
    ch = getchar();
  }
  while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
  x *= f;
  Finish_read = 1;
}
template <class T>
inline void print(T x) {
  if (x / 10 != 0) print(x / 10);
  putchar(x % 10 + '0');
}
template <class T>
inline void writeln(T x) {
  if (x < 0) putchar('-');
  x = abs(x);
  print(x);
  putchar('\n');
}
template <class T>
inline void write(T x) {
  if (x < 0) putchar('-');
  x = abs(x);
  print(x);
}
const int N = 2050;
const double eps = 1e-8;
int x[N], y[N], Del[N];
int n, tt, sumx, sumy, ans;
double A[N * N], heavx, heavy, tmp[N];
std::map<pair<int, int>, int> vis;
int cnt, T;
int Dcmp(double x) { return x < -eps ? -1 : x > eps; }
void check(double k) {
  int tnum = 0;
  double mid;
  for (int i = 1; i <= n; i++) tmp[++tnum] = (k * y[i] + x[i]) / (k * k + 1);
  sort(tmp + 1, tmp + tnum + 1);
  mid = (tmp[1] + tmp[tnum]) / 2;
  for (int i = 2; i <= (tnum + 1) / 2; i++)
    if (Dcmp(mid + mid - tmp[i] - tmp[tnum - i + 1]) != 0) return;
  ++ans;
  return;
}
void Delt() {
  for (int i = 1; i <= n; i++) {
    for (int j = i + 1; j <= n; j++) {
      if (Del[j]) continue;
      double Y = 1.0 * (y[i] + y[j]) / 2, X = 1.0 * (x[i] + x[j]) / 2;
      if (Dcmp(Y - heavy) == 0 && Dcmp(X - heavx) == 0) {
        Del[i] = Del[j] = 1;
        break;
      }
    }
  }
  cnt = 0;
  for (int i = 1; i <= n; i++) {
    if (!Del[i]) ++cnt, x[cnt] = x[i], y[cnt] = y[i];
  }
  n = cnt;
}
void Solve() {
  sort(A + 1, A + tt + 1);
  for (int L = 1, R; L <= tt;) {
    R = L;
    while (R + 1 <= tt && Dcmp(A[R + 1] - A[L]) == 0) ++R;
    if ((R - L + 1) >= n / 2) check(A[L]);
    L = R + 1;
  }
  int f = 1;
  sort(y + 1, y + n + 1);
  double mid = (y[1] + y[n]) / 2.0;
  for (int i = 2; i <= (n + 1) / 2; i++) {
    if (Dcmp(2.0 * mid - y[i] - y[n - i + 1]) != 0) {
      f = 0;
      break;
    }
  }
  if (f) ans++;
}
int main() {
  ans = 0, vis.clear(), tt = sumx = sumy = 0, cnt = 0;
  memset(Del, 0, sizeof Del);
  read(n);
  for (int i = 1, nx, ny; i <= n; i++) {
    read(nx), read(ny);
    if (!vis[pair<int, int>(nx, ny)]) {
      x[++cnt] = nx, y[cnt] = ny;
      vis[pair<int, int>(nx, ny)] = 1;
      sumx += nx, sumy += ny;
    }
  }
  n = cnt, heavx = 1.0 * sumx / n, heavy = 1.0 * sumy / n;
  Delt();
  if (n <= 2) return puts("-1"), 0;
  for (int i = 1; i <= n; i++) {
    for (int j = i + 1; j <= n; j++) {
      double Y = (y[i] + y[j]) / 2.0, X = (x[i] + x[j]) / 2.0;
      if (Dcmp(Y - heavy) == 0) continue;
      A[++tt] = 1.0 * (X - heavx) / (heavy - Y);
    }
  }
  Solve();
  printf("%d\n", ans);
}
