#include <bits/stdc++.h>
using namespace std;
const long mod = 1000000007;
long modbeki(long N) {
  long res = 1;
  for (long i = 0; i < N; i++) res = (res * 2) % mod;
  return res;
}
long gcd(long a, long b) {
  if (a < b) return gcd(b, a);
  long r = a % b;
  while (r) {
    a = b;
    b = r;
    r = a % b;
  }
  return b;
}
int main() {
  long N;
  cin >> N;
  map<pair<long, long>, pair<long, long> > data{};
  long num_origin = 0;
  for (long i = 0; i < N; ++i) {
    long A, B;
    cin >> A >> B;
    if (A * B == 0) {
      if (A == 0 && B == 0) {
        num_origin++;
      } else if (A == 0) {
        data[{0, 1}] = {data[{0, 1}].first + 1, data[{0, 1}].second};
      } else {
        data[{0, 1}] = {data[{0, 1}].first, data[{0, 1}].second + 1};
      }
    } else {
      if (A < 0) {
        A *= -1;
        B *= -1;
      }
      int is_positive = B > 0;
      if (B < 0) {
        long swap = A;
        A = -B;
        B = swap;
      }
      long G = gcd(A, B);
      A = A / G;
      B = B / G;
      if (!data.count({A, B})) data[{A, B}] = {0, 0};
      if (is_positive) {
        data[{A, B}] = {data[{A, B}].first + 1, data[{A, B}].second};
      } else {
        data[{A, B}] = {data[{A, B}].first, data[{A, B}].second + 1};
      }
    }
  }
  if (data.size() == 0) {
    cout << num_origin << endl;
    return 0;
  }
  long prod = 1;
  for (auto itr = data.begin(); itr != data.end(); ++itr) {
    pair<long, long> pos_neg = itr->second;
    long pos = pos_neg.first;
    long neg = pos_neg.second;
    long patterns = ((modbeki(pos) + modbeki(neg)) % mod + (mod - 1)) % mod;
    prod = (prod * patterns) % mod;
  }
  prod = prod - 1;
  cout << (num_origin + prod) % mod << endl;
  return 0;
}
