#include <bits/stdc++.h>
using namespace std;
struct pair_hash {
  template <class T1, class T2>
  std::size_t operator()(const std::pair<T1, T2> &p) const {
    auto h1 = std::hash<T1>{}(p.first);
    auto h2 = std::hash<T2>{}(p.second);
    return h1 ^ h2;
  }
};
long long gcd(long long x, long long y) {
  if (x > y) swap(x, y);
  if (x == 0) return y;
  return gcd(y % x, x);
}
long long euclid(long long a, long long b, long long &x, long long &y) {
  if (b) {
    long long d = euclid(b, a % b, y, x);
    return y -= a / b * x, d;
  }
  return x = 1, y = 0, a;
}
const long long mod = 1000000007;
struct Mod {
  long long x;
  Mod(long long xx) : x(xx) {}
  Mod operator+(Mod b) { return Mod((x + b.x) % mod); }
  Mod operator-(Mod b) { return Mod((x - b.x + mod) % mod); }
  Mod operator*(Mod b) { return Mod((x * b.x) % mod); }
  Mod operator/(Mod b) { return *this * invert(b); }
  Mod invert(Mod a) {
    long long x, y, g = euclid(a.x, mod, x, y);
    return Mod((x + mod) % mod);
  }
  Mod operator^(long long e) {
    if (!e) return Mod(1);
    Mod r = *this ^ (e / 2);
    r = r * r;
    return e & 1 ? *this * r : r;
  }
};
void solve() {
  int N;
  cin >> N;
  unordered_map<pair<long long, long long>, pair<int, int>, pair_hash> ok;
  for (int i = 0; i < N; i++) {
    long long A, B;
    cin >> A >> B;
    long long G = gcd(abs(A), abs(B));
    A /= G;
    B /= G;
    int nrots = 0;
    while (A < 0 || B < 0) {
      A *= -1;
      swap(A, B);
      nrots++;
    }
    pair<int, int> curr = ok[{A, B}];
    if (nrots % 2) {
      curr.first++;
    } else {
      curr.second++;
    }
    ok[{A, B}] = curr;
  }
  Mod sol(1);
  for (pair<pair<long long, long long>, pair<int, int>> p : ok) {
    int x, y;
    tie(x, y) = p.second;
    Mod a = (Mod(2) ^ x) - 1;
    Mod b = (Mod(2) ^ y) - 1;
    sol = sol * (Mod(1) + a + b);
  }
  sol = sol - Mod(1);
  cout << sol.x << "\n";
}
int main() {
  cin.sync_with_stdio(0);
  cin.tie(0);
  cin.exceptions(cin.failbit);
  solve();
}
