#include <bits/stdc++.h>
using namespace std;
namespace Mint {
const long long MOD = 1000000007;
template <long long Mod>
struct Modint {
  long long val = 0;
  Modint() = default;
  Modint(const Modint&) = default;
  Modint(long long _x) { val = _x >= 0 ? _x % Mod : ((_x % Mod) + Mod) % Mod; }
  long long modpow(long long a, long long b) const {
    long long ret = 1, kakeru = a;
    while (b > 0) {
      if (b & 1) ret *= kakeru, ret %= Mod;
      kakeru *= kakeru, kakeru %= Mod;
      b >>= 1;
    }
    return ret;
  }
  Modint inv() const { return modpow((*this).val, MOD - 2); }
  Modint operator=(const Modint& p) {
    val = p.val;
    return (*this);
  }
  Modint& operator+=(const Modint& p) {
    val += p.val;
    if (val >= Mod) val -= Mod;
    return (*this);
  }
  Modint& operator-=(const Modint& p) {
    val -= p.val;
    if (val < 0) val += Mod;
    return (*this);
  }
  Modint& operator*=(const Modint& p) {
    val *= p.val;
    val %= Mod;
    return (*this);
  }
  Modint& operator/=(const Modint& p) {
    Modint tmp(modpow(p.val, MOD - 2));
    (*this) *= tmp;
    return (*this);
  }
};
const Modint<MOD> operator+(const Modint<MOD>& l, const Modint<MOD>& r) {
  Modint<MOD> tmp = l;
  tmp += r;
  return tmp;
}
const Modint<MOD> operator+(const Modint<MOD>& l, const long long r) {
  Modint<MOD> tmp = l;
  tmp += Modint<MOD>(r);
  return tmp;
}
const Modint<MOD> operator+(const long long l, const Modint<MOD>& r) {
  Modint<MOD> tmp = l;
  tmp += r;
  return tmp;
}
const Modint<MOD> operator-(const Modint<MOD>& l, const Modint<MOD>& r) {
  Modint<MOD> tmp = l;
  tmp -= r;
  return tmp;
}
const Modint<MOD> operator-(const Modint<MOD>& l, const long long r) {
  Modint<MOD> tmp = l;
  tmp -= Modint<MOD>(r);
  return tmp;
}
const Modint<MOD> operator-(const long long l, const Modint<MOD>& r) {
  Modint<MOD> tmp = l;
  tmp -= r;
  return tmp;
}
const Modint<MOD> operator*(const Modint<MOD>& l, const Modint<MOD>& r) {
  Modint<MOD> tmp = l;
  tmp *= r;
  return tmp;
}
const Modint<MOD> operator*(const Modint<MOD>& l, const long long r) {
  Modint<MOD> tmp = l;
  tmp *= Modint<MOD>(r);
  return tmp;
}
const Modint<MOD> operator*(const long long l, const Modint<MOD>& r) {
  Modint<MOD> tmp = l;
  tmp *= r;
  return tmp;
}
const Modint<MOD> operator/(const Modint<MOD>& l, const Modint<MOD>& r) {
  Modint<MOD> tmp = l;
  tmp /= r;
  return tmp;
}
const Modint<MOD> operator/(const Modint<MOD>& l, const long long r) {
  Modint<MOD> tmp = l;
  tmp /= Modint<MOD>(r);
  return tmp;
}
const Modint<MOD> operator/(const long long l, const Modint<MOD>& r) {
  Modint<MOD> tmp = l;
  tmp /= r;
  return tmp;
}
const bool operator==(const Modint<MOD>& l, const Modint<MOD>& r) {
  return l.val == r.val;
}
const bool operator==(const Modint<MOD>& l, const long long r) {
  return l.val == r;
}
const bool operator==(const long long l, const Modint<MOD>& r) {
  return l == r.val;
}
const bool operator!=(const Modint<MOD>& l, const Modint<MOD>& r) {
  return !(l.val == r.val);
}
const bool operator!=(const Modint<MOD>& l, const long long r) {
  return !(l.val == r);
}
const bool operator!=(const long long l, const Modint<MOD>& r) {
  return !(l == r.val);
}
std::ostream& operator<<(std::ostream& stream, const Modint<MOD>& p) {
  stream << p.val;
  return stream;
}
std::istream& operator>>(std::istream& stream, Modint<MOD>& p) {
  stream >> p.val;
  return stream;
}
Modint<MOD> modpow(const Modint<MOD> a, long long b) {
  long long ret = 1, kakeru = a.val;
  while (b > 0) {
    if (b & 1) ret *= kakeru, ret %= MOD;
    kakeru *= kakeru, kakeru %= MOD;
    b >>= 1;
  }
  Modint<MOD> tmpret(ret);
  return tmpret;
}
}  // namespace Mint
using namespace Mint;
using mint = Mint::Modint<MOD>;
namespace comb {
long long fact[500001];
long long fact_inv[500001];
const long long MOD = 1000000007;
long long modpow(long long a, long long b) {
  long long base = 1, kakeru = a;
  while (b > 0) {
    if (b & 1) base *= kakeru, base %= MOD;
    kakeru *= kakeru, kakeru %= MOD;
    b >>= 1;
  }
  return base;
}
void setup() {
  fact[0] = 1, fact[1] = 1;
  for (int i = 2; i <= 500000; i++) {
    fact[i] = (fact[i - 1] * i) % MOD;
  }
  fact_inv[500000] = modpow(fact[500000], MOD - 2);
  for (int i = 499999; i >= 0; i--) {
    fact_inv[i] = fact_inv[i + 1] * (i + 1);
    fact_inv[i] %= MOD;
  }
}
long long combination(int a, int b) {
  if (a - b < 0) return 0;
  long long ret = fact[a];
  ret *= fact_inv[b], ret %= MOD;
  ret *= fact_inv[a - b], ret %= MOD;
  return ret;
}
long long permutation(int a, int b) {
  if (a - b < 0) return 0;
  long long ret = fact[a];
  ret *= fact_inv[a - b], ret %= MOD;
  return ret;
}
long long homogeneous(int a, int b) { return combination(a + b - 1, b); }
}  // namespace comb
long long gcd(long long a, long long b) {
  if (a % b == 0) return b;
  return gcd(b, a % b);
}
long long A[200000 + 10], B[200000 + 10];
int main() {
  comb::setup();
  int N;
  cin >> N;
  for (int i = 0; i < N; i++) cin >> A[i] >> B[i];
  long long cntzero = 0;
  map<tuple<long long, long long, long long>, long long> M;
  for (int i = 0; i < N; i++) {
    if (A[i] == 0 || B[i] == 0) {
      cntzero++;
      continue;
    }
    int sgn = 0;
    if ((A[i] > 0 && B[i] > 0) || (A[i] < 0 && B[i] < 0))
      sgn = +1;
    else
      sgn = -1;
    M[make_tuple(sgn, abs(A[i]) / gcd(abs(A[i]), abs(B[i])),
                 abs(B[i]) / gcd(abs(A[i]), abs(B[i])))]++;
  }
  mint ans = 1;
  for (auto it = M.begin(); it != M.end(); it++) {
    if ((*it).second == 0) continue;
    tuple<long long, long long, long long> val = (*it).first;
    int sgn = get<0>(val);
    long long bunsi = get<1>(val);
    long long bunbo = get<2>(val);
    ans *= comb::modpow(2, (*it).second) +
           comb::modpow(2, M[make_tuple(sgn * -1, bunbo, bunsi)]) - 1,
        M[make_tuple(sgn * -1, bunbo, bunsi)] = 0;
  }
  ans *= cntzero + 1;
  cout << ans - 1 << endl;
  return 0;
}
