#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
struct mint {
  static const long long MOD = 1000000007;
  long long v;
  mint() : v(0) {}
  mint(long long x) {
    x = x % MOD;
    if (x < 0) {
      x += MOD;
    }
    v = x;
  }
  mint& operator+=(mint a) {
    v += a.v;
    if (v >= MOD) {
      v -= MOD;
    }
    return *this;
  }
  mint& operator*=(mint a) {
    v *= a.v;
    v %= MOD;
    return *this;
  }
  mint& operator-=(mint a) {
    v -= a.v;
    if (v < 0) {
      v += MOD;
    }
    return *this;
  }
  mint& operator/=(mint a) { return (*this) *= a.inv(); }
  mint operator*(mint a) const { return mint(v) *= a; }
  mint operator+(mint a) const { return mint(v) += a; }
  mint operator-(mint a) const { return mint(v) -= a; }
  mint operator/(mint a) const { return mint(v) /= a; }
  mint pow(long long k) const {
    mint res(1), tmp(v);
    while (k) {
      if (k & 1) res *= tmp;
      tmp *= tmp;
      k >>= 1;
    }
    return res;
  }
  mint inv() { return pow(MOD - 2); }
  static mint comb(long long n, int k) {
    mint res(1);
    for (int i = 0; i < k; ++i) {
      res *= mint(n - i);
      res /= mint(i + 1);
    }
    return res;
  }
  static mint factorial(long long n) {
    mint res(1);
    for (int i = n; i > 1; --i) {
      res *= mint(i);
    }
    return res;
  }
  bool operator<(const mint& a) const { return v < a.v; };
};
mint operator*(long long l, mint r) { return r * l; }
std::ostream& operator<<(std::ostream& stream, const mint& m) {
  stream << m.v;
  return stream;
}
ll gcd(ll a, ll b) {
  if (a < b) {
    return gcd(b, a);
  }
  ll r;
  while ((r = a % b)) {
    a = b;
    b = r;
  }
  return b;
}
int main() {
  ll n;
  cin >> n;
  ll num0 = 0;
  set<pair<ll, ll>> type;
  map<pair<ll, ll>, ll> count;
  for (ll i = 0; i < (n); ++i) {
    ll ai, bi;
    cin >> ai >> bi;
    if (ai == 0 && bi == 0) {
      num0++;
      continue;
    }
    if (ai != 0 && bi != 0) {
      ll g = gcd(abs(ai), abs(bi));
      ai /= g;
      bi /= g;
      if (ai * bi < 0) {
        ai = -abs(ai);
        bi = abs(bi);
      }
      if (ai * bi >= 0) {
        type.emplace(ai, bi);
      } else {
        type.emplace(abs(bi), abs(ai));
      }
    } else if (ai == 0 && bi != 0) {
      ai = 0;
      bi = 1;
      type.emplace(1, 0);
    } else {
      assert(ai != 0 && bi == 0);
      ai = 1;
      bi = 0;
      type.emplace(1, 0);
    }
    count[make_pair(ai, bi)]++;
  }
  vector<mint> pow2(n + 1);
  pow2.at(0) = 1;
  for (ll i = 1; i <= n; ++i) {
    pow2.at(i) = pow2.at(i - 1) * 2;
  }
  mint ans = 1;
  for (auto p : type) {
    ll a1 = p.first, b1 = p.second;
    ll c1 = count[p];
    mint tmp = 1;
    if (a1 != 0 && b1 != 0) {
      pair<ll, ll> q;
      if (a1 * b1 >= 0) {
        q = make_pair(-b1, a1);
      } else {
        q = make_pair(-b1, abs(a1));
      }
      ll c2 = count[q];
      tmp += pow2.at(c1) - 1;
      tmp += pow2.at(c2) - 1;
    } else if (a1 == 0) {
      assert(b1 != 0);
      ll c2 = count[make_pair(1, 0)];
      tmp += pow2.at(c1) - 1;
      tmp += pow2.at(c2) - 1;
    } else {
      assert(b1 == 0);
      ll c2 = count[make_pair(0, 1)];
      tmp += pow2.at(c1) - 1;
      tmp += pow2.at(c2) - 1;
    }
    ans *= tmp;
  }
  cout << ans - 1 + num0 << endl;
  return 0;
}
