#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T>
using MaxHeap = priority_queue<T>;
template <class T>
using MinHeap = priority_queue<T, vector<T>, greater<T>>;
const double PI = 3.141592653589793238462643383279;
const ll MOD = 1e9 + 7;
const ll INF = 1LL << 55;
template <class T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
ll powmod(ll a, ll p, ll mod) {
  ll ans = 1;
  ll mul = a;
  for (; p > 0; p >>= 1, mul = (mul * mul) % mod) {
    if ((p & 1) == 1) ans = (ans * mul) % mod;
  }
  return ans;
}
signed main() {
  cin.sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  ll N;
  cin >> N;
  vector<ll> A(N);
  vector<ll> B(N);
  for (ll i = 0; i < N; i++) cin >> A[i] >> B[i];
  map<double, ll> m;
  for (ll i = 0; i < N; i++) {
    if (A[i] == 0 || B[i] == 0) {
      m[0]++;
    } else {
      m[1.0 * B[i] / A[i]]++;
    }
  }
  ll ret = 1;
  set<double> seen;
  for (auto it = m.begin(); it != m.end(); it++) {
    double value = it->first;
    ll count = it->second;
    if (seen.find(value) != seen.end()) continue;
    seen.insert(value);
    if (value == 0) {
      (ret *= count + 1) %= MOD;
    } else if (m.find(-1.0 / value) == m.end()) {
      (ret *= powmod(2, count, MOD)) %= MOD;
    } else {
      ll inv = m[-1.0 / value];
      seen.insert(-1.0 / value);
      (ret *= (powmod(2, inv, MOD) + powmod(2, count, MOD)) % MOD + MOD - 1) %=
          MOD;
    }
  }
  (ret += MOD - 1) %= MOD;
  cout << ret << endl;
  return 0;
}
