#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
using namespace std;
template <class T>
inline bool setmin(T &a, T b) {
  if (a > b) return a = b, 1;
  return 0;
}
template <class T>
inline bool setmax(T &a, T b) {
  if (a < b) return a = b, 1;
  return 0;
}
template <class T>
inline T fast(T a, T b, T mod) {
  long long res = 1;
  while (b) {
    if (b & 1) res = (res * a) % mod;
    a = (a * a) % mod;
    b >>= 1;
  }
  return res;
}
template <class T>
istream &operator>>(istream &os, vector<T> &container) {
  for (auto &u : container) os >> u;
  return os;
}
template <class T>
ostream &operator<<(ostream &os, const vector<T> &container) {
  for (auto &u : container) os << u << " ";
  return os;
}
template <class T>
ostream &operator<<(ostream &os, const pair<T, T> &u) {
  os << u.first << " " << u.second << ' ';
  return os;
}
template <class T>
inline T gcd(T a, T b) {
  while (b) swap(a %= b, b);
  return a;
}
const long long INF = 1e9 + 7;
const long long mod = 998244353;
const long long BIG_INF = 1e18;
const long long N = 1e6 + 7;
const long long T = 1 << 20;
const long double inf = 1e18;
long long n, m, q;
map<pair<long long, long long>, long long> mapa;
pair<long long, long long> norm(pair<long long, long long> x) {
  long long a = x.first, b = x.second;
  if (a == 0 or b == 0) return {a, b};
  if (a < 0 and b < 0) {
    a *= -1;
    b *= -1;
  }
  long long GCD = (gcd(abs(a), abs(b)));
  a /= GCD;
  b /= GCD;
  if (a < 0) {
    a *= -1;
    b *= -1;
  }
  return {a, b};
}
signed main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cin >> n;
  for (int i = 0; i < (n); i++) {
    long long a, b;
    cin >> a >> b;
    mapa[norm({a, b})]++;
  }
  long long pref = 1;
  bool dwa_zera = 0;
  long long pierwsze_zero = 0;
  long long drugie_zero = 0;
  for (auto &u : mapa) {
    if (u.first.first == 0 and u.first.second == 0) {
      dwa_zera = true;
      continue;
    } else if (u.first.first == 0) {
      pierwsze_zero += u.second;
      continue;
    } else if (u.first.second == 0) {
      drugie_zero += u.second;
      continue;
    }
    pair<long long, long long> opposite =
        norm({-u.first.second, u.first.first});
    if (opposite < u.first) {
      long long pom =
          pref * fast(fast(2LL, mapa[opposite], INF), INF - 2, INF) % INF;
      pref = pom *
             (fast(2LL, mapa[opposite], INF) + fast(2LL, u.second, INF) - 1) %
             INF;
    } else
      pref = pref * fast(2LL, u.second, INF) % INF;
  }
  pref = pref *
         (fast(2LL, pierwsze_zero, INF) + fast(2LL, drugie_zero, INF) - 1) %
         INF;
  pref += dwa_zera;
  cout << (pref - 1) % INF << '\n';
}
