#include <bits/stdc++.h>
constexpr double INFI = 1000000000000000001;
constexpr int BASE = 1000000007;
template <typename T>
T calc_gcd(T a, T b) {
  if (b > a) {
    T w;
    w = a;
    a = b;
    b = w;
  }
  while (a % b) {
    a = a % b;
    T w;
    w = a;
    a = b;
    b = w;
  }
  return b;
}
using namespace std;
int modpow(int a, int b, int base) {
  vector<int> vb, va;
  while (b != 0) {
    vb.push_back(b % 2);
    b /= 2;
    va.push_back(a);
    a *= a;
    a %= base;
  }
  int ans = 1;
  for (int i = 0; i < vb.size(); i++) {
    if (vb[i] == 1) {
      ans *= va[i];
      ans %= base;
    }
  }
  return ans;
}
struct iwasi {
  double a, b;
  double ab;
};
bool operator<=(iwasi x, iwasi y) { return x.ab <= y.ab; }
bool operator<(iwasi x, iwasi y) { return x.ab < y.ab; }
bool operator==(iwasi x, iwasi y) { return x.ab == y.ab; }
int main() {
  int n;
  long long a, b;
  cin >> n;
  iwasi* v = new iwasi[n];
  long long num_0 = 0;
  int j = 0;
  for (int i = 0; i < n; i++) {
    cin >> a >> b;
    if (a == 0 && b == 0) {
      num_0++;
    } else {
      v[j].a = a;
      v[j].b = b;
      if (v[j].a == 0) {
        v[j].ab = -1 / INFI;
      } else if (v[j].b == 0) {
        v[j].ab = INFI;
      } else {
        a = a / calc_gcd(a, b);
        b = b / calc_gcd(a, b);
        v[j].a = a;
        v[j].b = b;
        v[j].ab = v[j].a / v[j].b;
      }
      j++;
    }
  }
  if (j == 0) {
    cout << num_0 << endl;
    return 0;
  }
  sort(v, v + j);
  vector<pair<iwasi, int>> v2;
  v2.push_back(make_pair(v[0], 1));
  iwasi now = v[0];
  for (int i = 1; i < j; i++) {
    if (v[i] == now) {
      v2[v2.size() - 1].second++;
    } else {
      v2.push_back(make_pair(v[i], 1));
      now = v[i];
    }
  }
  vector<double> v3;
  long long sum = 0;
  long long psum = 0;
  for (int i = 0; i < v2.size(); i++) {
    v3.push_back(v2[i].first.ab);
  }
  for (int i = 0; i < v2.size(); i++) {
    psum = sum;
    if (v2[i].first.ab < 0) {
      sum += (1LL + sum) * ((long long)modpow(2, v2[i].second, BASE) - 1LL);
      sum %= BASE;
      if (v2[i].first.a == 0) {
        if (binary_search(v3.begin(), v3.end(), INFI)) {
          int index = lower_bound(v3.begin(), v3.end(), INFI) - v3.begin();
          sum += (1LL + psum) *
                 ((long long)modpow(2, v2[index].second, BASE) - 1LL);
          sum %= BASE;
        }
      } else if (binary_search(v3.begin(), v3.end(),
                               -v2[i].first.b / v2[i].first.a)) {
        int index =
            lower_bound(v3.begin(), v3.end(), -v2[i].first.b / v2[i].first.a) -
            v3.begin();
        sum +=
            (1LL + psum) * ((long long)modpow(2, v2[index].second, BASE) - 1LL);
        sum %= BASE;
      }
    } else {
      if (v2[i].first.ab == INFI) {
        if (binary_search(v3.begin(), v3.end(), -1 / INFI)) {
        } else {
          sum += (1LL + sum) * ((long long)modpow(2, v2[i].second, BASE) - 1LL);
          sum %= BASE;
        }
      } else if (binary_search(v3.begin(), v3.end(),
                               -v2[i].first.b / v2[i].first.a)) {
      } else {
        sum += (1LL + sum) * ((long long)modpow(2, v2[i].second, BASE) - 1LL);
        sum %= BASE;
      }
    }
  }
  cout << sum + num_0 << endl;
}
