#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
const long long MOD = 1e9 + 7;
const long long LINF = 1e18;
long long twopow[200005];
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
int lcm(int a, int b) { return a / gcd(a, b) * b; }
long long PowMod(long long n, long long m) {
  if (m == 0) {
    return (long long)1;
  }
  if (m % 2 == 0) {
    long long temp = PowMod(n, m / 2);
    return temp * temp % MOD;
  }
  return n * PowMod(n, m - 1) % MOD;
}
int main() {
  int n;
  cin >> n;
  twopow[0] = 1;
  for (int i = 1; i < 200005; i++) {
    twopow[i] = twopow[i - 1] * 2;
    twopow[i] %= MOD;
  }
  map<pair<int, int>, int> mp;
  vector<int> a(n);
  vector<int> b(n);
  for (int i = 0; i < (int)(n); i++) {
    cin >> a[i] >> b[i];
    int g = gcd(a[i], b[i]);
    mp[pair<int, int>(a[i] / g, b[i] / g)]++;
  }
  long long ans = twopow[n] - 1;
  long long sub = 0;
  for (auto obj : mp) {
    cout << obj.first.first << " " << obj.first.second << " " << obj.second
         << endl;
  }
  for (auto obj : mp) {
    long long temp = 0;
    int hoge = 0;
    int fuga = 0;
    int flag = 0;
    if (mp.count(pair<int, int>(obj.first.second, (-1) * obj.first.first))) {
      fuga += mp[obj.first];
      hoge += mp[pair<int, int>(obj.first.second, (-1) * obj.first.first)];
      mp.erase(pair<int, int>(obj.first.second, (-1) * obj.first.first));
      flag++;
    }
    if (mp.count(pair<int, int>((-1) * obj.first.second, obj.first.first))) {
      if (flag == 0) fuga += mp[obj.first];
      hoge += mp[pair<int, int>((-1) * obj.first.second, obj.first.first)];
      mp.erase(pair<int, int>((-1) * obj.first.second, obj.first.first));
    }
    temp = twopow[n - hoge - fuga] * (twopow[hoge] - 1) % MOD;
    temp = temp * (twopow[fuga] - 1) % MOD;
    sub += temp;
    sub %= MOD;
    mp.erase(obj.first);
  }
  ans -= sub;
  ans %= MOD;
  cout << ans << endl;
}
