#include <bits/stdc++.h>

using ll = long long;
using namespace std;
const int INFint = 2e9+1;
const ll INFll = 2e18+1;
ll gcd(ll a, ll b) { return __gcd(a,b); } //最大公約数
ll lcm(ll a, ll b) { return a/gcd(a,b)*b; } //最小公倍数

template<int MOD> struct Fp {
    long long val;
    constexpr Fp(long long v = 0) noexcept : val(v % MOD) {
        if (val < 0) val += MOD;
    }
    constexpr int getmod() { return MOD; }
    constexpr Fp operator - () const noexcept {
        return val ? MOD - val : 0;
    }
    constexpr Fp operator + (const Fp& r) const noexcept { return Fp(*this) += r; }
    constexpr Fp operator - (const Fp& r) const noexcept { return Fp(*this) -= r; }
    constexpr Fp operator * (const Fp& r) const noexcept { return Fp(*this) *= r; }
    constexpr Fp operator / (const Fp& r) const noexcept { return Fp(*this) /= r; }
    constexpr Fp& operator += (const Fp& r) noexcept {
        val += r.val;
        if (val >= MOD) val -= MOD;
        return *this;
    }
    constexpr Fp& operator -= (const Fp& r) noexcept {
        val -= r.val;
        if (val < 0) val += MOD;
        return *this;
    }
    constexpr Fp& operator *= (const Fp& r) noexcept {
        val = val * r.val % MOD;
        return *this;
    }
    constexpr Fp& operator /= (const Fp& r) noexcept {
        long long a = r.val, b = MOD, u = 1, v = 0;
        while (b) {
            long long t = a / b;
            a -= t * b; swap(a, b);
            u -= t * v; swap(u, v);
        }
        val = val * u % MOD;
        if (val < 0) val += MOD;
        return *this;
    }
    constexpr bool operator == (const Fp& r) const noexcept {
        return this->val == r.val;
    }
    constexpr bool operator != (const Fp& r) const noexcept {
        return this->val != r.val;
    }
    friend constexpr ostream& operator << (ostream &os, const Fp<MOD>& x) noexcept {
        return os << x.val;
    }
    friend constexpr Fp<MOD> modpow(const Fp<MOD> &a, long long n) noexcept {
        if (n == 0) return 1;
        auto t = modpow(a, n / 2);
        t = t * t;
        if (n & 1) t = t * a;
        return t;
    }
};


const int MOD = 1000000007;
using mint = Fp<MOD>;
long long modpow(ll a, ll n) {
    if(a == 0) return 1;
    long long res = 1;
    while (n > 0) {
        if (n & 1) res = res * a % MOD;
        a = a * a % MOD;
        n >>= 1; // right shift
    }
    return res;
}
int main(){
  ll N;
  cin>>N;
  map<ll,map<ll,ll>> m;
  vector<pair<ll,ll>> p(N);
  int cnt(0);
  for(int i(0);i<N;i++){
    ll a,b;
    cin>>a>>b;
    if(a == 0 && b == 0){
      cnt+=1;
      continue;
    }
    if(a == 0){
      b = 1;
    }else if(b == 0){
      a = 1;
    }else{
      if(a < 0 && b < 0){
        a *= -1;
        b *= -1;
      }else if(a < 0 && b > 0){
        a *= -1;b*=-1;
      }
      ll kouyakusuu = gcd(abs(a),abs(b));
      if(kouyakusuu != 0){
        a /= kouyakusuu;
        b /= kouyakusuu;
      }
    }
    m[a][b]++;
    p[i] = {a,b};
  }
  mint ans(1);
  for(int i(0);i<N;i++){
    ll a = p[i].first,b = p[i].second;
    if(m[a][b]){
      mint tmp(0);
      if(b>0){
        tmp = modpow(2,m[a][b]) + modpow(2,m[b][-a]) - 1;
        //cout << m[a][b] << " " << m[b][-a] << " " << a << " " << b << " "<<tmp << endl;
        m[b][-a] = 0;
      }else {
        tmp = modpow(2,m[a][b]) + modpow(2,m[-b][a]) - 1;
        //cout << m[a][b] << " " << m[b][-a] << " " << a << " " << b << " "<<tmp << endl;
        m[-b][a] = 0;
      }
      m[a][b] = 0;
      ans *= tmp;
    }
  }
  //for(auto mi:m){
    //for(auto mii:mi.second){
      //for(int i(0);i<mii.second;i++){
        //ans *= 2;
      //}
    //}
  //}
  ans -= 1;
  ans += cnt;
  cout << ans << endl;
  return 0;
}



Measured memory_bytes: 68796