#include <bits/stdc++.h>
using namespace std;
long long MOD = 1000000007;
long long MODPOW2[200002] = {0};
void initModPow2() {
  MODPOW2[0] = 1;
  for (int i = 1; i < 200002; i++) {
    MODPOW2[i] = (MODPOW2[i - 1] * 2) % MOD;
  }
}
long long GCD(long long x, long long y) {
  long long r = 0;
  if (x < y) swap(x, y);
  r = x % y;
  while (r != 0) {
    x = y;
    y = r;
    r = x % y;
  }
  return y;
}
long long countUV(long long u, long long v) {
  long long a = 0, b = 0, c = 0, ret = 0;
  a = MODPOW2[u + v] % MOD;
  b = (MODPOW2[u] - 1) % MOD;
  b = (b * (MODPOW2[v] - 1)) % MOD;
  ret = (a - b) % MOD;
  if (ret < 0) ret += MOD;
  return ret;
}
class Tilt {
 public:
  long long x;
  long long y;
  Tilt() { x = 0, y = 0; }
  Tilt(long long x, long long y) {
    if (x == 0) {
      this->x = 0;
      this->y = 1;
    } else if (y == 0) {
      this->x = 1;
      this->y = 0;
    } else {
      long p, a, b;
      p = GCD(x, y);
      a = x / p;
      b = y / p;
      if (a > 0) {
        this->x = a;
        this->y = b;
      } else {
        this->x = 0 - a;
        this->y = 0 - b;
      }
    }
  }
  inline bool operator==(const Tilt& t) const {
    if (x == t.x && y == t.y) {
      return true;
    } else {
      return false;
    }
  }
  inline bool operator!=(const Tilt& t) const { return !(this->operator==(t)); }
};
class MyHash {
 public:
  std::size_t operator()(const Tilt& t) const {
    std::size_t h1 = std::hash<long long>{}(abs(t.x));
    std::size_t h2 = std::hash<long long>{}(abs(t.y));
    return h1 ^ (h2 << 1);
  }
};
unordered_map<Tilt, long long, MyHash> m1, m2;
int main(int argc, char* argv[]) {
  int N, M;
  long long zero = 0;
  cin >> N;
  m1.reserve(N);
  m2.reserve(N);
  initModPow2();
  long long ans = 1;
  for (int i = 1; i <= N; i++) {
    long long a, b;
    cin >> a >> b;
    if (a == 0 && b == 0) {
      zero++;
      continue;
    }
    Tilt t = Tilt(a, b);
    if (m1.count(t) == 0) {
      m1[t] = 1;
      m2[t] = 1;
    } else {
      long long v = m1[t];
      m1[t] = v + 1;
      m2[t] = v + 1;
    }
  }
  for (auto itr = m1.begin(); itr != m1.end(); itr++) {
    if (m2.empty()) break;
    long long x, y, u, v;
    Tilt t = itr->first;
    auto tmpitr1 = m2.find(t);
    if (tmpitr1 == m2.end()) {
      continue;
    }
    u = itr->second;
    x = t.x;
    y = t.y;
    Tilt w = Tilt(0 - y, x);
    auto tmpitr2 = m2.find(w);
    if (tmpitr2 != m2.end()) {
      v = m1[w];
    } else {
      v = 0;
    }
    long long uvcnt = countUV(u, v);
    ans = (ans * uvcnt) % MOD;
    m2.erase(t);
    m2.erase(w);
  }
  ans = ans + (zero % MOD) - 1;
  ans = ans % MOD;
  if (ans < 0) ans += MOD;
  cout << ans << endl;
  return 0;
}
