#include <bits/stdc++.h>
using namespace std;
vector<long long> fac(200005);
vector<long long> ifac(200005);
const double INF = 1e18 + 1;
long long mpow(long long x, long long n) {
  long long ans = 1;
  while (n != 0) {
    if (n & 1) ans = ans * x % 1000000007;
    x = x * x % 1000000007;
    n = n >> 1;
  }
  return ans;
}
void init_comb() {
  fac[0] = 1;
  ifac[0] = 1;
  for (long long i = 1; i < 200005; i++) {
    fac[i] = fac[i - 1] * i % 1000000007;
    ifac[i] = ifac[i - 1] * mpow(i, 1000000007 - 2) % 1000000007;
  }
}
long long combination(long long n, long long m) {
  if (m == n || m == 0) return 1;
  long long tmp = fac[n] * ifac[m] % 1000000007;
  return tmp * ifac[n - m] % 1000000007;
}
long long mdev(long long a, long long b) {
  return a * mpow(b, 1000000007 - 2) % 1000000007;
}
long long msub(long long a, long long b) {
  if (a > b) return (a - b) % 1000000007;
  return msub(a + 1000000007, b);
}
long long sum_comb(int n) {
  long long sum = 0;
  for (int i = 0; i < (int)(n + 1); i++) {
    sum = (sum + combination(n, i)) % 1000000007;
  }
  return sum;
}
long long gcd(long long a, long long b) {
  if (b == 0) return a;
  return gcd(b, a % b);
}
int main() {
  init_comb();
  int n;
  cin >> n;
  map<pair<long long, long long>, int> s;
  vector<pair<long long, long long> > keys;
  for (int i = 0; i < (int)(n); i++) {
    long long a, b;
    cin >> a >> b;
    if (a < 0 && b < 0) {
      a = -a;
      b = -b;
    } else if (a < 0 && b > 0) {
      a = -a;
      b = -b;
    }
    if (a == 0 && b == 0) {
    } else if (a == 0) {
      b = 1;
    } else if (b == 0) {
      a = 1;
    } else {
      long long g = gcd(a, b);
      g = abs(g);
      a = a / g;
      b = b / g;
    }
    pair<long long, long long> k = pair<long long, long long>(a, b);
    if (!(s.find(k) != s.end())) {
      keys.push_back(k);
    }
    s[k]++;
  }
  int free_n = 0;
  int zero_n = 0;
  vector<pair<long long, long long> > twin;
  for (int i = 0; i < (int)(keys.size()); i++) {
    long long inv_ka = keys[i].second;
    long long inv_kb = -keys[i].first;
    if (keys[i].first == 0 && keys[i].second == 0) {
      zero_n = s[keys[i]];
      continue;
    }
    if (inv_ka <= 0) {
      inv_ka = -inv_ka;
      inv_kb = -inv_kb;
    }
    pair<long long, long long> pk = pair<long long, long long>(inv_ka, inv_kb);
    if ((s.find(pk) != s.end())) {
      if (s[pk] > 0) {
        twin.push_back(pair<long long, long long>(s[keys[i]], s[pk]));
        s[keys[i]] = 0;
        s[pk] = 0;
      }
    } else {
      free_n++;
    }
  }
  long long ans = sum_comb(free_n);
  for (int i = 0; i < (int)(twin.size()); i++) {
    int a = twin[i].first, b = twin[i].second;
    long long twin_comb = (sum_comb(a) + sum_comb(b)) % 1000000007;
    twin_comb = msub(twin_comb, 1);
    ans = (ans * twin_comb) % 1000000007;
  }
  ans = (ans + zero_n) % 1000000007;
  ans = msub(ans, 1);
  cout << ans << endl;
  return 0;
}
