#include <bits/stdc++.h>
using namespace std;
using vec = vector<long long>;
using mat = vector<vec>;
using Pii = pair<long long, long long>;
using PiP = pair<long long, Pii>;
using PPi = pair<Pii, long long>;
using bvec = vector<bool>;
using Pvec = vector<Pii>;
template <typename T>
void readv(vector<T> &a) {
  for (long long i = (0); i < (a.size()); i++) cin >> a[i];
}
void readv_m1(vector<int> &a) {
  for (long long i = (0); i < (a.size()); i++) {
    cin >> a[i];
    a[i]--;
  }
}
constexpr long long MOD = 1000000007ll;
constexpr long long MAX = 510000;
long long gcd(long long n, long long m) {
  if (n > m) swap(n, m);
  if (m % n == 0)
    return n;
  else {
    return gcd(n, m % n);
  }
}
int main() {
  long long N;
  cin >> N;
  vector<vec> AB(N, vec(2, -1));
  for (long long i = (0); i < (N); i++) {
    cin >> AB[i][0] >> AB[i][1];
    if (AB[i][0] < 0) {
      AB[i][0] *= -1;
      AB[i][1] *= -1;
    }
    if (AB[i][0] > 0 && AB[i][1] < 0) {
      long long gcdval = gcd(AB[i][0], -AB[i][1]);
      AB[i][0] /= gcdval;
      AB[i][1] /= gcdval;
    } else if (AB[i][0] > 0 && AB[i][1] > 0) {
      long long gcdval = gcd(AB[i][0], AB[i][1]);
      AB[i][0] /= gcdval;
      AB[i][1] /= gcdval;
    }
  }
  sort(AB.begin(), AB.end());
  vec A(N, -1), B(N, -1);
  for (long long i = (0); i < (N); i++) {
    A[i] = AB[i][0];
    B[i] = AB[i][1];
  }
  vec multiple(0);
  vec ansind(N, -1);
  for (long long i = (0); i < (N); i++) {
    if (ansind[i] >= 0) continue;
    long long upperA =
        distance(A.begin(), upper_bound(A.begin(), A.end(), -1 * B[i]));
    long long lowerA =
        distance(A.begin(), lower_bound(A.begin(), A.end(), -1 * B[i]));
    long long upperA2 =
        distance(A.begin(), upper_bound(A.begin(), A.end(), A[i]));
    long long lowerA2 =
        distance(A.begin(), lower_bound(A.begin(), A.end(), A[i]));
    long long uppermB = distance(
        B.begin(), upper_bound(B.begin() + lowerA, B.begin() + upperA, A[i]));
    long long lowermB = distance(
        B.begin(), lower_bound(B.begin() + lowerA, B.begin() + upperA, A[i]));
    long long upperB = distance(
        B.begin(), upper_bound(B.begin() + lowerA2, B.begin() + upperA2, B[i]));
    long long lowerB = distance(
        B.begin(), lower_bound(B.begin() + lowerA2, B.begin() + upperA2, B[i]));
    long long p = upperB - lowerB;
    long long m = uppermB - lowermB;
    if (m > 0) {
      for (long long j = (lowerB); j < (upperB); j++) {
        ansind[j] = 0;
      }
      for (long long j = (lowermB); j < (uppermB); j++) {
        ansind[j] = 0;
      }
      ansind[i] = 1 + pow(2, m) - 1 + pow(2, p) - 1;
    } else {
      ansind[i] = 1;
    }
  }
  long long ans = 1;
  for (long long i = (0); i < (N); i++) {
    if (ansind[i] == 0)
      continue;
    else if (ansind[i] == 1) {
      ans *= 2;
      ans %= MOD;
    } else {
      ans *= ansind[i];
      ans %= MOD;
    }
  }
  ans--;
  ans %= MOD;
  cout << ans << endl;
  return 0;
}
