#include <bits/stdc++.h>
using namespace std;
long long int mod = 1e9 + 7;
long long int power[200009];
long long int gcd(long long int x, long long int y) {
  if (y == 0) return x;
  return gcd(y, x % y);
}
struct frac {
  long long int n, d;
};
bool operator<(const frac &f1, const frac &f2) {
  return (double)f1.n / f1.d < (double)f2.n / f2.d;
}
frac reduce(frac f) {
  if (f.d < 0) {
    f.n = -1 * f.n;
    f.d = -1 * f.d;
  }
  if (f.n == 0 and f.d != 0) return {0, 1};
  if (f.d == 0 and f.n != 0) return {-1, 0};
  return {f.n / gcd(abs(f.n), abs(f.d)), f.d / gcd(abs(f.n), abs(f.d))};
}
frac perp(frac f) {
  if (f.n >= 0) return {-f.d, f.n};
  return {f.d, -f.n};
}
int main() {
  long long int ans = 1;
  int n;
  cin >> n;
  bool isthere = false;
  power[0] = 1;
  for (int i = 1; i <= 200000; i++) power[i] = (power[i - 1] * 2) % mod;
  map<frac, long long int> M;
  frac x;
  for (int i = 1; i <= n; i++) {
    cin >> x.n >> x.d;
    if (x.n != 0 or x.d != 0)
      M[reduce(x)]++;
    else
      isthere = true;
  }
  set<frac> found;
  for (auto X : M) {
    if (found.find(X.first) == found.end()) {
      if (M.find(perp(X.first)) != M.end()) {
        ans =
            (ans * (power[X.second] + power[M[perp(X.first)]] - 1) % mod) % mod;
      } else
        ans = (ans * power[X.second]) % mod;
      found.insert(X.first);
      found.insert(perp(X.first));
    }
  }
  if (!isthere) ans--;
  cout << ans;
}
