#include <bits/stdc++.h>
using namespace std;

void solve(std::istream &in, std::ostream &out);

int main() {
#ifdef LOCAL
  freopen("../IO/e.in", "r", stdin);
//  freopen("../IO/e.out", "w", stdout);
#else
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(nullptr);
  std::cout.tie(nullptr);
#endif
  solve(std::cin, std::cout);
  return 0;
}

constexpr int P = 1000'000'007;

int64_t gcd(int64_t a, int64_t b) {
  while (b != 0) {
    tie(a, b) = make_pair(b, a % b);
  }
  return a;
}

void solve(std::istream &in, std::ostream &out) {
  int n;
  in >> n;
  int z = 0;
  map<pair<int64_t, int64_t>, int> m1, m2;
  for (int i = 0; i < n; ++i) {
    int64_t x, y;
    in >> x >> y;
    if (x == 0 && y == 0) {
      ++z;
      continue;
    }
    if (y < 0) {
      x = -x;
      y = -y;
    }
    if (x == 0 || y == 0) assert(false);
    if (x == 0) y = 1;
    if (y == 0) x = 1;
    int64_t g = gcd(abs(x), abs(y));
    x /= g;
    y /= g;
    m1[{x, y}]++;
    if (x >= 0) {
      m2[{-y, x}]++;
    } else {
      m2[{y, -x}]++;
    }
  }
  vector<int> p2(1, 1);
  while (p2.size() < n + 100) {
    p2.push_back(p2.back() * 2 % P);
  }
  int64_t res = 1;

  for (auto &[x, y] : m1) {
    auto [a, b] = x;
    int64_t a1 = -b, b1 = a;
    if (b1 < 0) {
      a1 = -a1;
      b1 = -b1;
    }
//    cout << a << ' ' << b << ": ";
    res *= (p2[y] + p2[m1[{a1, b1}]] - 1);
    res %= P;
    m1[{a1, b1}] = 0;
    m1[{a, b}] = 0;
  }
  out << (z + res + P - 1) % P << '\n';
}
