#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-10;
const long long mod = 1000000007;
struct Direction {
  long long x, y;
  int sign = 0;
  Direction() {}
  Direction(long long a, long long b) {
    if (b < 0) a = -a, b = -b;
    if (b == 0 and a < 0) a = -a;
    if (a <= 0) swap(a, b), b = -b, sign = 1;
    x = a, y = b;
  }
  bool operator<(const Direction& other) const {
    if (x > 0 and other.x > 0)
      return ((double)y / (double)x < (double)other.y / (double)other.x);
    if (y > 0 and other.y > 0)
      return (-(double)x / (double)y < -(double)other.x / (double)other.y);
    return (x < other.x);
  }
  bool operator==(const Direction& other) const {
    return ((double)y / (double)x - (double)other.y / (double)other.x) < eps;
  }
};
long long esp(long long x, long long e) {
  if (e == 0) return 1;
  if (e % 2 == 1) return (x * esp(x, e - 1)) % mod;
  return esp(x * x % mod, e / 2);
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int N;
  cin >> N;
  vector<Direction> dirs(N);
  for (int i = 0; i < N; i++) {
    long long A, B;
    cin >> A >> B;
    dirs[i] = Direction(A, B);
  }
  vector<int> zeros, nonz;
  for (int i = 0; i < N; i++) {
    if (dirs[i].x == 0 and dirs[i].y == 0)
      zeros.push_back(i);
    else
      nonz.push_back(i);
  }
  sort(nonz.begin(), nonz.end(),
       [&](int i, int j) { return dirs[i] < dirs[j]; });
  int at = 0;
  long long res = 1;
  while (at < (int)nonz.size()) {
    int bt = at;
    long long u = 0, v = 0;
    while (bt < (int)nonz.size() and dirs[nonz[bt]] == dirs[nonz[at]]) {
      bt++;
      if (dirs[nonz[bt]].sign == 0) {
        u++;
      } else
        v++;
    }
    at = bt;
    long long at_res = (esp(2, u) + esp(2, v) - 1) % mod;
    res = (res * at_res) % mod;
  }
  res--;
  res += esp(2, (int)zeros.size()) - 1;
  res += mod;
  res %= mod;
  cout << res << endl;
}
