#include <bits/stdc++.h>
#define lli long long int
#define pb push_back
#define mod 1000000007
#pragma GCC optimize ("-O2")
#define mod2 998244353
#define MAXN 1000000000
#define v32 vector<int>
#define v64 vector<lli>
#define v1024 vector <vector <int>>
#define v4096 vector <vector <lli>>
#define vt vector
#define f(x, y, z) for (lli x = y; x < z; x++)
#define fd(x, y, z) for (lli x = y; x > z; x--)
#define lb lower_bound
#define ld long double
#define m64 map<lli,lli>
#define m32 map<int,int>
#define m64it map<lli,lli>::iterator
#define m32it map<int,int>::iterator
#define fastio ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define ist insert
#define endl "\n"
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update> 
#define p_q priority_queue 
#define min_p_q priority_queue <pair<lli,int>,vt <pair<lli,int>>,greater <pair<lli,int>>>
using namespace std;
using namespace __gnu_pbds; 

//USE AT YOUR OWN RISK
lli tmod(lli x,lli m=mod){return (x%m+m)%m;}

template <typename T> 
void DEBUG_ARR(vt<T> a,char c)
{
	f(i,0,a.size())cout<<tmod(a[i])<<c;
	cout<<"\n";
}

//make sure x is below mod
lli power(lli x, lli y,lli m=mod) 
{
    lli res = 1;  
   
    while (y > 0) 
    { 
        if (y & 1) 
            res = (res*x)%m; 
        y = y>>1; 
        x = (x*x)%m;  
    }
    if(res<0)
       res+=m; 
    return res; 
}

lli fact[2000009];
lli ncr(lli n,lli r){
    lli ans=fact[n];
    if(r>n)return 1;
    if(r<0)return 0;
    if(n<0)return 0;
    ans=(ans*power(fact[n-r],mod-2))%mod;
    ans=(ans*power(fact[r],mod-2))%mod;
    return ans;
}


int main() 
{ 
    fact[0]=1;
    f(i,1,2000001)fact[i]=(i*fact[i-1])%mod;
    fastio;
    int t;
    // cin>>t;
    t=1;
    // int temp=t;
	while(t--){
        // cout<<"Case #"<<temp-t<<": ";
        // clock_t t=clock();
        lli n;
        cin>>n;
        map <pair<lli,lli>,lli> mp;
        f(i,0,n){
            lli a,b;cin>>a>>b;
            if(a==0 && b==0){
                mp[{0,0}]++;
                continue;
            }
            if(a<0){
                a=-a;
                b=-b;
            }
            else if(a==0){
                if(b<0)b=-b;
            }
            lli g=__gcd(a,b);
            if(g!=0){
                a/=g;
                b/=g;
            }
            
            mp[{a,b}]++;
        }
        lli total=0;
        for(auto x:mp){
            if(x.first.first==0 || x.first.second==0)continue;
            pair<lli,lli> temp={-x.first.second,x.first.first};
            if(temp.first<0){
                temp.first=-temp.first;
                temp.second=-temp.second;
            }
            total+=x.second*mp[temp];
        }
        total/=2;
        total+=(mp[{0,0}]*(n-mp[{0,0}])+(mp[{0,0}]*(mp[{0,0}]-1))/2);
        lli azero=0,bzero=0;
        for(auto x:mp){
            // if(x.first.first==0 && x.first.second==0)continue;
            if(x.first.first==0 && x.first.second!=0)azero+=x.second;
            else if(x.first.first!=0 && x.first.second==0)bzero+=x.second;
        }
        map <pair<lli,lli>,pair<lli,lli>> mp2;
        for(auto x:mp){
            if(x.first.first==0 || x.first.second==0)continue;
            pair<lli,lli> temp={-x.first.second,x.first.first};
            if(temp.first<0){
                temp.first=-temp.first;
                temp.second=-temp.second;
            }
            if(mp2.find(temp)!=mp2.end())continue;
            mp2.insert({x.first,{mp[x.first],mp[temp]}});
        }
        lli ans=0;
        for(auto x:mp2){
            // if(x==*mp2.begin())continue;
            ans=(ans+(1+ans)*(power(2,x.second.first)+power(2,x.second.second)-2))%mod;
        }
        ans=(ans+(1+ans)*(power(2,azero)+power(2,bzero)-2))%mod;
        ans+=mp[{0,0}];
        cout<<tmod(ans)<<"\n";
        // cout<<clock()-t<<"\n";
    }   
    return 0; 	
}
