#include <bits/stdc++.h>
using namespace std;
template <typename T>
T gcd(T a, T b) {
  return (b ? gcd(b, a % b) : a);
}
static const int64_t MOD = 1000000007;
int64_t modpow(int64_t base, int64_t k, int64_t mod) {
  base %= mod;
  int64_t answer = 1;
  while (k > 0) {
    if (k & 1) answer = (answer * base) % mod;
    base = (base * base) % mod;
    k >>= 1;
  }
  return answer;
}
int main() {
  int N;
  cin >> N;
  unordered_map<int64_t, unordered_map<int64_t, int64_t>> M;
  for (int i = 0; i < N; i++) {
    int64_t a, b;
    scanf("%ld %ld", &a, &b);
    int64_t g = gcd(a, b);
    a /= g;
    b /= g;
    if (a < 0) {
      a = -a;
      b = -b;
    } else if (a == 0) {
      if (b < 0) b = -b;
    }
    M[a][b]++;
  }
  int64_t answer = 1;
  unordered_map<int64_t, unordered_set<int64_t>> used;
  for (const auto& p : M) {
    int64_t A1 = p.first;
    for (const auto& p2 : M[A1]) {
      int64_t B1 = p2.first;
      int64_t C1 = p2.second;
      if (used[A1].count(B1)) continue;
      if (used[-A1].count(-B1)) continue;
      if (used[-B1].count(A1)) continue;
      if (used[B1].count(-A1)) continue;
      used[A1].insert(B1);
      used[-A1].insert(-B1);
      used[-B1].insert(A1);
      used[B1].insert(-A1);
      int64_t C2 = 0;
      if (M[-B1].find(A1) != M[-B1].end()) {
        C2 = M[-B1][A1];
      } else if (M[B1].find(-A1) != M[B1].end()) {
        C2 = M[B1][-A1];
      }
      int64_t K = modpow(2, C1, MOD);
      K = (K + modpow(2, C2, MOD)) % MOD;
      K = (K - 1 + MOD) % MOD;
      answer = (answer * K) % MOD;
    }
  }
  answer = (answer + MOD - 1) % MOD;
  cout << answer << endl;
  return 0;
}
