#include <bits/stdc++.h>
using namespace std;
long long modinv(long long a, long long m) {
  long long b = m, u = 1, v = 0;
  while (b) {
    long long t = a / b;
    a -= t * b;
    swap(a, b);
    u -= t * v;
    swap(u, v);
  }
  u %= m;
  if (u < 0) u += m;
  return u % m;
}
long long gcd(long long x, long long y) {
  if (x < y) swap(x, y);
  while (x % y != 0) {
    long long divisor = x % y;
    x = y;
    y = divisor;
  }
  return y;
}
pair<long long, long long> getFrac(long long A, long long B) {
  pair<long long, long long> f;
  if (A == 0 && B == 0) {
    f.first = 0;
    f.second = 0;
  } else if (A == 0) {
    f.first = 0;
    f.second = 1;
  } else if (B == 0) {
    f.first = 1;
    f.second = 0;
  } else {
    long long g = gcd(abs(A), abs(B));
    A /= g;
    B /= g;
    f.first = abs(A);
    f.second = abs(B);
    if ((A > 0 && B < 0) || (A < 0 && B > 0)) {
      f.first *= -1;
    }
  }
  return f;
}
pair<long long, long long> getReversedFrac(pair<long long, long long> p) {
  pair<long long, long long> q;
  if (p.first == 0 && p.second == 0) {
    q.first = 0;
    q.second = 0;
  } else if (p.first == 0) {
    q.first = 1;
    q.second = 0;
  } else if (p.second == 0) {
    q.first = 0;
    q.second = 1;
  } else {
    q.first = abs(p.second) * (p.first < 0 ? 1 : -1);
    q.second = abs(p.first);
  }
  return q;
}
int main() {
  int N;
  cin >> N;
  vector<long long> A(N), B(N);
  for (int i = 0; i < (N); ++i) cin >> A[i] >> B[i];
  map<pair<long long, long long>, int> pairs;
  int all_zero = 0;
  for (int i = 0; i < (N); ++i) {
    if (A[i] == 0 && B[i] == 0)
      all_zero++;
    else {
      pair<long long, long long> p = getFrac(A[i], B[i]);
      decltype(pairs)::iterator it = pairs.find(p);
      if (it != pairs.end()) {
        pairs[p]++;
      } else {
        pairs.insert(make_pair(p, 1));
      }
    }
  }
  long long ans = 1;
  vector<long long> doubles(N + 1, 1);
  for (int i = 1; i <= N; i++) {
    doubles[i] = doubles[i - 1] * 2;
    doubles[i] %= 1000000007;
  }
  set<pair<long long, long long> > checkedSet;
  for (decltype(pairs)::iterator it = pairs.begin(); it != pairs.end();
       it = next(it, 1)) {
    long long c = 1;
    pair<long long, long long> p = it->first;
    int count_p = it->second;
    if (checkedSet.find(p) != checkedSet.end()) continue;
    c += doubles[count_p] - 1 + 1000000007;
    c %= 1000000007;
    pair<long long, long long> q = getReversedFrac(p);
    decltype(pairs)::iterator itq = pairs.find(q);
    if (itq != pairs.end() && checkedSet.find(q) == checkedSet.end()) {
      int count_q = itq->second;
      c += doubles[count_q] - 1 + 1000000007;
      c %= 1000000007;
      checkedSet.insert(q);
    }
    checkedSet.insert(p);
    ans *= c;
    ans %= 1000000007;
  }
  ans += all_zero;
  ans %= 1000000007;
  cout << ans - 1 << endl;
  return 0;
}
