#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <cmath>
#include <set>
#include <algorithm>

typedef long long ll;
const ll MOD = 1e9 + 7;
const long long INF = 1LL<<60;
const double PI=3.14159265358979323846;
const int NMAX=200005;
using namespace std;

ll fact[NMAX+12];
ll invfact[NMAX+12];

ll pow(ll a, ll b) {
  if (b == 0) {
    return 1;
  } else if (b % 2 == 0) {
    ll d = pow(a, b / 2);
    return (d * d) % MOD;
  } else {
    ll d = pow(a, b - 1);
    return (a * d) % MOD;
  }
}

ll gcd(ll a, ll b)
{
   if (a%b == 0)
   {
       return(b);
   }
   else
   {
       return(gcd(b, a%b));
   }
}

int main(){
    ll n;
    cin >> n;
    vector<ll> a(n),b(n);
    for(int i = 0; i < n; i++){
        cin >> a[i] >> b[i];
    }
    map<pair<ll,ll>,ll> ab,ba;
    ll zeros = 0, zeroa = 0, zerob = 0;
    for(int i = 0; i < n; i++){
        if(a[i] == 0 && b[i] == 0){
            zeros++;
            continue;
        }
        if(a[i] == 0){
            auto p = make_pair(1,0);
            if(ba.find(p) == ba.end()){
                ba.insert(make_pair(p,1));
            } else {
                ba[p]++;
            }
            continue;
        } else if(b[i] == 0){
            auto p = make_pair(1,0);
            if(ab.find(p) == ab.end()){
                ab.insert(make_pair(p,1));
            } else {
                ab[p]++;
            }
            continue;
        }
        ll g = gcd(a[i],b[i]);
        ll tmpa = a[i]/g;
        ll tmpb = b[i]/g;
        if(abs(tmpa) > abs(tmpb)){
            if(tmpb < 0){
                tmpa = 0-tmpa;
                tmpb = 0-tmpb;
            }
            auto p = make_pair(tmpa,tmpb);
            if(ab.find(p) == ab.end()){
                ab.insert(make_pair(p,1));
            } else {
                ab[p] += 1;
            }
        } else if(abs(tmpa) == abs(tmpb)){
            if(tmpa == tmpb){
                if(tmpa < 0){
                    tmpa = 0-tmpa;
                    tmpb = 0-tmpb;
                }
                auto p = make_pair(tmpa,tmpb);
                if(ab.find(p) == ab.end()){
                    ab.insert(make_pair(p,1));
                } else {
                    ab[p] += 1;
                }    
            } else {
                if(tmpb < 0) tmpb = 0-tmpb;
                else tmpa = 0-tmpa;
                auto p = make_pair(tmpb,tmpa);
                if(ba.find(p) == ba.end()){
                    ba.insert(make_pair(p,1));
                } else {
                    ba[p] += 1;
                }
            }
        } else {
            if(tmpa < 0){
                tmpa = 0-tmpa;
                tmpb = 0-tmpb;
            }
            tmpb = 0-tmpb;
            auto p = make_pair(tmpb,tmpa);
            if(ba.find(p) == ba.end()){
                ba.insert(make_pair(p,1));
            } else {
                ba[p] += 1;
            }
        }
    }

    ll ans = 1;
    for(auto it = ab.begin(); it != ab.end(); it++){
        auto key = it->first;
        ll value = it->second;
        ll tmp = (pow(2ll,value)) % MOD;
        if(ba.find(key) != ba.end()){
            ll match = 1;
            match = ba[key];
            tmp = tmp+(pow(2ll,match)-1)%MOD;
        }
        ans *= tmp;
        ans %= MOD;
    }
    for(auto it = ba.begin(); it != ba.end(); it++){
        auto key = it->first;
        ll value = it->second;
        if(ab.find(key) == ab.end()){
            ll tmp = (pow(2ll,value))%MOD;
            ans *= tmp;
            ans %= MOD;
        }
    }
    
    // ll tmp = 1;
    // if(zeroa != 0) tmp *= pow(2ll,zeroa);
    // tmp %= MOD;
    // if(zerob != 0) tmp += pow(2ll,zerob);
    // tmp %= MOD;
    // if(zeroa != 0 && zerob != 0) tmp -= 1;
    // ans = ans*tmp%MOD;

    if(zeros != 0){
        ans += zeros;
        ans %= MOD;
    }
    ans -= 1;
    if(ans < 0) ans += MOD;

    cout << ans%MOD << endl;

    return 0;
}

Measured memory_bytes: 18640