/*
AUTHOR: Aman Raj
LANG: C++
*/

using namespace std;

typedef   long long ll;
#include <bits/stdc++.h>


//setbase - cout << setbase (16); cout << 100 << endl; Prints 64
//setfill -   cout << setfill ('x') << setw (5); cout << 77 << endl; prints xxx77
//setprecision - cout << setprecision (14) << f << endl; Prints x.xxxx
//cout.precision(x)  cout<<fixed<<val;  // prints x digits after decimal in val
#define fast  ios_base::sync_with_stdio(false); cin.tie(0);  cout.tie(0);
#define all(a) a.begin(),a.end()
//#define mod 998244353
#define mod 100000007
#define inf 1e18
//#define mod 3
#define flush fflush(stdout)

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef cc_hash_table<ll, ll, hash<ll> > ht;

// find_by_order()  // order_of_key
typedef tree<
    int,
    null_type,
    less<long long int>,
    rb_tree_tag,
    tree_order_statistics_node_update>
    ordered_set;






ll power1(ll a, ll b)//a raised to power b
   {  if(b<=0) return 1; if(b==1) return a;
       ll c=power1(a,b/2);
        c*=c;c=c%mod;if(b%2==1) c*=a;c=c%mod;
        return c;
   }
   ll mi(ll a,ll m)
   { ll c= power1(a,m-2);

     return c;
   }



 struct less_then_greater {
    template<typename T, typename U>
    bool operator()(T const& lhs, U const& rhs) const {
        if (lhs.first < rhs.first) return true;
        if (rhs.first < lhs.first) return false;
        return lhs.second > rhs.second;
    }
};
 /*std::priority_queue<std::pair<int, int>,
                    std::vector<std::pair<int, int>>,
                    less_then_greater
                   > pq;*/


ll n;

  int main()
{    fast;
    cin>>n;

       map<pair<ll,ll>,ll> mpp;
       vector<ll> v;
       ll ans2=0;
       ll first=0,second=0;
       for(ll i=0;i<n;i++)
       {
           ll a,b;cin>>a>>b;
           if(a==0&&b==0){ ans2++;continue;  }
           if(a==0){ first++;continue; }
           if(b==0){ second++;continue; }
            bool neg=true;
            if(a*b>=0)neg=false;
            a=abs(a);b=abs(b);
              ll g=__gcd(a,b);
            a/=g;b/=g;
             if(!neg)mpp[{a,b}]++;
             else mpp[{-a,b}]++;
       }
        ll h=power1(2,first)+power1(2,second)-1;h+=mod;h%=mod;
        v.push_back(h);
         ll ans=1;
       for(auto x:mpp)
       {
           ll a=x.first.first,b=x.first.second;
            //cout<<a<<" "<<b<<" "<<x.second<<endl;
           bool neg=true;
            if(a*b>=0)neg=false;
             a=abs(a);b=abs(b);
           if(neg){ auto y=mpp.find({b,a});
                if(y!=mpp.end())
                     {  ll h=power1(2,x.second)+power1(2,y->second)-1;h+=mod;h%=mod;
                         v.push_back(h);
                          mpp.erase(y);
                     }
                    else v.push_back(power1(2,x.second));
                    }
           else
           { auto y=mpp.find({-b,a});
               if(y!=mpp.end())
                     {  ll h=power1(2,x.second)+power1(2,y->second)-1;h+=mod;h%=mod;
                         v.push_back(h);
                        mpp.erase(y);
                     }
                    else v.push_back(power1(2,x.second));
           }

       }
       for(auto x:v )
       { //cout<<x<<endl;
           ans*=x;ans%=mod;
       }
  ans-=1;ans+=mod+ans2;ans%=mod;
  cout<<ans<<endl;

        return 0;
}
