#include <bits/stdc++.h>
using std::cin;
using std::cout;
using std::endl;
using std::vector;
using ll = long long;
using ull = unsigned long long;
struct hash_pair {
  template <class T1, class T2>
  size_t operator()(const std::pair<T1, T2>& p) const {
    auto hash1 = std::hash<T1>()(p.first);
    auto hash2 = std::hash<T2>()(p.second);
    return hash1 ^ hash2;
  }
};
template <class T>
T get_gcd(T a, T b) {
  if (b == 0) return a;
  return get_gcd(b, a % b);
}
inline ull p2(ull power) {
  ull ret = 1;
  ull base = 2;
  while (0ULL < power) {
    if (power & 1) {
      ret *= base % 1000000007;
    }
    base = base * base % 1000000007;
    power >>= 1;
  }
  return ret % 1000000007;
}
int main() {
  std::cin.tie(0);
  std::ios::sync_with_stdio(false);
  ll n, a, b;
  std::cin >> n;
  std::unordered_map<std::pair<ll, ll>, std::pair<ull, ull>, hash_pair> slope;
  ll zero_pair = 0;
  for (ull i = 0; i < n; i++) {
    cin >> a >> b;
    std::pair<ll, ll> p0, p1;
    if (a == 0 && b == 0) {
      zero_pair++;
      continue;
    } else if (a == 0) {
      p0 = std::make_pair(0, 1);
      p1 = std::make_pair(1, 0);
    } else if (b == 0) {
      p0 = std::make_pair(1, 0);
      p1 = std::make_pair(0, 1);
    } else {
      ll gcd = get_gcd(abs(a), abs(b));
      a /= gcd;
      b /= gcd;
      p0 = (a > 0) ? std::make_pair(a, b) : std::make_pair(-a, -b);
      p1 = (b > 0) ? std::make_pair(b, -a) : std::make_pair(-b, a);
    }
    if (slope.find(p0) != slope.end()) {
      slope[p0].first++;
    } else if (slope.find(p1) != slope.end()) {
      slope[p1].second++;
    } else {
      slope[p0].first = 1;
      slope[p0].second = 0;
    }
  }
  ull ans = 1;
  for (const auto& e : slope) {
    ull factor;
    factor = (p2(e.second.first) + p2(e.second.second) - 1 + 1000000007) %
             1000000007;
    ans *= factor;
    ans %= 1000000007;
  }
  ans += zero_pair;
  ans--;
  ans %= 1000000007;
  cout << ans << endl;
  return 0;
}
