#include <bits/stdc++.h>
using namespace std;
struct V {
  int64_t n;
  int64_t v;
};
struct N {
  int64_t np;
  int64_t nn;
};
int64_t gcd(int64_t a, int64_t b) {
  if (a < b) swap(a, b);
  if (a % b == 0) return b;
  return gcd(b, a % b);
}
int64_t powint(int64_t x, int64_t m) {
  if (m == 0) {
    return 1;
  }
  if (m == 1) {
    return x;
  }
  if (m & 1) {
    int64_t val = powint(x, m / 2);
    val = val * val;
    val *= x;
    return val;
  } else {
    int64_t val = powint(x, m / 2);
    val = val * val;
    return val;
  }
}
template <int64_t M = 1000000007>
class ModInt {
 public:
  ModInt() : val_(0){};
  ModInt(int64_t val) {
    this->val_ = val;
    this->val_ %= M;
    while (this->val_ >= M) this->val_ -= M;
    while (this->val_ < 0) this->val_ += M;
  }
  operator int64_t() const { return this->val_; }
  ModInt& operator+=(int64_t val) {
    this->val_ += val;
    this->val_ %= M;
    while (this->val_ >= M) this->val_ -= M;
    return *this;
  }
  ModInt& operator-=(int64_t val) {
    this->val_ -= val;
    this->val_ %= M;
    while (this->val_ < 0) this->val_ += M;
    return *this;
  }
  ModInt& operator*=(int64_t val) {
    this->val_ *= val;
    this->val_ %= M;
    return *this;
  }
  ModInt& operator/=(int64_t val) {
    ModInt v = ModInt::pow(val, M - 2);
    *this *= v;
    return *this;
  }
  ModInt operator+(int64_t v) const {
    ModInt ret = *this;
    return (ret += v);
  }
  ModInt operator-(int64_t v) const {
    ModInt ret = *this;
    return (ret -= v);
  }
  ModInt operator*(int64_t v) const {
    ModInt ret = *this;
    return (ret *= v);
  }
  ModInt operator/(int64_t v) const {
    ModInt ret = *this;
    return (ret /= v);
  }
  static ModInt pow(ModInt n, int64_t m) {
    if (m == 0) {
      ModInt ret(1);
      return ret;
    }
    if (m == 1) {
      return n;
    }
    ModInt v = pow(n, m / 2);
    ModInt ret = v * v;
    if (m & 1) {
      ret *= n;
    }
    return ret;
  }
  ostream& operator<<(ostream& out) {
    out << this->val_;
    return out;
  }

 private:
  int64_t val_;
};
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout << fixed << setprecision(20);
  int n;
  cin >> n;
  auto cmp = [](const V& lhs, const V& rhs) {
    if (lhs.n != rhs.n) return lhs.n < rhs.n;
    return lhs.v < rhs.v;
  };
  map<V, N, decltype(cmp)> data(cmp);
  int64_t nzero = 0;
  for (int i = (int)(0); i < (int)(n); i++) {
    int64_t n, v;
    cin >> n >> v;
    if (n == 0 && v == 0) {
      nzero++;
      continue;
    }
    if (n == 0 || v == 0) {
      if (data.find({0, 0}) == data.end()) {
        data[{0, 0}] = {0, 0};
      }
      if (n == 0) {
        data[{0, 0}].np++;
      }
      if (v == 0) {
        data[{0, 0}].nn++;
      }
      continue;
    }
    bool is_p = (n < 0) == (v < 0);
    n = abs(n);
    v = abs(v);
    int64_t d = gcd(n, v);
    n /= d;
    v /= d;
    if (is_p) std::swap(n, v);
    if (data.find({n, v}) == data.end()) {
      data[{n, v}] = {0, 0};
    }
    if (is_p)
      data[{n, v}].nn++;
    else
      data[{n, v}].np++;
  }
  ModInt<> ans = 1;
  for (auto& n : data) {
    ans *= ModInt<>::pow(2, n.second.nn) + ModInt<>::pow(2, n.second.np) -
           ModInt<>(1);
  }
  ans += nzero - 1;
  cout << ans << endl;
  return 0;
}
