#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector<ll>;
const ll inf = LLONG_MAX;
const long double pi = acos(-1);
void Yes() { cout << "Yes" << endl; }
void No() { cout << "No" << endl; }
void YES() { cout << "YES" << endl; }
void NO() { cout << "NO" << endl; }
long long modpow(long long a, long long n, long long p) {
  a %= p;
  if (a == 0) return 0;
  if (a == 1) return 1;
  long long b = 1, cnt = 0;
  while (b < p && cnt < n) {
    b *= a;
    cnt++;
  }
  if (b < p) return b;
  b %= p;
  return modpow(b, n / cnt, p) * (long long)pow(a, n % cnt) % p;
}
bool is_prime(long long n) {
  if (n == 1) return false;
  if (n == 2) return true;
  if (n % 2 == 0) return false;
  for (long long i = 3; i <= sqrt(n); i += 2) {
    if (n % i == 0) return false;
  }
  return true;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  const ll p = 1e9 + 7;
  ll n;
  cin >> n;
  vll a(n), b(n);
  for (ll i = 0; i < n; i++) cin >> a[i] >> b[i];
  vector<map<ll, ll>> v(n);
  vll sg(n, 0);
  for (ll i = 0; i < n; i++) {
    if (a[i] > 0 && b[i] > 0)
      sg[i] = 1;
    else if (a[i] < 0 && b[i] < 0)
      sg[i] = 1;
    else if (a[i] > 0 && b[i] < 0)
      sg[i] = -1;
    else if (a[i] < 0 && b[i] > 0)
      sg[i] = -1;
  }
  for (ll i = 0; i < n; i++) {
    ll x = a[i], y = b[i];
    if (x == 0 || y == 0) continue;
    x = abs(x);
    y = abs(y);
    if (x % 2 == 0) {
      ll cnt = 0;
      while (x % 2 == 0) {
        x /= 2;
        cnt++;
      }
      v[i][2] += cnt;
    }
    for (ll j = 3; j <= x; j += 2) {
      if (is_prime(x)) {
        v[i][x]++;
        break;
      }
      if ((x % j) || !is_prime(j)) continue;
      ll cnt = 0;
      while (x % j == 0) {
        x /= j;
        cnt++;
      }
      v[i][j] += cnt;
    }
    if (y % 2 == 0) {
      ll cnt = 0;
      while (y % 2 == 0) {
        y /= 2;
        cnt++;
      }
      v[i][2] += cnt;
    }
    for (ll j = 3; j <= y; j += 2) {
      if (is_prime(y)) {
        v[i][y]++;
        break;
      }
      if ((y % j) || !is_prime(j)) continue;
      ll cnt = 0;
      while (y % j == 0) {
        y /= j;
        cnt++;
      }
      v[i][j] += cnt;
    }
  }
  map<map<ll, ll>, ll> mp1, mp2;
  vll cntban(n, 0);
  ll zr = 0;
  for (ll i = 0; i < n; i++) {
    if (sg[i] > 0)
      mp1[v[i]]++;
    else if (sg[i] < 0)
      mp2[v[i]]++;
    else
      zr++;
  }
  vector<vll> ban(0);
  if (mp1.size() < mp2.size()) {
    for (auto i = mp1.begin(); i != mp1.end(); i++) {
      ll x = mp2[i->first];
      if (x > 0) {
        ban.push_back({i->second, x});
      }
    }
  } else {
    for (auto i = mp2.begin(); i != mp2.end(); i++) {
      ll x = mp1[i->first];
      if (x > 0) {
        ban.push_back({i->second, x});
      }
    }
  }
  ll cnt = 0;
  for (ll i = 0; i < ban.size(); i++) {
    cnt += ban[i][0] + ban[i][1];
  }
  if (zr > 1) cnt += zr;
  ll ans = modpow(2, n - cnt, p);
  for (ll i = 0; i < ban.size(); i++) {
    ll subans = 1 + modpow(2, ban[i][0] - 1, p) + modpow(2, ban[i][1] - 1, p);
    subans %= p;
    ans *= subans;
    ans %= p;
  }
  cout << ans - 1 << endl;
}
