#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1e9 + 7;
const long double Pi = acos(-1);
using P = pair<long long, long long>;
map<P, long long> mp;
long long nature(long long a) {
  if (a >= 0) {
    return a;
  } else {
    return -1 * a;
  }
}
long long gcd(long long a, long long b) {
  if (a % b == 0) {
    return (b);
  } else {
    return (gcd(b, a % b));
  }
}
long long pw(long long x, long long y) {
  long long tmp = x;
  long long res = 1;
  while (y) {
    if (y % 2) res = res * tmp % MOD;
    y >>= 1;
    tmp = tmp * tmp % MOD;
  }
  return res;
}
long long pow(long long a, long long b, long long c) {
  if (b == 1) {
    return c;
  } else {
    b--;
    c *= a;
    c %= MOD;
    return (pow(a, b, c));
  }
}
int main() {
  long long N, count0 = 0, rock1 = 0, rock2 = 0;
  cin >> N;
  unordered_map<long long, long long> visited;
  vector<long long> A(N);
  vector<long long> B(N);
  for (long long i = 0; i < N; i++) {
    long long a, b;
    cin >> a >> b;
    if (a == 0 && b == 0) {
      A.at(i) = 0;
      B.at(i) = 0;
      count0++;
    } else if (a == 0 && b != 0) {
      A.at(i) = 0;
      B.at(i) = 1;
      rock1++;
    } else if (a != 0 && b == 0) {
      A.at(i) = 1;
      B.at(i) = 0;
      rock2++;
    } else {
      if (a > 0 && b > 0) {
        A.at(i) = a / gcd(nature(a), nature(b));
        B.at(i) = b / gcd(nature(a), nature(b));
      }
      if (a < 0 && b > 0) {
        A.at(i) = a / gcd(nature(a), nature(b));
        B.at(i) = b / gcd(nature(a), nature(b));
      }
      if (a > 0 && b < 0) {
        A.at(i) = -1 * a / gcd(nature(a), nature(b));
        B.at(i) = -1 * b / gcd(nature(a), nature(b));
      }
      if (a < 0 && b < 0) {
        A.at(i) = -1 * a / gcd(nature(a), nature(b));
        B.at(i) = -1 * b / gcd(nature(a), nature(b));
      }
    }
    mp[make_pair(A.at(i), B.at(i))]++;
  }
  long long ans = 1;
  long long n = N;
  if (n == 1) {
    cout << 1 << endl;
    return 0;
  }
  if (n == count0) {
    cout << n << endl;
    return 0;
  }
  for (long long i = 0; i < N; i++) {
    long long count = 0;
    if (A.at(i) == 0 && B.at(i) == 0) {
    } else if (A.at(i) > 0 && B.at(i) > 0 && visited[A.at(i)] != 54) {
      long long x = mp[make_pair(-1 * B.at(i), A.at(i))];
      long long y = mp[make_pair(A.at(i), B.at(i))];
      if (x > 0 && y > 0) {
        n -= x;
        n -= y;
        visited[A.at(i)] = 54;
        count += pw(2, x) + pw(2, y) - 1;
        count %= MOD;
      }
    } else if (A.at(i) == 0 && visited[0] != 54 && rock1 > 0 && rock2 > 0) {
      count = pow(2, rock1) + pw(2, rock2) - 1;
      n -= rock1;
      n -= rock2;
      count %= MOD;
      visited[0] = 54;
    }
    if (count > 0) {
      ans *= count;
    }
    ans %= MOD;
  }
  if (count0 == 0) {
    long long answer = ans * pw(2, n) - 1;
    cout << (answer + MOD) % MOD << endl;
  } else {
    long long answer = ans * pw(2, n - count0) - 1 + count0;
    cout << (answer + MOD) % MOD << endl;
  }
}
