#include <bits/stdc++.h>
using namespace std;
vector<long long> fac(200005);
vector<long long> ifac(200005);
long long mpow(long long x, long long n) {
  long long ans = 1;
  while (n != 0) {
    if (n & 1) ans = ans * x % 1000000007;
    x = x * x % 1000000007;
    n = n >> 1;
  }
  return ans;
}
void init_comb() {
  fac[0] = 1;
  ifac[0] = 1;
  for (long long i = 1; i < 200005; i++) {
    fac[i] = fac[i - 1] * i % 1000000007;
    ifac[i] = ifac[i - 1] * mpow(i, 1000000007 - 2) % 1000000007;
  }
}
long long combination(long long n, long long m) {
  if (m == n || m == 0) return 1;
  long long tmp = fac[n] * ifac[m] % 1000000007;
  return tmp * ifac[n - m] % 1000000007;
}
long long mdev(long long a, long long b) {
  return a * mpow(b, 1000000007 - 2) % 1000000007;
}
long long msub(long long a, long long b) {
  if (a < b) a += 1000000007;
  return msub(a, b);
}
long long sum_comb(int n) {
  long long sum = 0;
  for (int i = 0; i < (int)(n + 1); i++) {
    sum = (sum + combination(n, i)) % 1000000007;
  }
  return sum;
}
pair<long long, long long> sdn[200005];
int main() {
  init_comb();
  int n;
  cin >> n;
  map<double, int> s;
  vector<double> keys;
  int cnt = 0;
  for (int i = 0; i < (int)(n); i++) {
    long long a, b;
    cin >> a >> b;
    double a_b = a / (double)b;
    if (!(s.find(a_b) != s.end())) {
      keys.push_back(a_b);
    }
    s[a_b]++;
  }
  int free_n = 0;
  vector<pair<long long, long long> > twin;
  for (int i = 0; i < (int)(keys.size()); i++) {
    if ((s.find(-1 / keys[i]) != s.end())) {
      if (s[-1 / keys[i]] > 0) {
        twin.push_back(pair<long long, long long>(s[keys[i]], s[-1 / keys[i]]));
        s[-1 / keys[i]] = 0;
        s[keys[i]] = 0;
      }
    } else {
      free_n++;
    }
  }
  long long ans = sum_comb(free_n);
  for (int i = 0; i < (int)(twin.size()); i++) {
    int a = twin[i].first, b = twin[i].second;
    long long twin_comb = (sum_comb(a) + sum_comb(b) - 1) % 1000000007;
    ans = (ans * twin_comb) % 1000000007;
  }
  cout << ans - 1 << endl;
  return 0;
}
