    //For higher stack size use g++ -O2 -std=c++11 -Wall -Wl,--stack=268435456 a.cpp -o a.exe in cmd
    #include <bits/stdc++.h>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <cstring>
    #include <chrono>
    #include <complex>
    #define ll long long
    #define ld long double
    #define vi vector<int>
    #define vll vector<ll>
    #define vvi vector < vi >
    #define pii pair<int,int>
    #define pll pair<long long, long long>
    #define mod 1000000007
    #define inf 1000000000000000001;
    #define all(c) c.begin(),c.end()
    #define mp(x,y) make_pair(x,y)
    #define mem(a,val) memset(a,val,sizeof(a))
    #define eb emplace_back
    #define pb push_back
    #define f first
    #define s second
    
    using namespace std;

    ll power(ll a, ll b)    //a is base, b is exponent
    {
        if(b==0)
            return 1;
        if(b==1)
            return a;
        if(b%2 == 1)
            return (power(a,b-1)*a)%mod;
        ll q = power(a,b/2);
        return (q*q)%mod;
    }

    // Disjoint Set DataStructure
    int parent[200001];         // reserve space for map if n > 10000
    int urank[200001],sz[200001];

    void create(ll x)
    {
        parent[x] = x ;
        urank[x] = 1 ;         // rank = no. of nodes in its subtree
        sz[x]=1;
    }

    ll find(ll x)
    {
        if( parent[x] != x )    //path compression
        {
            parent[x] = find(parent[x]) ;
        }
        return parent[x];
    }

    void merge(ll x, ll y)
    {
        ll xroot = find(x);
        ll yroot = find(y);
        if(xroot == yroot)
            return;
        if( urank[xroot] <= urank[yroot] )    // Union by rank
        {
            parent[xroot] = yroot ;
            sz[yroot]+=sz[xroot];
            urank[yroot] = urank[yroot] + urank[xroot] ;
        }
        else
        {
            parent[yroot] = xroot;
            sz[xroot]+=sz[yroot];
            urank[xroot] = urank[xroot] + urank[yroot] ;
        }
    }



    int main()
    {
        std::ios::sync_with_stdio(false);
        int T;
        T=1;
        // cin.ignore(); must be there when using getline(cin, s)
        while(T--)
        {
            ll n,i,j,a,b,x;
            cin>>n;
            pll ar[n+1];
            ll ct=0,ct2=0;
            map<pll,ll> mp,mp2;
            ll ans=0;
            for(i=1;i<=n;++i)
                create(i);
            for(i=1;i<=n;++i)
            {
                cin>>a>>b;
                ar[i].f=a,ar[i].s=b;
                if(a==0 && b==0)
                    continue;
                if(a==0)
                {
                    ++ct;
                }
                else if(b==0)
                {
                    ++ct2;
                }
                else
                {
                    x=__gcd(a,b);

                    a=a/x;
                    b=b/x;
                    
                    if(a<0 && b<0)
                    {
                        a=a*-1;
                        b=b*-1;
                    }
                    // cout<<i<<":::"<<a<<" "<<b<<endl;
                    ++mp[{a,b}];
                }
            }
            vector<pll> v;
            for(auto it:mp)
            {
                a=it.f.f,b=it.f.s;
                if(mp2.find({a,b})!=mp2.end())
                    continue;
                mp2[{a,b}]=1;
                
                x=-b;
                b=a;
                a=x;
                if(a<0 && b<0)
                {
                    a=a*-1;
                    b=b*-1;
                }
                if(mp.find({a,b})!=mp.end())
                {
                    v.pb({it.s,mp[{a,b}]});
                }
                else
                {
                    v.pb({it.s,0});
                }

                mp2[{a,b}]=1;
            }

            sort(v.begin(),v.end());

            ans=1;
            ll ans2=0;
            for(auto it:v)
            {
                // cout<<it.f<<" "<<it.s<<endl;
                x=it.f;
                ans2=ans;
                ans2=((ans)*power(2,x))%mod;
                x=it.s;
                if(x!=0)
                {
                    ans2=(ans2+(ans)*(power(2,x)-1+mod)%mod)%mod;
                    
                }

                ans=ans2;
                // cout<<ans<<endl;
            }
            ans=(ans-1+mod)%mod;
            ans = (ans*((power(2,ct) + power(2,ct2) - 1 + mod)%mod))%mod;
            cout<<ans<<endl;
        }
        return 0;
    }
