#include <bits/stdc++.h>
using namespace std;
template <typename T1, typename T2>
string print_iterable(T1 begin_iter, T2 end_iter, int counter) {
  bool done_something = false;
  stringstream res;
  res << "[";
  for (; begin_iter != end_iter and counter; ++begin_iter) {
    done_something = true;
    counter--;
    res << *begin_iter << ", ";
  }
  string str = res.str();
  if (done_something) {
    str.pop_back();
    str.pop_back();
  }
  str += "]";
  return str;
}
vector<int> SortIndex(int size, std::function<bool(int, int)> compare) {
  vector<int> ord(size);
  for (int i = 0; i < size; i++) ord[i] = i;
  sort(ord.begin(), ord.end(), compare);
  return ord;
}
template <typename T>
bool MinPlace(T& a, const T& b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T>
bool MaxPlace(T& a, const T& b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename Container>
int SZ(const Container& S) {
  return S.size();
}
template <typename S, typename T>
ostream& operator<<(ostream& out, const pair<S, T>& p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}
template <typename T>
ostream& operator<<(ostream& out, const vector<T>& v) {
  out << "[";
  for (int i = 0; i < (int)v.size(); i++) {
    out << v[i];
    if (i != (int)v.size() - 1) out << ", ";
  }
  out << "]";
  return out;
}
const int MAXN = -1;
struct Point {
  long long x, y;
  Point() : x(0), y(0) {}
  Point(long long x, long long y) : x(x), y(y) {}
  Point operator+(const Point& other) const {
    return {x + other.x, y + other.y};
  };
  Point operator-(const Point& other) const {
    return {x - other.x, y - other.y};
  };
  Point operator*(long long lambda) const { return {x * lambda, y * lambda}; };
  long long operator*(const Point& other) const {
    return x * other.x + y * other.y;
  }
  bool operator<(const Point& other) const { return x * other.y > y * other.x; }
};
Point Rotate90(const Point& P) { return {-P.y, P.x}; }
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int N;
  cin >> N;
  Point O;
  vector<Point> P(N);
  for (int i = 0; i < N; i++) {
    cin >> P[i].x >> P[i].y;
    O = O + P[i];
  }
  vector<bool> removed(N, false);
  vector<set<Point>> good_lines(N);
  for (int i = 0; i < N; i++) {
    if (removed[i]) continue;
    for (int j = 0; j < N; j++) {
      if (removed[j]) continue;
      Point Q = ((P[i] + P[j]) * N) - (O * 2);
      if (Q.x == 0 and Q.y == 0) {
        removed[i] = true;
        removed[j] = true;
        break;
      }
      Q = Rotate90(Q);
      if (Q.y < 0 || (Q.y == 0 and Q.x < 0)) Q = Q * (-1);
      good_lines[i].insert(Q);
    }
  }
  vector<int> not_removed;
  for (int i = 0; i < N; i++) {
    if (!removed[i]) not_removed.push_back(i);
  }
  if (not_removed.empty()) {
    cout << "-1"
         << "\n";
    return 0;
  }
  int M = not_removed.size();
  set<Point> perfect_lines = good_lines[not_removed[0]];
  int res = 0;
  for (const Point& line : perfect_lines) {
    vector<long long> scal(M);
    for (int i = 0; i < M; i++) scal[i] = P[not_removed[i]] * line;
    sort(scal.begin(), scal.end());
    long long center = scal.back() + scal[0];
    bool works = true;
    for (int i = 0; i <= M - 1 - i; i++) {
      if (scal[i] + scal[M - 1 - i] != center) {
        works = false;
        break;
      }
    }
    if (works) res++;
  }
  cout << res << "\n";
}

### Prompt

Create a solution in cpp for 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;
template <typename T1, typename T2>
string print_iterable(T1 begin_iter, T2 end_iter, int counter) {
  bool done_something = false;
  stringstream res;
  res << "[";
  for (; begin_iter != end_iter and counter; ++begin_iter) {
    done_something = true;
    counter--;
    res << *begin_iter << ", ";
  }
  string str = res.str();
  if (done_something) {
    str.pop_back();
    str.pop_back();
  }
  str += "]";
  return str;
}
vector<int> SortIndex(int size, std::function<bool(int, int)> compare) {
  vector<int> ord(size);
  for (int i = 0; i < size; i++) ord[i] = i;
  sort(ord.begin(), ord.end(), compare);
  return ord;
}
template <typename T>
bool MinPlace(T& a, const T& b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T>
bool MaxPlace(T& a, const T& b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename Container>
int SZ(const Container& S) {
  return S.size();
}
template <typename S, typename T>
ostream& operator<<(ostream& out, const pair<S, T>& p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}
template <typename T>
ostream& operator<<(ostream& out, const vector<T>& v) {
  out << "[";
  for (int i = 0; i < (int)v.size(); i++) {
    out << v[i];
    if (i != (int)v.size() - 1) out << ", ";
  }
  out << "]";
  return out;
}
const int MAXN = -1;
struct Point {
  long long x, y;
  Point() : x(0), y(0) {}
  Point(long long x, long long y) : x(x), y(y) {}
  Point operator+(const Point& other) const {
    return {x + other.x, y + other.y};
  };
  Point operator-(const Point& other) const {
    return {x - other.x, y - other.y};
  };
  Point operator*(long long lambda) const { return {x * lambda, y * lambda}; };
  long long operator*(const Point& other) const {
    return x * other.x + y * other.y;
  }
  bool operator<(const Point& other) const { return x * other.y > y * other.x; }
};
Point Rotate90(const Point& P) { return {-P.y, P.x}; }
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int N;
  cin >> N;
  Point O;
  vector<Point> P(N);
  for (int i = 0; i < N; i++) {
    cin >> P[i].x >> P[i].y;
    O = O + P[i];
  }
  vector<bool> removed(N, false);
  vector<set<Point>> good_lines(N);
  for (int i = 0; i < N; i++) {
    if (removed[i]) continue;
    for (int j = 0; j < N; j++) {
      if (removed[j]) continue;
      Point Q = ((P[i] + P[j]) * N) - (O * 2);
      if (Q.x == 0 and Q.y == 0) {
        removed[i] = true;
        removed[j] = true;
        break;
      }
      Q = Rotate90(Q);
      if (Q.y < 0 || (Q.y == 0 and Q.x < 0)) Q = Q * (-1);
      good_lines[i].insert(Q);
    }
  }
  vector<int> not_removed;
  for (int i = 0; i < N; i++) {
    if (!removed[i]) not_removed.push_back(i);
  }
  if (not_removed.empty()) {
    cout << "-1"
         << "\n";
    return 0;
  }
  int M = not_removed.size();
  set<Point> perfect_lines = good_lines[not_removed[0]];
  int res = 0;
  for (const Point& line : perfect_lines) {
    vector<long long> scal(M);
    for (int i = 0; i < M; i++) scal[i] = P[not_removed[i]] * line;
    sort(scal.begin(), scal.end());
    long long center = scal.back() + scal[0];
    bool works = true;
    for (int i = 0; i <= M - 1 - i; i++) {
      if (scal[i] + scal[M - 1 - i] != center) {
        works = false;
        break;
      }
    }
    if (works) res++;
  }
  cout << res << "\n";
}

```