#include <bits/stdc++.h>
using namespace std;
const double EPS = 1e-8, PI = acos(-1.0);
int sign(double a) {
  if (fabs(a) < EPS) return 0;
  return a < 0 ? -1 : 1;
}
template <class T>
T mod(T a, T b) {
  return a - b * floor(a / b);
}
template <class T>
T sqr(T a) {
  return a * a;
}
template <class T>
T minus(T a) {
  return -a;
}
class point {
 private:
  friend ostream& operator<<(ostream&, const point&);
  friend istream& operator>>(istream&, point&);

 protected:
 public:
  vector<double> x;
  int size() const { return x.size(); }
  point();
  point(unsigned int);
  point(const vector<double>&);
  point(const point&);
  point(point&&);
  bool operator<(const point&) const;
  bool operator==(const point&) const;
  double operator%(const point&) const;
  double operator*(const point&) const;
  double& operator[](unsigned int);
  double operator[](unsigned int) const;
  point& operator=(point&&);
  point& operator=(const point&);
  point& operator+=(const point&);
  point operator+(const point&) const;
  point& operator-=(const point&);
  point operator-(const point&) const;
  point& operator*=(const double&);
  point operator*(const double&) const;
  friend point operator*(const double&, const point&);
  point& operator/=(const double&);
  point operator/(const double&) const;
  point operator^(const point&) const;
  void resize(unsigned int);
  friend double abs(point);
  friend double abs2(point);
};
ostream& operator<<(ostream& os, const point& P) {
  for (auto& i : P.x) {
    if (&i != &P.x.front()) os << " ";
    os << i;
  }
  return os;
}
istream& operator>>(istream& is, point& P) {
  for_each(P.x.begin(), P.x.end(), [&](double& v) { is >> v; });
  return is;
}
point::point() {}
point::point(unsigned int DIM) : x(DIM, 0) {}
point::point(const vector<double>& V) : x(V) {}
point::point(const point& P) : x(P.x) {}
point::point(point&& P) { x = move(P.x); }
void point::resize(unsigned int dim) { x.resize(dim); }
bool point::operator<(const point& P) const {
  assert(P.size() == size());
  for (int i = 0; i < size(); i++)
    if (fabs(x[i] - P.x[i]) > EPS) return x[i] < P.x[i];
  return false;
}
double& point::operator[](unsigned int i) {
  assert(i < size());
  return x[i];
}
double point::operator[](unsigned int i) const {
  assert(i < size());
  return x[i];
}
point& point::operator=(point&& that) {
  x = move(that.x);
  return *this;
}
point& point::operator=(const point& that) {
  x = that.x;
  return *this;
}
point& point::operator+=(const point& that) {
  assert(size() == that.size());
  for (int i = 0; i < size(); i++) {
    x[i] += that.x[i];
  }
  return *this;
}
point point::operator+(const point& that) const { return point(*this) += that; }
point& point::operator-=(const point& that) {
  assert(size() == that.size());
  for (int i = 0; i < size(); i++) {
    x[i] -= that.x[i];
  }
  return *this;
}
point point::operator-(const point& that) const { return point(*this) -= that; }
point& point::operator*=(const double& v) {
  for (auto& i : x) i *= v;
  return *this;
}
point point::operator*(const double& v) const { return point(*this) *= v; }
point operator*(const double& v, const point& P) { return point(P) *= v; }
point& point::operator/=(const double& v) {
  for (auto& i : x) i /= v;
  return *this;
}
point point::operator/(const double& v) const { return point(*this) /= v; }
double point::operator*(const point& that) const {
  assert(size() == that.size());
  double s = 0;
  for (int i = 0; i < size(); i++) s += x[i] * that.x[i];
  return s;
}
bool point::operator==(const point& that) const {
  return abs(*this - that) < EPS;
}
point point::operator^(const point& P) const {
  assert(P.size() == size() && size() == 3);
  return point({x[1] * P[2] - x[2] * P[1], x[2] * P[0] - x[0] * P[2],
                x[0] * P[1] - x[1] * P[0]});
}
double point::operator%(const point& P) const {
  assert(size() == P.size() && (size() == 3 || size() == 2));
  if (size() == 2) return x[0] * P[1] - x[1] * P[0];
  return abs(*this ^ P);
}
double abs(point p) { return sqrt(fabs(p * p)); }
double abs2(point p) { return fabs(p * p); }
double angle(point A, point B) { return atan2(A % B, A * B); }
point normalize(point P) {
  double m = abs(P);
  if (fabs(m) < EPS) {
    P = point(P.size());
  } else {
    P *= 1. / m;
    for (int i = 0; i < P.size(); i++)
      if (sign(P[i]) != 0) {
        P *= sign(P[i]);
        break;
      }
  }
  return P;
}
using namespace std;
const point zero(2);
point V[2010];
int N;
bool good(point& L) {
  map<long long, int> S;
  for (int i = 0; i < N; i++) {
    long long b, a = L * V[i];
    b = a * (-1.);
    if (S[b] > 0) {
      S[b]--;
    } else {
      S[a]++;
    }
  }
  S[0] = 0;
  int s = 0;
  for (auto p : S) s += p.second;
  return s == 0;
}
int main() {
  point com(zero);
  cin >> N;
  for (int i = 0; i < N; i++) {
    V[i] = zero;
    cin >> V[i];
    com += V[i];
  }
  com /= N;
  for (int i = 0; i < N; i++) V[i] -= com;
  for (int i = 0; i < N;) {
    bool ok = true;
    for (int j = i; j < N; j++)
      if ((V[i] + V[j]) == zero) {
        ok = false;
        if (i != j) {
          V[j] = V[--N];
        }
        V[i] = V[--N];
      }
    if (ok) break;
  }
  for (int i = 0; i < N; i++)
    if (V[i] == zero) V[i] = V[--N];
  if (N == 0) {
    cout << "-1\n";
    return 0;
  }
  set<point> ct;
  for (int i = 0; i < N; i++) {
    point d = V[i] + V[0];
    d = point({d[1], 0 - d[0]});
    if (good(d)) ct.insert(normalize(d));
  }
  cout << ct.size() << endl;
  return 0;
}

