#define TEMPLATE_USED
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef pair<ll,ll> pl;
typedef vector<pl> vp;
const ll INF=1001001001;
const ll LINF=1001001001001001001;
const ll D4[]={0,1,0,-1,0};
const ll D8[]={0,1,1,0,-1,-1,1,-1,0};
#define _overload3(_1,_2,_3,name,...) name
#define _rep2(i,n) for(ll i=0;i<(n);++i)
#define _rep3(i,a,b) for(ll i=(a);i<(b);++i)
#define rep(...) _overload3(__VA_ARGS__,_rep3,_rep2)(__VA_ARGS__)
#define _repe2(i,n) for(ll i=0;i<=(n);++i)
#define _repe3(i,a,b) for(ll i=(a);i<=(b);++i)
#define repe(...) _overload3(__VA_ARGS__,_repe3,_repe2)(__VA_ARGS__)
#define _rrep2(i,n) for(ll i=(n)-1;i>=0;i--)
#define _rrep3(i,a,b) for(ll i=(b)-1;i>=(a);i--)
#define rrep(...) _overload3(__VA_ARGS__,_rrep3,_rrep2)(__VA_ARGS__)
#define all(x) (x).begin(),(x).end()
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;}
template<class T>
using pq=priority_queue<T,vector<T>,greater<T>>;
const ll mod = 1000000007;

ll N;
vl A;
vl B;

void solve();

int main(){
    cin.tie(0);
    ios::sync_with_stdio(0);
    cin >> N;
    A = vl(N);
    B = vl(N);
    for(int i = 0; i < N; ++i){
        cin >> A[i];
        cin >> B[i];
    }
    solve();
}

// 入力はすべて整数
// 1 <= N <= 2 × 10^5
// -10^{18} <= A_i, B_i <= 10^{18}

#ifndef TEMPLATE_USED
#include "../template/template.hpp"
#endif

template<int m>
struct MInt{
    //static int m;

    ll x;
    MInt(ll x=0):x((x%m+m)%m){}

    MInt operator-()const{return MInt(-x);}
    MInt operator+(const MInt &p)const{return MInt(*this)+=p;}
    MInt operator-(const MInt &p)const{return MInt(*this)-=p;}
    MInt operator*(const MInt &p)const{return MInt(*this)*=p;}
    MInt operator/(const MInt &p)const{return MInt(*this)/=p;}

    MInt &operator+=(const MInt &p){
        if((x+=p.x)>=m)x-=m;
        return *this;
    }
    MInt &operator-=(const MInt &p){
        if((x+=m-p.x)>=m)x-=m;
        return *this;
    }
    MInt &operator*=(const MInt &p){
        (x*=p.x)%=m;
        return *this;
    }
    MInt &operator/=(const MInt &p){
        return *this*=p.inv();
    }

    MInt pow(ll n)const{
        MInt ret(1),mul(x);
        while(n){
            if(n&1)ret*=mul;
            mul*=mul;
            n>>=1;
        }
        return ret;
    }
    MInt inv()const{
        //return pow(m-2);
        int a=x,b=m,u=1,v=0,t;
        while(b){
            t=a/b;
            swap(a-=t*b,b);
            swap(u-=t*v,v);
        }
        return MInt(u);
    }

    friend ostream& operator<<(ostream& os,const MInt& a) {return os<<a.x;}
};
//int MInt::m=0;
using mint=MInt<mod>;

// ll N, vl A, vl B
// 答えを 1000000007 で割ったあまりを出力せよ。
void solve(){
    map<pl,ll> cnt1,cnt2;
    ll cnt0=0;
    rep(i,N){
        if(A[i]==0&&B[i]==0){
            ++cnt0;
            continue;
        }

        ll g=__gcd(abs(A[i]),abs(B[i]));
        A[i]/=g;
        B[i]/=g;
        //cerr<<A[i]<<' '<<B[i]<<endl;
        if(A[i]>0&&B[i]>0||A[i]<0&&B[i]<0){
            ++cnt1[pl(abs(A[i]),abs(B[i]))];
        }else if(A[i]>0&&B[i]<0||A[i]<0&&B[i]>0){
            ++cnt2[pl(abs(B[i]),abs(A[i]))];
        }else if(A[i]!=0){
            ++cnt1[pl(0,0)];
        }else{
            ++cnt2[pl(0,0)];
        }
    }

    mint ans=1;
    for(auto p:cnt1){
        mint tmp=mint(2).pow(p.second)+mint(2).pow(cnt2[p.first])-1;
        ans*=tmp;
    }
    for(auto p:cnt2){
        if(cnt1[p.first])continue;
        ans*=mint(2).pow(p.second);
    }
    cout<<ans+cnt0-1<<endl;
}


Measured memory_bytes: 31272