#include <bits/stdc++.h>
using namespace std;
template <typename T>
T Input() {
  T v;
  cin >> v;
  return v;
}
template <typename T>
vector<T> InputVector(int n) {
  vector<T> v(n);
  for (int i = 0; i < n; ++i) {
    cin >> v[i];
  }
  return v;
}
template <typename T>
void InputArray(T* begin, int n) {
  for (int i = 0; i < n; ++i) {
    cin >> begin[i];
  }
}
template <int Mod>
struct MintBase {
  int64_t x;
  MintBase(int64_t x = 0) : x((x % Mod + Mod) % Mod) {}
  MintBase operator-() const { return MintBase(-x); }
  MintBase& operator+=(const MintBase a) {
    if ((x += a.x) >= Mod) x -= Mod;
    return *this;
  }
  MintBase& operator-=(const MintBase a) {
    if ((x += Mod - a.x) >= Mod) x -= Mod;
    return *this;
  }
  MintBase& operator*=(const MintBase a) {
    (x *= a.x) %= Mod;
    return *this;
  }
  MintBase operator+(const MintBase a) const { return MintBase(*this) += a; }
  MintBase operator-(const MintBase a) const { return MintBase(*this) -= a; }
  MintBase operator*(const MintBase a) const { return MintBase(*this) *= a; }
  MintBase pow(int64_t t) const {
    if (!t) return 1;
    MintBase a = pow(t >> 1);
    a *= a;
    if (t & 1) a *= *this;
    return a;
  }
  MintBase inv() const { return pow(Mod - 2); }
  MintBase& operator/=(const MintBase a) { return *this *= a.inv(); }
  MintBase operator/(const MintBase a) const { return MintBase(*this) /= a; }
};
using mint = MintBase<1000000007>;
istream& operator>>(istream& is, const mint& a) { return is >> a.x; }
ostream& operator<<(ostream& os, const mint& a) { return os << a.x; }
int64_t gcd(int64_t a, int64_t b) {
  if (a < b) return gcd(b, a);
  int64_t r;
  while ((r = a % b)) {
    a = b;
    b = r;
  }
  return b;
}
int main(int, const char**) {
  int n;
  cin >> n;
  int zeros = 0;
  struct Key {
    int64_t x;
    int64_t y;
    int64_t z;
    void Dump() { cout << "(" << x << ", " << y << ", " << z << ")" << endl; }
  };
  auto compare = [](const Key& a, const Key& b) -> bool {
    if (a.x == b.x) {
      if (a.y == b.y) {
        return a.z < b.z;
      }
      return a.y < b.y;
    }
    return a.x < b.x;
  };
  map<Key, int64_t, decltype(compare)> t{compare};
  for (int i = 0; i < n; ++i) {
    int a, b;
    cin >> a >> b;
    if (a == 0 && b == 0) {
      zeros++;
      continue;
    }
    if (a == 0) {
      Key k = {0, 1, 1};
      if (t.find(k) == t.end()) {
        t[k] = 0;
      }
      t[k]++;
      continue;
    }
    if (b == 0) {
      Key k = {1, 0, 1};
      if (t.find(k) == t.end()) {
        t[k] = 0;
      }
      t[k]++;
      continue;
    }
    auto g = gcd(abs(a), abs(b));
    a /= g;
    b /= g;
    Key k = {abs(a), abs(b), a * b < 0 ? -1 : 1};
    if (t.find(k) == t.end()) {
      t[k] = 0;
    }
    t[k]++;
  }
  set<Key, decltype(compare)> done{compare};
  vector<mint> counts;
  for (auto itr = t.begin(); itr != t.end(); ++itr) {
    auto k = itr->first;
    auto v = itr->second;
    if (done.find(k) != done.end()) {
      continue;
    }
    Key tk = {k.y, k.x, -1 * k.z};
    if (t.find(tk) == t.end()) {
      t[tk] = 0;
    }
    auto tv = t[tk];
    mint c = 2;
    c = c.pow(v);
    c -= 1;
    mint tc = 2;
    tc = tc.pow(tv);
    tc -= 1;
    ((void)0);
    ((void)0);
    counts.push_back(c + tc + 1);
    done.insert(k);
    done.insert(tk);
  }
  mint ans = 0;
  if (counts.size() > 0) {
    ans = 1;
    for (auto count : counts) {
      ans *= count;
    }
    ans -= 1;
  }
  ans += zeros;
  cout << ans << endl;
  return 0;
}
