#include <bits/stdc++.h>
const int MAXN = 2010;
struct vec {
  int x, y;
  vec() { x = y = 0; }
  vec(int a, int b) { x = a, y = b; }
  long long operator^(vec b) const {
    return (long long)x * b.y - (long long)y * b.x;
  }
  long long operator*(vec b) const {
    return (long long)x * b.x + (long long)y * b.y;
  }
  vec operator-(vec b) const { return vec(x - b.x, y - b.y); }
  vec operator+(vec b) const { return vec(x + b.x, y + b.y); }
  vec operator*(int k) const { return vec(x * k, y * k); }
  friend std::istream& operator>>(std::istream& in, vec& x) {
    in >> x.x >> x.y;
    return in;
  }
  friend std::ostream& operator<<(std::ostream& out, vec x) {
    out << '(' << x.x << ',' << x.y << ')';
    return out;
  }
  friend bool operator<(vec a, vec b) { return (a ^ b) > 0; }
  bool iszero() { return x == 0 && y == 0; }
} ps[MAXN], pt[MAXN];
std::vector<std::pair<vec, vec> > V;
int n;
vec red(vec x) {
  std::swap(x.x, x.y);
  x.x = -x.x;
  if (x.x < 0) x = x * -1;
  if (x.x == 0 && x.y != 0) x.y = -1;
  return x;
}
int rnk[MAXN];
int li[MAXN * MAXN], bak;
void swap(vec x) {
  ++rnk[x.x], --rnk[x.y];
  li[++bak] = x.x;
  li[++bak] = x.y;
}
void bye() {
  std::cout << -1 << std::endl;
  exit(0);
}
std::set<vec> S;
vec val[MAXN];
void upd(int l) {
  if (l < 1 || l > n) return;
  int r = n - l + 1;
  if (l > r) std::swap(l, r);
  if (r - l < 2) return;
  vec lhs = pt[l + 1] - pt[l];
  vec rhs = pt[r] - pt[r - 1];
  val[l] = lhs - rhs;
}
void push() {
  std::sort(li + 1, li + 1 + bak);
  bak = std::unique(li + 1, li + 1 + bak) - li - 1;
  for (int i = 1; i <= bak; ++i) {
    pt[rnk[li[i]]] = ps[li[i]];
  }
  for (int i = 1; i <= bak; ++i)
    for (int j = -1; j <= 1; ++j) upd(rnk[li[i]] + j);
  bak = 0;
}
int main() {
  std::ios_base::sync_with_stdio(false), std::cin.tie(0);
  std::cin >> n;
  for (int i = 1; i <= n; ++i) std::cin >> ps[i];
  auto cmp = [](vec a, vec b) { return a.y == b.y ? a.x < b.x : a.y > b.y; };
  std::sort(ps + 1, ps + 1 + n, cmp);
  for (int i = 1; i <= n; ++i) rnk[i] = i, li[++bak] = i;
  for (int i = 1; i <= n; ++i)
    for (int j = i + 1; j <= n; ++j) {
      vec t = red(ps[j] - ps[i]);
      if (t.iszero() || t.x == 0) continue;
      V.emplace_back(t, vec(i, j));
    }
  std::sort(V.begin(), V.end());
  V.emplace_back(vec(0, 1), vec(0, 0));
  vec lst(0, -1);
  const int sz = V.size();
  for (int i = 0; i < sz;) {
    vec spe = V[i].first;
    push();
    {
      vec ch(0, 0);
      bool can = true;
      for (int l = 1, r = n; r - l >= 2; ++l, --r) {
        vec lhs = pt[l + 1] - pt[l];
        vec rhs = pt[r] - pt[r - 1];
        vec sl = lhs - rhs;
        if (ch.iszero())
          ch = sl;
        else {
          if ((ch ^ sl) != 0) {
            can = false;
            break;
          }
        }
      }
      if (can) {
        if (ch.iszero()) bye();
        ch = red(ch);
        if (!(ch < lst) && ch < spe) {
          S.insert(ch);
        }
      }
    }
    while (i < sz && (V[i].first ^ spe) == 0) swap(V[i++].second);
    lst = spe;
  }
  std::cout << S.size() << std::endl;
  return 0;
}

### Prompt

