#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<__int128_t, __int128_t>;
using vi = vector<__int128_t>;
using vvi = vector<vi>;
using vpii = vector<pii>;
using vvpii = vector<vpii>;
template <typename T, typename U>
ostream& operator<<(ostream& o, const pair<T, U>& p) {
  return o << "(" << p.first << "," << p.second << ")";
}
template <typename T>
ostream& operator<<(ostream& o, const vector<T>& v) {
  o << "[";
  for (const T& x : v) o << x << ",";
  return o << "]";
}
const __int128_t INF = 1e18;
const ll MOD = 1e9 + 7;
ll pow2(ll x) {
  assert(x >= 0);
  if (x == 0) return 1;
  ll res = 1;
  if (x % 2) res = (res * 2) % MOD;
  ll hp = pow2(x / 2);
  return res * hp % MOD * hp % MOD;
}
bool divless(const pii& x1, const pii& x2) {
  return x1.first * x2.second < x2.first * x1.second;
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  ll n;
  cin >> n;
  ll zzcnt = 0;
  ll azcnt = 0;
  ll zbcnt = 0;
  vpii neg, pos;
  for (ll i = 0; i < n; ++i) {
    ll xi, xj;
    cin >> xi >> xj;
    __int128_t xir = xi, xjr = xj;
    if (xi == 0 && xj == 0)
      ++zzcnt;
    else if (xi == 0)
      ++zbcnt;
    else if (xj == 0)
      ++azcnt;
    else {
      if (xjr < 0) {
        xir = -xir;
        xjr = -xjr;
      }
      if (xir < 0)
        neg.push_back({xir, xjr});
      else
        pos.push_back({xir, xjr});
    }
  }
  sort(neg.begin(), neg.end(), divless);
  sort(pos.begin(), pos.end(), divless);
  ll res = 1;
  ll l = 0, r = 0;
  while (true) {
    if (l < neg.size() &&
        (r == pos.size() ||
         neg[l].first * pos[r].first < -neg[l].second * pos[r].second)) {
      res = (res * 2) % MOD;
      ++l;
    } else if (r < pos.size() &&
               (l == neg.size() ||
                neg[l].first * pos[r].first > -neg[l].second * pos[r].second)) {
      res = (res * 2) % MOD;
      ++r;
    } else {
      pii currval = neg[l];
      ll leftsz = 0;
      while (l < neg.size() &&
             neg[l].first * currval.second == currval.first * neg[l].second) {
        ++leftsz;
        ++l;
      }
      assert(leftsz > 0);
      ll rightsz = 0;
      while (r < pos.size() &&
             pos[r].first * currval.first == -currval.second * pos[r].second) {
        ++rightsz;
        ++r;
      }
      res *= (pow2(leftsz) + pow2(rightsz) - 1) % MOD;
      res %= MOD;
    }
    assert(l <= neg.size() && r <= pos.size());
    if (l == neg.size() && r == pos.size()) break;
  }
  res *= (pow2(azcnt) + pow2(zbcnt) - 1) % MOD;
  res %= MOD;
  res -= 1;
  res += zzcnt;
  cout << res << "\n";
}
