#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <map>
#include <stack>
#include <algorithm>
#include <climits>
#include <cmath>
#include <functional>
#include <utility>
#include <numeric>
#define REP(i, n) for (int i = 0; i < (int)n; i++)
#define FOR(i, m, n) for (int i = (int)m; i < (int)n; i++)
#define REPvec(itr, mp) for (auto itr = mp.begin(); itr != mp.end(); itr++)
#define REPe(e, mp) for (auto& e : mp)
#define all(x) x.begin(), x.end()
#define MOD 1000000007  // 1e9+7
using namespace std;
using ll = long long int;
using vecint = vector<int>;
using vecll = vector<ll>;
using vec2int = vector<vector<int>>;
using P = pair<int, int>;
////////////////////////////////////////////////
const int mod = 1000000007;
struct mint {
  long long x;
  mint(long long x = 0) : x((x % mod + mod) % mod) {}
  mint operator-() const { return mint(-x); }
  mint& operator+=(const mint& a) {
    if ((x += a.x) >= mod) x -= mod;
    return *this;
  }
  mint& operator-=(const mint& a) {
    if ((x += mod - a.x) >= mod) x -= mod;
    return *this;
  }
  mint& operator*=(const mint& a) {
    (x *= a.x) %= mod;
    return *this;
  }
  mint operator+(const mint& a) const {
    mint res(*this);
    return res += a;
  }
  mint operator-(const mint& a) const {
    mint res(*this);
    return res -= a;
  }
  mint operator*(const mint& a) const {
    mint res(*this);
    return res *= a;
  }
  mint pow(ll t) const {
    if (!t) return 1;
    mint a = pow(t >> 1);
    a *= a;
    if (t & 1) a *= *this;
    return a;
  }
  // for prime mod
  mint inv() const { return pow(mod - 2); }
  mint& operator/=(const mint& a) { return (*this) *= a.inv(); }
  mint operator/(const mint& a) const {
    mint res(*this);
    return res /= a;
  }

  friend ostream& operator<<(ostream& os, const mint& m) {
    os << m.x;
    return os;
  }
};
////////////////////////////////////////////////
int main() {
  ////////////////////////////////////////////////
  cin.tie(nullptr);
  ios_base::sync_with_stdio(false);
  ////////////////////////////////////////////////
  int n;
  cin >> n;
  // vector<pair<ll, ll>> a(n);
  vector<mint> p2(n + 1, 1LL);
  REP(i, n) { p2[i + 1] = p2[i] * 2; }
  map<pair<ll, ll>, ll> mp;
  ll cnt = 0;
  REP(i, n) {
    ll a, b;
    cin >> a >> b;
    if (a == 0 && b == 0) {
      cnt++;
      continue;
    }
    ll g = gcd(abs(a), abs(b));
    a /= g;
    b /= g;
    if (a == 0 && b != 0) {
      //(0,1)
      b = 1;
    } else if (b == 0 && a != 0) {
      //(1,0)
      a = 1;
    }
    if ((a < 0 && b > 0) || (a < 0 && b < 0)) {
      // (+a,-b) or (+a, +b)
      a *= -1LL;
      b *= -1LL;
    }
    mp[{a, b}]++;
  }
  mint ans = 1;
  map<pair<ll, ll>, int> seen;
  REPvec(itr, mp) {
    pair<ll, ll> p = itr->first;
    if (seen[p] > 0) continue;
    seen[p] = 1;
    pair<ll, ll> q = {p.second, -p.first};
    if (p.second < 0) {
      // p(+,-)->q(+,+)
      q = {-p.second, p.first};
    } else if (p.second == 0) {
      q = {0, 1};
    } else if (p.first == 0) {
      q = {1, 0};
    }
    if (p == q || mp.count(q) == 0) {
      ans *= p2[mp[p]];
    } else {
      seen[q] = 1;
      ans *= (p2[mp[p]] + p2[mp[q]] - 1);
    }
    // cout << ans << endl;
  }
  ans += cnt - 1;
  cout << ans << endl;
}


Measured memory_bytes: 29748