#include <bits/stdc++.h>
using namespace std;
const int NN = 2000 + 17;
const int inf = 1000000000;
int read() {
  int x;
  scanf("%d", &x);
  return x;
}
void open() {
  freopen("life.in", "r", stdin);
  freopen("life.out", "w", stdout);
}
void close() {
  fclose(stdin);
  fclose(stdout);
}
struct Vec {
  long long x, y;
  Vec(long long x_ = 0, long long y_ = 0) { x = x_, y = y_; }
} a[NN] = {}, cent;
Vec vv(Vec a, Vec b) { return (b.x - a.x, b.y - a.y); }
long long gcd(long long a, long long b) {
  if (a < 0) a = -a;
  if (b < 0) b = -b;
  if (!b) return a;
  while (b ^= a ^= b ^= a %= b)
    ;
  return a;
}
long long tp[NN] = {};
int n;
long long check(long long aa, long long bb) {
  for (int i = 1; i <= n; ++i) {
    tp[i] = a[i].x * aa + a[i].y * bb;
  }
  sort(tp + 1, tp + 1 + n);
  long long res = tp[1] + tp[n];
  for (int i = 2; i <= (n + 1) / 2; ++i) {
    if (res != tp[i] + tp[n + 1 - i]) return 0;
  }
  return 1;
}
bool cmp(Vec a, Vec b) { return a.x < b.x; }
bool del[NN] = {};
map<pair<int, int>, bool> mp;
void solve() {
  n = read();
  cent.x = 0;
  cent.y = 0;
  mp.clear();
  memset(del, 0, sizeof del);
  for (int i = 1; i <= n; ++i) {
    a[i].x = read() * 2 * n;
    a[i].y = read() * 2 * n;
    cent.x += a[i].x;
    cent.y += a[i].y;
  }
  cent.x /= n;
  cent.y /= n;
  int ans = 0;
  int kcnt = 0;
  for (int i = 1; i <= n; ++i) {
    if (cent.x == a[i].x && cent.y == a[i].y) del[i] = 1;
  }
  for (int i = 1; i <= n; ++i) {
    if (del[i]) continue;
    for (int j = i + 1; j <= n; ++j) {
      if (!del[j] && a[i].x + a[j].x == cent.x * 2 &&
          a[i].y + a[j].y == cent.y * 2) {
        del[j] = 1;
        del[i] = 1;
        break;
      }
    }
  }
  int okcnt = 0;
  for (int i = 1; i <= n; ++i) {
    if (!del[i]) ++okcnt;
  }
  if (okcnt < 2) {
    printf("-1\n");
    return;
  }
  int st = 1;
  for (; del[st]; ++st)
    ;
  for (int i = st; i <= n; ++i) {
    if (del[i]) continue;
    long long x = (a[i].x + a[st].x) / 2;
    long long y = (a[i].y + a[st].y) / 2;
    x = cent.x - x;
    y = cent.y - y;
    if (!x && !y) continue;
    swap(x, y);
    x = -x;
    long long g = gcd(x, y);
    x /= g;
    y /= g;
    if (x < 0) {
      x = -x;
      y = -y;
    }
    if (x == 0) {
      if (y < 0) y = -y;
    }
    if (mp[make_pair(x, y)]) {
      continue;
    } else {
      mp[make_pair(x, y)] = 1;
      ans += check(x, y);
    }
  }
  printf("%d\n", ans);
}
int main() {
  solve();
  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 int NN = 2000 + 17;
const int inf = 1000000000;
int read() {
  int x;
  scanf("%d", &x);
  return x;
}
void open() {
  freopen("life.in", "r", stdin);
  freopen("life.out", "w", stdout);
}
void close() {
  fclose(stdin);
  fclose(stdout);
}
struct Vec {
  long long x, y;
  Vec(long long x_ = 0, long long y_ = 0) { x = x_, y = y_; }
} a[NN] = {}, cent;
Vec vv(Vec a, Vec b) { return (b.x - a.x, b.y - a.y); }
long long gcd(long long a, long long b) {
  if (a < 0) a = -a;
  if (b < 0) b = -b;
  if (!b) return a;
  while (b ^= a ^= b ^= a %= b)
    ;
  return a;
}
long long tp[NN] = {};
int n;
long long check(long long aa, long long bb) {
  for (int i = 1; i <= n; ++i) {
    tp[i] = a[i].x * aa + a[i].y * bb;
  }
  sort(tp + 1, tp + 1 + n);
  long long res = tp[1] + tp[n];
  for (int i = 2; i <= (n + 1) / 2; ++i) {
    if (res != tp[i] + tp[n + 1 - i]) return 0;
  }
  return 1;
}
bool cmp(Vec a, Vec b) { return a.x < b.x; }
bool del[NN] = {};
map<pair<int, int>, bool> mp;
void solve() {
  n = read();
  cent.x = 0;
  cent.y = 0;
  mp.clear();
  memset(del, 0, sizeof del);
  for (int i = 1; i <= n; ++i) {
    a[i].x = read() * 2 * n;
    a[i].y = read() * 2 * n;
    cent.x += a[i].x;
    cent.y += a[i].y;
  }
  cent.x /= n;
  cent.y /= n;
  int ans = 0;
  int kcnt = 0;
  for (int i = 1; i <= n; ++i) {
    if (cent.x == a[i].x && cent.y == a[i].y) del[i] = 1;
  }
  for (int i = 1; i <= n; ++i) {
    if (del[i]) continue;
    for (int j = i + 1; j <= n; ++j) {
      if (!del[j] && a[i].x + a[j].x == cent.x * 2 &&
          a[i].y + a[j].y == cent.y * 2) {
        del[j] = 1;
        del[i] = 1;
        break;
      }
    }
  }
  int okcnt = 0;
  for (int i = 1; i <= n; ++i) {
    if (!del[i]) ++okcnt;
  }
  if (okcnt < 2) {
    printf("-1\n");
    return;
  }
  int st = 1;
  for (; del[st]; ++st)
    ;
  for (int i = st; i <= n; ++i) {
    if (del[i]) continue;
    long long x = (a[i].x + a[st].x) / 2;
    long long y = (a[i].y + a[st].y) / 2;
    x = cent.x - x;
    y = cent.y - y;
    if (!x && !y) continue;
    swap(x, y);
    x = -x;
    long long g = gcd(x, y);
    x /= g;
    y /= g;
    if (x < 0) {
      x = -x;
      y = -y;
    }
    if (x == 0) {
      if (y < 0) y = -y;
    }
    if (mp[make_pair(x, y)]) {
      continue;
    } else {
      mp[make_pair(x, y)] = 1;
      ans += check(x, y);
    }
  }
  printf("%d\n", ans);
}
int main() {
  solve();
  return 0;
}

```