#include <bits/stdc++.h>
const int MOD_BY = 1000000007;
int add(int a, int b) { return a + b - (a + b >= MOD_BY ? MOD_BY : 0); }
int sub(int a, int b) { return b == 0 ? a : add(a, MOD_BY - b); }
int mul(int a, int b) {
  int r = 0;
  while (b > 0) {
    if (b & 1) r = add(r, a);
    a = add(a, a);
    b >>= 1;
  }
  return r;
}
int pou(int a, int b) {
  int r = 1;
  while (b > 0) {
    if (b & 1) r = mul(r, a);
    a = mul(a, a);
    b >>= 1;
  }
  return r;
}
int64_t gcd(int64_t a, int64_t b) {
  if (a < 0) a = -a;
  if (b < 0) b = -b;
  if (a == 0 && b == 0) return 1;
  if (a == 0) return b;
  if (b == 0) return a;
  while (b > 0) {
    int64_t r = a % b;
    a = b;
    b = r;
  }
  return a;
}
struct ayaneru {
  int64_t x, y;
  ayaneru() : x(0), y(0) {}
  ayaneru(int64_t hoge, int64_t fuga) {
    int64_t g = gcd(hoge, fuga);
    x = hoge / g;
    y = fuga / g;
    if (x < 0) {
      x = -x;
      y = -y;
    }
  }
  ayaneru are() const { return ayaneru(y, -x); }
  bool zero() const { return x == 0 && y == 0; }
  bool operator<(const ayaneru& o) const {
    if (x != o.x) return x < o.x;
    return y < o.y;
  }
};
struct asumisu {
  int kore, chokkaku;
  asumisu(int k = 0, int c = 0) : kore(k), chokkaku(c) {}
};
template <typename A, typename B>
bool in(const std::map<A, B>& m, const A& key) {
  return m.find(key) != m.end();
}
int main(void) {
  int N;
  std::vector<ayaneru> iwasi;
  int zeroCount = 0;
  int kotae;
  if (scanf("%d", &N) != 1) return 1;
  iwasi.reserve(N);
  for (int i = 0; i < N; i++) {
    int64_t A, B;
    if (scanf("%" SCNd64 "%" SCNd64, &A, &B) != 2) return 1;
    iwasi.push_back(ayaneru(A, B));
  }
  std::map<ayaneru, asumisu> risuto;
  for (std::vector<ayaneru>::iterator itr = iwasi.begin(); itr != iwasi.end();
       itr++) {
    const ayaneru& i = *itr;
    ayaneru op = i.are();
    if (i.zero()) {
      zeroCount++;
    } else if (in(risuto, i)) {
      risuto[i].kore++;
    } else if (in(risuto, op)) {
      risuto[op].chokkaku++;
    } else {
      risuto[i] = asumisu(1, 0);
    }
  }
  kotae = 1;
  for (std::map<ayaneru, asumisu>::iterator itr = risuto.begin();
       itr != risuto.end(); itr++) {
    const asumisu& a = itr->second;
    int kore = a.kore == 0 ? 0 : pou(2, a.kore);
    int chokkaku = a.chokkaku == 0 ? 0 : pou(2, a.chokkaku);
    int delta = add(kore, chokkaku);
    if (a.kore != 0 && a.chokkaku != 0) delta = sub(delta, 1);
    kotae = mul(kotae, delta);
  }
  kotae = add(sub(kotae, 1), zeroCount);
  printf("%d\n", kotae);
  return 0;
}
