#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
using vl = vector<ll>;
using Map = map<P, ll>;
using T = tuple<ll, ll, ll>;
using vvl = vector<vector<ll>>;
template <typename T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <typename T>
bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
const ll INF = 1LL << 60;
const ll MOD = 1000000007;
ll gcd(ll a, ll b) {
  while (1) {
    if (a < b) swap(a, b);
    if (!b) break;
    a %= b;
  }
  return a;
}
P F(ll a, ll b) {
  if (a == 0 && b == 0) {
    return P(0, 0);
  }
  if (a == 0) return P(0, 1);
  if (b == 0) return P(1, 0);
  ll x = gcd(abs(a), abs(b));
  ll A = a / x;
  ll B = b / x;
  if (A < 0) {
    A *= -1;
    B *= -1;
  }
  return P(A, B);
}
long long modpow(long long a, long long n) {
  ll mod = MOD;
  long long res = 1;
  while (n > 0) {
    if (n & 1) res = res * a % mod;
    a = a * a % mod;
    n >>= 1;
  }
  return res;
}
int main() {
  ll N;
  cin >> N;
  vector<ll> A(N, 0);
  vector<ll> B(N, 0);
  for (ll i = 0; i < N; i++) cin >> A[i] >> B[i];
  Map G;
  for (ll i = 0; i < N; i++) {
    G[P(F(A[i], B[i]))]++;
  }
  ll ans = 1;
  for (auto p : G) {
    ll a = p.first.first;
    ll b = p.first.second;
    ll f = p.second;
    G[P(a, b)] = INF;
    if (f == INF) continue;
    G[P(a, b)] = 0;
    ll c;
    if (a == 0 && b == 0) {
      continue;
    } else if (a == 0) {
      c = G[P(1, 0)];
      G[P(1, 0)] = INF;
    } else if (b > 0) {
      c = G[P(b, -a)];
      G[P(b, -a)] = INF;
    } else if (b < 0) {
      c = G[P(-b, a)];
      G[P(-b, a)] = INF;
    } else if (b == 0) {
      c = G[P(0, 1)];
      G[P(0, 1)] = INF;
    }
    ans *= modpow(2, f) + modpow(2, c) - 1;
    ans %= MOD;
  }
  cout << (ans - 1 + MOD) % MOD << endl;
  ;
  return 0;
}
