#include <stdio.h>
#include <algorithm>
#include <utility>
#include <functional>
#include <cstring>
#include <queue>
#include <stack>
#include <cmath>
#include <iterator>
#include <vector>
#include <string>
#include <set>
#include <iostream>
#include <random>
#include <map>
#include <iomanip>
#include <stdlib.h>
#include <list>
#include <typeinfo>
#include <list>
#include <set>
#include <cassert>
#include <fstream>
#include <unordered_map>
#include <cstdlib>
#include <complex>
#include <cctype>
#include <bitset>
using namespace std;

using ll = long long;
using vll = vector<ll>;
using pll = pair<ll, ll>;
using qll = queue<ll>;
using vb = vector<bool>;
using mll = map<ll, ll>;
using sll = stack<ll>;
#define REP(i,n) for(ll i(0);(i)<(n);(i)++)
#define rep(i,n) for(ll i(0);(i)<(n);(i)++)
#define ALL(a) a.begin(), a.end()
#define enld endl //* missspell check
const ll INF = 1LL << 60;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a = b; return 1; } return 0; }
const long long MOD = 1000000007;

ll gcd (ll a, ll b){ return b == 0? a : gcd(b, a % b); }

//* calculate x^n mod something in O(log n) -- recursive version
ll mod_pow(ll x, ll n, ll mod){
    if(n == 0) return 1;
    ll res = mod_pow(x*x % mod, n/2, mod);
    if(n & 1) res = res * x % mod;
    return res;
}

void solve(long long N, std::vector<long long> A, std::vector<long long> B){
    ll numZero = 0;
    map<pll, pll> R;
    REP(i, N){
        if(A[i] == 0 && B[i] == 0) {numZero++; continue;}

        ll tmp = gcd(abs(A[i]), abs(B[i]));
        A[i] /= tmp; B[i] /= tmp;
        if(B[i]<0) {A[i] = -A[i]; B[i] = -B[i];}
        else if(A[i] < 0 && B[i] == 0)  {A[i] = -A[i]; B[i] = -B[i];}

        if(A[i] > 0){
            if(!R.count(make_pair(A[i], B[i]))){
                R[make_pair(A[i], B[i])] = make_pair(0, 0);
            }
            R[make_pair(A[i], B[i])].first++;
        }
        else{//* A[i] <= 0
            if(!R.count(make_pair(B[i], -A[i]))){
                R[make_pair(B[i], -A[i])] = make_pair(0, 0);
            }
            R[make_pair(B[i], -A[i])].second++;
        }
    }
    ll ans = 1;
    
    ll NNZ = N -  numZero;
    for(auto x: R){
        ll s = x.second.first, t = x.second.second;
        ll sm = s + t;
        ll now = 0;
        if(s == 0){
            now = mod_pow(2, t, MOD) ;
        }
        else if(t == 0){
            now = mod_pow(2, s, MOD);
        }
        else{//* both are not zero
            now = mod_pow(2, sm, MOD) ;
            ll diff = ((mod_pow(2, s, MOD) - 1) *  (mod_pow(2, t, MOD) - 1))% MOD;
            now = (now - diff) % MOD;
            
            if(now < 0) now += MOD;
            
        }
        ans = (ans * now) % MOD;
    }
    ans = (ans - 1) % MOD;
    while(ans < 0) ans += MOD;
    if(numZero > 0) ans = (ans + numZero) % MOD;
    
    cout<<ans<<endl;
}
int main(){
    long long N;
    scanf("%lld",&N);
    std::vector<long long> A(N);
    std::vector<long long> B(N);
    for(int i = 0 ; i < N ; i++){
        scanf("%lld",&A[i]);
        scanf("%lld",&B[i]);
    }
    solve(N, std::move(A), std::move(B));
    return 0;
}


Measured memory_bytes: 21628