Please create a solution in Cpp 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>
const int MAXN = 2010;
struct vec {
  int x, y;
  vec() { x = y = 0; }
  vec(int a, int b) { x = a, y = b; }
  long long operator^(vec b) const {
    return (long long)x * b.y - (long long)y * b.x;
  }
  long long operator*(vec b) const {
    return (long long)x * b.x + (long long)y * b.y;
  }
  vec operator-(vec b) const { return vec(x - b.x, y - b.y); }
  vec operator+(vec b) const { return vec(x + b.x, y + b.y); }
  vec operator*(int k) const { return vec(x * k, y * k); }
  friend std::istream& operator>>(std::istream& in, vec& x) {
    in >> x.x >> x.y;
    return in;
  }
  friend std::ostream& operator<<(std::ostream& out, vec x) {
    out << '(' << x.x << ',' << x.y << ')';
    return out;
  }
  friend bool operator<(vec a, vec b) { return (a ^ b) > 0; }
  bool iszero() { return x == 0 && y == 0; }
} ps[MAXN], pt[MAXN];
std::vector<std::pair<vec, vec> > V;
int n;
vec red(vec x) {
  std::swap(x.x, x.y);
  x.x = -x.x;
  if (x.x < 0) x = x * -1;
  if (x.x == 0 && x.y != 0) x.y = -1;
  return x;
}
int rnk[MAXN];
int li[MAXN * MAXN], bak;
void swap(vec x) {
  ++rnk[x.x], --rnk[x.y];
  li[++bak] = x.x;
  li[++bak] = x.y;
}
void bye() {
  std::cout << -1 << std::endl;
  exit(0);
}
std::set<vec> S;
vec val[MAXN];
void upd(int l) {
  if (l < 1 || l > n) return;
  int r = n - l + 1;
  if (l > r) std::swap(l, r);
  if (r - l < 2) return;
  vec lhs = pt[l + 1] - pt[l];
  vec rhs = pt[r] - pt[r - 1];
  val[l] = lhs - rhs;
}
void push() {
  std::sort(li + 1, li + 1 + bak);
  bak = std::unique(li + 1, li + 1 + bak) - li - 1;
  for (int i = 1; i <= bak; ++i) {
    pt[rnk[li[i]]] = ps[li[i]];
  }
  for (int i = 1; i <= bak; ++i)
    for (int j = -1; j <= 1; ++j) upd(rnk[li[i]] + j);
  bak = 0;
}
int main() {
  std::ios_base::sync_with_stdio(false), std::cin.tie(0);
  std::cin >> n;
  for (int i = 1; i <= n; ++i) std::cin >> ps[i];
  auto cmp = [](vec a, vec b) { return a.y == b.y ? a.x < b.x : a.y > b.y; };
  std::sort(ps + 1, ps + 1 + n, cmp);
  for (int i = 1; i <= n; ++i) rnk[i] = i, li[++bak] = i;
  for (int i = 1; i <= n; ++i)
    for (int j = i + 1; j <= n; ++j) {
      vec t = red(ps[j] - ps[i]);
      if (t.iszero() || t.x == 0) continue;
      V.emplace_back(t, vec(i, j));
    }
  std::sort(V.begin(), V.end());
  V.emplace_back(vec(0, 1), vec(0, 0));
  vec lst(0, -1);
  const int sz = V.size();
  for (int i = 0; i < sz;) {
    vec spe = V[i].first;
    push();
    {
      vec ch(0, 0);
      bool can = true;
      for (int l = 1, r = n; r - l >= 2; ++l, --r) {
        vec lhs = pt[l + 1] - pt[l];
        vec rhs = pt[r] - pt[r - 1];
        vec sl = lhs - rhs;
        if (ch.iszero())
          ch = sl;
        else {
          if ((ch ^ sl) != 0) {
            can = false;
            break;
          }
        }
      }
      if (can) {
        if (ch.iszero()) bye();
        ch = red(ch);
        if (!(ch < lst) && ch < spe) {
          S.insert(ch);
        }
      }
    }
    while (i < sz && (V[i].first ^ spe) == 0) swap(V[i++].second);
    lst = spe;
  }
  std::cout << S.size() << std::endl;
  return 0;
}

```