#include <bits/stdc++.h>
using namespace std;
long powP(long a, long b) {
  if (b == 1)
    return a;
  else if (b == 0)
    return 1;
  else if (b < 0)
    return powP(a, 1000000007 + b - 1);
  else
    return (powP(a, b / 2) * powP(a, b / 2 + b % 2)) % 1000000007;
}
template <typename T>
using vec = vector<T>;
template <typename T>
using vvec = vector<vector<T>>;
class iwashi {
 public:
  double tan;
  double cot;
  long a;
  long b;
};
bool operator<(const iwashi& l, const iwashi& r) { return l.tan < r.tan; }
int main() {
  int n;
  cin >> n;
  int iw00 = 0, iw01 = 0, iw10 = 0;
  vec<iwashi> iw11p, iw11m;
  double a, b;
  for (int i = 0; i < n; i++) {
    cin >> a >> b;
    if (a == 0 && b == 0) {
      iw00++;
    } else if (a == 0) {
      iw01++;
    } else if (b == 0) {
      iw10++;
    } else {
      iwashi iw;
      iw.a = a, iw.b = b;
      iw.tan = (double)b / a, iw.cot = (double)a / b;
      if (iw.tan > 0) {
        iw11p.push_back(iw);
      } else {
        swap(iw.tan, iw.cot);
        iw.tan = -iw.tan;
        iw.cot = -iw.cot;
        iw11m.push_back(iw);
      }
    }
  }
  long ans = 1;
  int nkys = 0;
  sort((iw11p).begin(), (iw11p).end());
  sort((iw11m).begin(), (iw11m).end());
  auto itrp = iw11p.begin();
  auto itrm = iw11m.begin();
  while (itrp != iw11p.end() && itrm != iw11m.end()) {
    if ((*itrp).tan > (*itrm).tan) {
      itrm++;
      nkys++;
    } else if ((*itrp).tan < (*itrm).tan) {
      itrp++;
      nkys++;
    } else {
      auto itrp_ = itrp;
      auto itrm_ = itrm;
      itrp = upper_bound(itrp, iw11p.end(), *itrp);
      itrm = upper_bound(itrm, iw11m.end(), *itrm);
      ans *= (powP(2, itrp - itrp_) + powP(2, itrm - itrm_) - 1);
      ans %= 1000000007;
    }
  }
  nkys += (iw11p.end() - itrp);
  nkys += (iw11m.end() - itrm);
  ans *= powP(2, nkys);
  ans %= 1000000007;
  ans *= (powP(2, iw01) + powP(2, iw10) - 1);
  ans = (ans + iw00 - 1) % 1000000007;
  cout << ans;
}
