#include <bits/stdc++.h>
using namespace std;
using ll = long long int;
using vec = vector<int>;
using P = pair<int, int>;
const int mod = 1000000007;
struct mint {
  ll x;
  mint(ll x = 0) : x((x % mod + mod) % mod) {}
  mint operator-() const { return mint(-x); }
  mint& operator+=(const mint a) {
    if ((x += a.x) >= mod) x -= mod;
    return *this;
  }
  mint& operator-=(const mint a) {
    if ((x += mod - a.x) >= mod) x -= mod;
    return *this;
  }
  mint& operator*=(const mint a) {
    (x *= a.x) %= mod;
    return *this;
  }
  mint operator+(const mint a) const { return mint(*this) += a; }
  mint operator-(const mint a) const { return mint(*this) -= a; }
  mint operator*(const mint a) const { return mint(*this) *= a; }
  mint pow(ll t) const {
    if (!t) return 1;
    mint a = pow(t >> 1);
    a *= a;
    if (t & 1) a *= *this;
    return a;
  }
  mint inv() const { return pow(mod - 2); }
  mint& operator/=(const mint a) { return *this *= a.inv(); }
  mint operator/(const mint a) const { return mint(*this) /= a; }
};
istream& operator>>(istream& is, const mint& a) { return is >> a.x; }
ostream& operator<<(ostream& os, const mint& a) { return os << a.x; }
const int MAX_N = 200006;
struct combination {
  vector<mint> fact, ifact;
  combination(int n) : fact(n + 1), ifact(n + 1) {
    assert(n < mod);
    fact[0] = 1;
    for (int i = 1; i <= n; ++i) fact[i] = fact[i - 1] * i;
    ifact[n] = fact[n].inv();
    for (int i = n; i >= 1; --i) ifact[i - 1] = ifact[i] * i;
  }
  mint operator()(int n, int k) {
    if (k < 0 || k > n) return 0;
    return fact[n] * ifact[k] * ifact[n - k];
  }
} c(MAX_N);
ll gcd(ll a, ll b) {
  if (b == 0) return a;
  return gcd(b, a % b);
}
int main() {
  int n;
  cin >> n;
  vector<P> v(0);
  int az = 0, bz = 0, cz = 0;
  for (int i = 0; i < (n); ++i) {
    ll a, b;
    cin >> a >> b;
    if (a == 0 && b == 0) {
      cz++;
    } else if (a == 0) {
      az++;
    } else if (b == 0) {
      bz++;
    } else {
      int sign = 1;
      if (a < 0 && b > 0) {
        a = -a;
        sign = -1;
      } else if (a > 0 && b < 0) {
        b = -b;
        sign = -1;
      }
      ll g = gcd(max(a, b), min(a, b));
      v.push_back(P(sign * a / g, b / g));
    }
  }
  sort((v).begin(), (v).end());
  ll now = v[0].first;
  vector<P> s(0);
  int i = 0;
  int n_v = v.size();
  int t = n_v;
  while (i < n_v) {
    P p = v[i];
    ll a = p.first, b = p.second;
    P p2 = P(b, -a);
    int cnt2 = upper_bound((v).begin(), (v).end(), p2) -
               lower_bound((v).begin(), (v).end(), p2);
    int cnt = upper_bound((v).begin(), (v).end(), p) -
              lower_bound((v).begin(), (v).end(), p);
    if (a < 0 && cnt2 > 0) {
      s.push_back(P(cnt2, cnt));
      t -= cnt + cnt2;
    }
    i += cnt;
  }
  if (az > 0 && bz > 0) t -= az + bz;
  t -= cz;
  mint pro = 0;
  for (int j = 0; j < (t + 1); ++j) {
    pro += c(t, j);
  }
  for (P p : s) {
    mint sum = -1;
    ll a = p.first, b = p.second;
    for (int j = 0; j < (a + 1); ++j) {
      sum += c(a, j);
    }
    for (int j = 0; j < (b + 1); ++j) {
      sum += c(b, j);
    }
    pro *= sum;
  }
  if (az > 0 && bz > 0) {
    mint sum0 = -1;
    for (int j = 0; j < (az + 1); ++j) {
      sum0 += c(az, j);
    }
    for (int j = 0; j < (bz + 1); ++j) {
      sum0 += c(bz, j);
    }
    pro *= sum0;
  }
  cout << pro - 1 << endl;
}
