#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1e9 + 7;
const long long MOD2 = 998244353;
const long long MOD3 = 1812447359;
const long long INF = 1ll << 60;
const double PI = 2 * asin(1);
void yes() { printf("yes\n"); }
void no() { printf("no\n"); }
void Yes() { printf("Yes\n"); }
void No() { printf("No\n"); }
void YES() { printf("YES\n"); }
void NO() { printf("NO\n"); }
const double EPS = 1e-10;
int N;
long long A[int(2e5 + 5)], B[int(2e5 + 5)];
pair<double, int> P[int(2e5 + 5)];
bool visited[int(2e5 + 5)];
long long GCD(long long a, long long b) {
  if (a < b) swap(a, b);
  while (a % b != 0) {
    a %= b;
    swap(a, b);
  }
  return b;
}
long long Pow(long long a, long long n) {
  if (n == 0)
    return 1;
  else if (n % 2 == 0)
    return Pow(a * a % MOD, n / 2);
  else
    return a * Pow(a * a % MOD, n / 2) % MOD;
}
int main() {
  scanf("%d", &N);
  for (int i = 0; i < N; i++) {
    scanf("%lld%lld", A + i, B + i);
    if (A[i] == 0 || B[i] == 0) continue;
    long long G = GCD(abs(A[i]), abs(B[i]));
    A[i] /= G;
    B[i] /= G;
  }
  long long ZeroA = 0, ZeroB = 0;
  int Psize = 0;
  for (int i = 0; i < N; i++) {
    if (A[i] == 0 && B[i] == 0) continue;
    if (A[i] == 0) {
      ZeroA++;
      continue;
    }
    if (B[i] == 0) {
      ZeroB++;
      continue;
    }
    P[Psize].first = (double)A[i] / (double)B[i];
    P[Psize].second = i;
    Psize++;
  }
  sort(P, P + Psize);
  vector<pair<long long, long long> > Count;
  Count.push_back(make_pair(ZeroA, ZeroB));
  long long nowA = 1, nowB = 0;
  for (int i = 0; i < Psize - 1; i++) {
    int now = P[i].second, next = P[i + 1].second;
    if (visited[now]) continue;
    visited[now] = true;
    if (A[now] == A[next] && B[now] == B[next]) {
      nowA++;
      continue;
    }
    double Target = -1 / P[i].first;
    if (Target < 0 || Target - EPS > P[Psize - 1].first) {
      Count.push_back(make_pair(nowA, nowB));
      nowA = 1;
      nowB = 0;
      continue;
    }
    int L1 = 0, R1 = Psize;
    while (R1 - L1 > 1) {
      int Mid = (L1 + R1) / 2;
      if (P[Mid].first < Target - EPS)
        L1 = Mid;
      else
        R1 = Mid;
    }
    int L2 = 0, R2 = Psize;
    while (R2 - L2 > 1) {
      int Mid = (L2 + R2) / 2;
      if (Target + EPS < P[Mid].first)
        R2 = Mid;
      else
        L2 = Mid;
      if (Mid == (L2 + R2) / 2) break;
    }
    for (int j = L1; j < R2; j++) {
      if (A[now] == B[P[j].second] && B[now] == -1 * A[P[j].second]) {
        nowB++;
        visited[j] = true;
      } else if (A[now] == -1 * B[P[j].second] && B[now] == A[P[j].second]) {
        nowB++;
        visited[j] = true;
      }
    }
    Count.push_back(make_pair(nowA, nowB));
    nowA = 1;
    nowB = 0;
  }
  if (!visited[Psize - 1]) Count.push_back(make_pair(nowA, nowB));
  long long ans = 1;
  for (int i = 0; i < Count.size(); i++) {
    long long now = Pow(2, Count[i].first) + Pow(2, Count[i].second) - 1;
    cout << now << endl;
    ans *= now % MOD;
    ans %= MOD;
  }
  cout << ans - 1 << endl;
  return 0;
}
