#include <bits/stdc++.h>
#pragma warning(disable : 6031)
int minimum(int a, int b) { return a < b ? a : b; }
int maximum(int a, int b) { return a > b ? a : b; }
const long long mod = 1000000007;
const double PI = 3.14159265358979323846;
using std::abs;
using std::map;
using std::pair;
using std::priority_queue;
using std::string;
using std::vector;
unsigned long long euclidean_gcd(unsigned long long a, unsigned long long b) {
  if (a < b) return euclidean_gcd(b, a);
  unsigned r;
  while ((r = a % b)) {
    a = b;
    b = r;
  }
  return b;
}
int main() {
  int N;
  scanf("%d", &N);
  auto A = new long long[N];
  auto B = new long long[N];
  for (int i = 0; i < N; i++) scanf("%lld %lld", A + i, B + i);
  map<pair<long long, long long>, int> m;
  map<pair<long long, long long>, int> mc;
  int num = N;
  int zero = 0;
  for (int i = 0; i < N; i++) {
    if (A[i] < 0) {
      A[i] *= -1;
      B[i] *= -1;
    }
    pair<long long, long long> p;
    if (B[i] == 0) {
      if (A[i] == 0) {
        zero = 1;
        continue;
      } else {
        p = pair<long long, long long>{1, 0};
      }
    } else if (A[i] == 0) {
      p = pair<long long, long long>{0, 1};
    } else {
      long long gcd = euclidean_gcd(A[i], B[i] < 0 ? B[i] * -1 : B[i]);
      A[i] /= gcd;
      B[i] /= gcd;
      p = pair<long long, long long>{A[i], B[i]};
    }
    if (m.count(p)) {
      m[p]++;
    } else {
      m[p] = 1;
    }
  }
  auto p2 = new long long[N + 1];
  p2[0] = 1;
  for (int i = 1; i < N + 1; i++) {
    p2[i] = (p2[i - 1] * 2) % mod;
  }
  long long res = 1;
  for (auto i = m.begin(); i != m.end(); ++i) {
    pair<long long, long long> p = i->first;
    pair<long long, long long> q =
        pair<long long, long long>{p.second, p.first * -1};
    if (q.first < 0) {
      q.first *= -1;
      q.second *= -1;
    }
    if (m.count(q)) {
      res = (res * (p2[m[p]] + p2[m[q]] - 1)) % mod;
      m.erase(q);
    } else {
      res = (res * p2[m[p]]) % mod;
    }
  }
  res += zero;
  printf("%lld", res - 1);
  return 0;
}
