#include <bits/stdc++.h>
using namespace std;
vector<pair<string, pair<int, int> > > vec;
const long long MAX_P = 200001;
const long long MOD = 1000000007;
bool is_prime(long long n) {
  for (long long i = 2; i * i <= n; i++) {
    if (n % i == 0) return false;
  }
  return n != 1;
}
vector<long long> divisor(long long n) {
  vector<long long> res;
  for (long long i = 1; i * i <= n; i++) {
    if (n % i == 0) {
      res.push_back(i);
      if (i != n / i) res.push_back(n / i);
    }
  }
  return res;
}
map<long long, long long> prime_factor(long long n) {
  map<long long, long long> res;
  for (long long i = 2; i * i <= n; i++) {
    while (n % i == 0) {
      ++res[i];
      n /= i;
    }
  }
  if (n != 1) res[n] = 1;
  return res;
}
long long extgcd(long long a, long long b, long long &x, long long &y) {
  long long d = a;
  if (b != 0) {
    d = extgcd(b, a % b, y, x);
    y -= (a / b) * x;
  } else {
    x = 1;
    y = 0;
  }
  return d;
}
long long mod_inverse(long long a, long long m) {
  long long x, y;
  extgcd(a, m, x, y);
  return (m + x % m) % m;
}
long long fact[MAX_P + 1];
void mod_fact(long long n, long long m) {
  fact[0] = 1;
  for (long long i = 1; i <= n; i++) fact[i] = fact[i - 1] * i % m;
}
long long mod_fact(long long n, long long p, long long &e) {
  e = 0;
  if (n == 0) return 1;
  long long res = mod_fact(n / p, p, e);
  e += n / p;
  if (n / p % 2 != 0) return res * (p - fact[n % p]) % p;
  return res * fact[n % p] % p;
}
long long mod_comb(long long n, long long k, long long p) {
  if (n < 0 || k < 0 || n < k) return 0;
  long long e1, e2, e3;
  long long a1 = mod_fact(n, p, e1), a2 = mod_fact(k, p, e2),
            a3 = mod_fact(n - k, p, e3);
  if (e1 > e2 + e3) return 0;
  return a1 * mod_inverse(a2 * a3 % p, p) % p;
}
long long modpow(long long x, long long y, long long m) {
  if (y == 0) return 1;
  long long res = modpow(x, y / 2, m);
  return res * res % m * (y & 1 ? x : 1) % m;
}
long long modpow(long long x, long long y) {
  if (y == 0) return 1;
  long long res = modpow(x, y / 2);
  return res * res % MOD * (y & 1 ? x : 1) % MOD;
}
void solve(long long N, std::vector<long long> A, std::vector<long long> B) {
  long long x, y;
  map<pair<int, int>, long long> m;
  for (long long i = 0; i < N; i++) {
    long long d = extgcd(A[i], B[i], x, y);
    long long a = A[i] / d, b = B[i] / d;
    if (a < 0) {
      a = -a;
      b = -b;
    }
    m[pair<int, int>(a, b)]++;
  }
  long long res = 1;
  long long n = N;
  map<pair<int, int>, bool> used;
  for (auto x : m) {
    long long a = x.first.first, b = x.first.second;
    long long n1 = m[pair<int, int>(a, b)], n2 = m[pair<int, int>(b, -a)];
    if (used[pair<int, int>(a, b)]) continue;
    used[pair<int, int>(a, b)] = true;
    if (b < 0) {
      n2 = m[pair<int, int>(-b, a)];
      used[pair<int, int>(-b, a)] = true;
    } else {
      used[pair<int, int>(b, -a)] = true;
    }
    if (n2 == 0)
      res = res * modpow(2, n1) % MOD;
    else {
      res = (res * (modpow(2, n1) + modpow(2, n2) - 1 + MOD) % MOD) % MOD;
    }
    m[pair<int, int>(a, b)] = 0;
    if (b < 0)
      m[pair<int, int>(-b, a)] = 0;
    else
      m[pair<int, int>(b, -a)] = 0;
    n -= n1 + n2;
  }
  res = (res - 1 + MOD) % MOD;
  cout << res << endl;
}
int main() {
  long long N;
  scanf("%lld", &N);
  std::vector<long long> A(N);
  std::vector<long long> B(N);
  for (int i = 0; i < N; i++) {
    scanf("%lld", &A[i]);
    scanf("%lld", &B[i]);
  }
  solve(N, std::move(A), std::move(B));
  return 0;
}