### Prompt

Your task is to create a CPP solution 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>
using namespace std;
const double EPS = 1e-8, PI = acos(-1.0);
int sign(double a) {
  if (fabs(a) < EPS) return 0;
  return a < 0 ? -1 : 1;
}
template <class T>
T mod(T a, T b) {
  return a - b * floor(a / b);
}
template <class T>
T sqr(T a) {
  return a * a;
}
template <class T>
T minus(T a) {
  return -a;
}
class point {
 private:
  friend ostream& operator<<(ostream&, const point&);
  friend istream& operator>>(istream&, point&);

 protected:
 public:
  vector<double> x;
  int size() const { return x.size(); }
  point();
  point(unsigned int);
  point(const vector<double>&);
  point(const point&);
  point(point&&);
  bool operator<(const point&) const;
  bool operator==(const point&) const;
  double operator%(const point&) const;
  double operator*(const point&) const;
  double& operator[](unsigned int);
  double operator[](unsigned int) const;
  point& operator=(point&&);
  point& operator=(const point&);
  point& operator+=(const point&);
  point operator+(const point&) const;
  point& operator-=(const point&);
  point operator-(const point&) const;
  point& operator*=(const double&);
  point operator*(const double&) const;
  friend point operator*(const double&, const point&);
  point& operator/=(const double&);
  point operator/(const double&) const;
  point operator^(const point&) const;
  void resize(unsigned int);
  friend double abs(point);
  friend double abs2(point);
};
ostream& operator<<(ostream& os, const point& P) {
  for (auto& i : P.x) {
    if (&i != &P.x.front()) os << " ";
    os << i;
  }
  return os;
}
istream& operator>>(istream& is, point& P) {
  for_each(P.x.begin(), P.x.end(), [&](double& v) { is >> v; });
  return is;
}
point::point() {}
point::point(unsigned int DIM) : x(DIM, 0) {}
point::point(const vector<double>& V) : x(V) {}
point::point(const point& P) : x(P.x) {}
point::point(point&& P) { x = move(P.x); }
void point::resize(unsigned int dim) { x.resize(dim); }
bool point::operator<(const point& P) const {
  assert(P.size() == size());
  for (int i = 0; i < size(); i++)
    if (fabs(x[i] - P.x[i]) > EPS) return x[i] < P.x[i];
  return false;
}
double& point::operator[](unsigned int i) {
  assert(i < size());
  return x[i];
}
double point::operator[](unsigned int i) const {
  assert(i < size());
  return x[i];
}
point& point::operator=(point&& that) {
  x = move(that.x);
  return *this;
}
point& point::operator=(const point& that) {
  x = that.x;
  return *this;
}
point& point::operator+=(const point& that) {
  assert(size() == that.size());
  for (int i = 0; i < size(); i++) {
    x[i] += that.x[i];
  }
  return *this;
}
point point::operator+(const point& that) const { return point(*this) += that; }
point& point::operator-=(const point& that) {
  assert(size() == that.size());
  for (int i = 0; i < size(); i++) {
    x[i] -= that.x[i];
  }
  return *this;
}
point point::operator-(const point& that) const { return point(*this) -= that; }
point& point::operator*=(const double& v) {
  for (auto& i : x) i *= v;
  return *this;
}
point point::operator*(const double& v) const { return point(*this) *= v; }
point operator*(const double& v, const point& P) { return point(P) *= v; }
point& point::operator/=(const double& v) {
  for (auto& i : x) i /= v;
  return *this;
}
point point::operator/(const double& v) const { return point(*this) /= v; }
double point::operator*(const point& that) const {
  assert(size() == that.size());
  double s = 0;
  for (int i = 0; i < size(); i++) s += x[i] * that.x[i];
  return s;
}
bool point::operator==(const point& that) const {
  return abs(*this - that) < EPS;
}
point point::operator^(const point& P) const {
  assert(P.size() == size() && size() == 3);
  return point({x[1] * P[2] - x[2] * P[1], x[2] * P[0] - x[0] * P[2],
                x[0] * P[1] - x[1] * P[0]});
}
double point::operator%(const point& P) const {
  assert(size() == P.size() && (size() == 3 || size() == 2));
  if (size() == 2) return x[0] * P[1] - x[1] * P[0];
  return abs(*this ^ P);
}
double abs(point p) { return sqrt(fabs(p * p)); }
double abs2(point p) { return fabs(p * p); }
double angle(point A, point B) { return atan2(A % B, A * B); }
point normalize(point P) {
  double m = abs(P);
  if (fabs(m) < EPS) {
    P = point(P.size());
  } else {
    P *= 1. / m;
    for (int i = 0; i < P.size(); i++)
      if (sign(P[i]) != 0) {
        P *= sign(P[i]);
        break;
      }
  }
  return P;
}
using namespace std;
const point zero(2);
point V[2010];
int N;
bool good(point& L) {
  map<long long, int> S;
  for (int i = 0; i < N; i++) {
    long long b, a = L * V[i];
    b = a * (-1.);
    if (S[b] > 0) {
      S[b]--;
    } else {
      S[a]++;
    }
  }
  S[0] = 0;
  int s = 0;
  for (auto p : S) s += p.second;
  return s == 0;
}
int main() {
  point com(zero);
  cin >> N;
  for (int i = 0; i < N; i++) {
    V[i] = zero;
    cin >> V[i];
    com += V[i];
  }
  com /= N;
  for (int i = 0; i < N; i++) V[i] -= com;
  for (int i = 0; i < N;) {
    bool ok = true;
    for (int j = i; j < N; j++)
      if ((V[i] + V[j]) == zero) {
        ok = false;
        if (i != j) {
          V[j] = V[--N];
        }
        V[i] = V[--N];
      }
    if (ok) break;
  }
  for (int i = 0; i < N; i++)
    if (V[i] == zero) V[i] = V[--N];
  if (N == 0) {
    cout << "-1\n";
    return 0;
  }
  set<point> ct;
  for (int i = 0; i < N; i++) {
    point d = V[i] + V[0];
    d = point({d[1], 0 - d[0]});
    if (good(d)) ct.insert(normalize(d));
  }
  cout << ct.size() << endl;
  return 0;
}

```