#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;
}
struct Hash {
  template <class T1, class T2>
  size_t operator()(const pair<T1, T2>& p) const {
    auto h1 = hash<T1>{}(p.first);
    auto h2 = hash<T2>{}(p.second);
    return h2 ^ h2;
  }
};
int main() {
  int N;
  cin >> N;
  unordered_map<pair<int64_t, int64_t>, int64_t, Hash> M;
  for (int i = 0; i < N; i++) {
    int64_t a, b;
    cin >> 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_set<pair<int64_t, int64_t>, Hash> used;
  for (const auto& p : M) {
    int64_t A1 = p.first.first;
    int64_t B1 = p.first.second;
    int64_t C1 = p.second;
    if (used.count({A1, B1})) continue;
    used.insert({A1, B1});
    used.insert({-A1, -B1});
    used.insert({-B1, A1});
    used.insert({B1, -A1});
    pair<int64_t, int64_t> d1{-B1, A1};
    pair<int64_t, int64_t> d2{B1, -A1};
    int64_t C2 = 0;
    if (M.find(d1) != M.end()) {
      C2 = M[d1];
    } else if (M.find(d2) != M.end()) {
      C2 = M[d2];
    }
    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;
}
