#include <bits/stdc++.h>
using namespace std;
long long int fac[10000000 + 1];
long long int inv[10000000 + 1];
long long int finv[10000000 + 1];
long long int comb(long long int n, long long int k) {
  if (n < 0 || k < 0 || n < k) return 0;
  return (((fac[n] * finv[n - k]) % 1000000007) * finv[k]) % 1000000007;
}
void init() {
  fac[0] = finv[0] = fac[1] = finv[1] = inv[1] = 1;
  for (int i = 2; i <= 10000000; i++) {
    fac[i] = (fac[i - 1] * i) % 1000000007;
    inv[i] =
        ((-(1000000007 / i) * inv[1000000007 % i]) % 1000000007 + 1000000007) %
        1000000007;
    finv[i] = (finv[i - 1] * inv[i]) % 1000000007;
  }
}
long long int pp(long long int a, long long int b) {
  return (a * b) % 1000000007;
}
long long int mpow(long long int a, long long int b, long long int p = -1) {
  long long int ret = 1, num = a;
  if (p == -1) {
    while (b > 0) {
      if (b % 2) ret *= num;
      num = num * num;
      b /= 2;
    }
  } else {
    while (b > 0) {
      if (b % 2) ret = (ret * num) % p;
      num = (num * num) % p;
      b /= 2;
    }
  }
  return ret;
}
long double round_n(long double number, long double n) {
  number = number * pow(10, n - 1);
  number = round(number);
  number /= pow(10, n - 1);
  return number;
}
long double e = 5;
long double kakudo(long long int a, long long int b) {
  complex<long double> tmp(a, b);
  long double x = arg(tmp);
  if (x < 0) x = 2.0 * M_PI + x;
  return round_n(x, e);
}
int main(int argc, char const *argv[]) {
  long long int n;
  std::cin >> n;
  init();
  map<long double, long long int> mp;
  map<long double, long long int> za;
  for (int i = 0; i < n; i++) {
    long long int a, b;
    scanf("%lld %lld", &a, &b);
    if (a == 0 && b == 0) continue;
    long double x = kakudo(a, b);
    if (0 <= x && x < 2 / M_PI) {
      za.emplace(round_n(x, e), 0);
      za.emplace(round_n(x + M_PI / 2, e), 0);
      za.emplace(round_n(x + M_PI, e), 0);
      za.emplace(round_n(x + M_PI * (long double)3 / (long double)2, e), 0);
    } else if (2 / M_PI <= x && x < M_PI) {
      za.emplace(round_n(x, e), 0);
      za.emplace(round_n(x + M_PI / 2, e), 0);
      za.emplace(round_n(x + M_PI, e), 0);
      za.emplace(round_n(x - M_PI / 2, e), 0);
    } else if (M_PI <= x && x < M_PI * (long double)3 / (long double)2) {
      za.emplace(round_n(x, e), 0);
      za.emplace(round_n(x + M_PI / 2, e), 0);
      za.emplace(round_n(x - M_PI, e), 0);
      za.emplace(round_n(x - M_PI / 2, e), 0);
    } else {
      za.emplace(round_n(x, e), 0);
      za.emplace(round_n(x - M_PI / 2, e), 0);
      za.emplace(round_n(x - M_PI, e), 0);
      za.emplace(round_n(x - M_PI * (long double)3 / (long double)2, e), 0);
    }
    auto itr = mp.find(x);
    if (itr == mp.end())
      mp.emplace(x, 1);
    else
      (*itr).second++;
  }
  long long int C = 0;
  for (auto itr = za.begin(); itr != za.end(); itr++, C++) (*itr).second = C;
  vector<vector<long long int>> p =
      vector<vector<long long int>>(5 * n, vector<long long int>(4, 0));
  long long int ans = 1;
  for (auto now : za) {
    if (now.first < 0) continue;
    if (now.first >= M_PI / 2) break;
    long long int idx = now.second;
    auto a = mp.find(round_n(now.first, e));
    auto b = mp.find(round_n(now.first + M_PI / 2, e));
    auto c = mp.find(round_n(now.first + M_PI, e));
    auto d = mp.find(
        round_n(now.first + M_PI * (long double)3.0 / (long double)2.0, e));
    if (a != mp.end()) p[idx][0] = (*a).second;
    if (b != mp.end()) p[idx][1] = (*b).second;
    if (c != mp.end()) p[idx][2] = (*c).second;
    if (d != mp.end()) p[idx][3] = (*d).second;
    long long int f =
        (mpow(2, p[idx][0] + p[idx][2], 1000000007) - 1 + 1000000007) %
        1000000007;
    long long int g =
        (mpow(2, p[idx][1] + p[idx][3], 1000000007) - 1 + 1000000007) %
        1000000007;
    long long int tmp = (1 + f + g) % 1000000007;
    ans = pp(ans, tmp);
  }
  std::cout << (ans - 1 + 1000000007) % 1000000007 << '\n';
  return 0;
}
