#include "bits/stdc++.h"
using namespace std;
#define REP(i, n) for(ll i = 0;i < n;i++)
#define ll long long
#define MOD 1000000007
#define llMAX 9223372036854775807
#define llMIN -9223372036854775808
using vi = vector<ll>; // intの1次元の型に vi という別名をつける
using vvi = vector<vi>; // intの2次元の型に vvi という別名をつける

ll n,k,x,y;


ll gcd(ll a,ll b){
  ll r = a % b;
  while(r!=0){
    a = b;
    b = r;
    r = a % b;
  }
return b;
}

//mapの使い方
#include <map>
ll moddiv(ll a,ll b){
	ll x0=MOD,x1=b,x2,n0=0LL,n1=1LL,n2,t=a%b,m,ans;
	if (t==0) return a/b;
		for(int i=0;i<900;i++){
      m=x0/x1;
      x2=x0-x1*m;
      n2=(n0-m*n1)%MOD;
      if (x2==1){
        ans=(n2+MOD)%MOD;
        break;
      }
      x0=x1;x1=x2;
      n0=n1;n1=n2;
    }
	return (a+((t*ans)%MOD)*b-t)/b;
}
//剰余の割ざん

//aのn乗 mod c
ll expmod(ll a,ll n){
  ll ans=1LL,aa=a,beki=n;
  for(int i=0;i<64;i++){
    if (beki%2==1) ans=ans*aa%MOD;
    aa=aa*aa%MOD;
    beki/=2;
    if (beki==0)break;
  }
  return ans;
}

//nCk
vi mulmod(500001);//0!,1!,2!,3!,4!,,,,
void first_nCk(){
  mulmod[0]=1;
  for(ll i=1;i<500001;i++){
    mulmod[i]=mulmod[i-1]*i%MOD;
  }
}
ll nCk(ll nn,ll kk){
  return moddiv(mulmod[nn],mulmod[kk]*mulmod[nn-kk]%MOD);
}







//469762049
//1811939329
//2013265921
//1000000007

int main(){
  ll ans=1;
  cin >> n ;

  vi md(4);
  md[0]=469762049;
  md[1]=1811939329;
  md[2]=2013265921;
  md[3]=1000000007;
  vi a(n),b(n),pm(n);
  vvi h(n, vi(4));  // N * M の2次元配列
  REP(i,n) cin>>a[i]>>b[i];

  REP(i,n){
    if (a[i]<0){
      pm[i]++;
      //a[i]=-a[i];
    }
    if (b[i]<0){
      pm[i]++;
      //b[i]=-b[i];
    }

    for(ll j=0;j<4;j++){
      h[i][j]=(a[i]%md[j])*(b[i]%md[j])%md[j];
    }
  }




  vector<pair<ll, ll>> pa(n);
  map<pair<ll, ll>, ll> nums;
  ll w=1;
  ll azc=0;//aが0の個数
  ll bzc=0;//bが0の個数
  ll abzc=0;//abが0の個数
  for(ll i=0;i<n;i++){

    /*
    pa[i].first=h[i][0]*(1LL<32LL)+h[i][1];
    pa[i].second=h[i][2]*(1LL<32LL)+h[i][3];
    */
    if ((a[i]==0)&(b[i]==0)){
      abzc++;
      continue;
    }
    
    if ((a[i]==0)){
      azc++;
      continue;
    }

    if ((b[i]==0)){
      bzc++;
      continue;
    }

    ll c=gcd(abs(a[i]),abs(b[i]));
    a[i]/=c;
    b[i]/=c;
    //if (pm[i]%2==1)a[i]=-a[i];
    pa[i].first=abs(a[i]);
    pa[i].second=abs(b[i]);
    if (pm[i]%2==1)pa[i].first*=-1;


    
    //if ( nums.find(pa[i]) == end(nums) ) {
      nums[pa[i]]++;//=w;
      //w++;
    //}
  }



  /*
  vi id(n);
  map<ll, ll> idnums;
  for(ll i=0;i<n;i++){
    id[i]=nums[pa[i]];
    //if (pm[i]%2==1)id[i]*=-1;
    idnums[id[i]]++;
  }


    for (auto it : idnums) {
        long long num = it.second; // it.first が it.second 個ある
        cout<<it.first<<" "<<it.second<<endl;
    }




  for(ll i=1;i<=n;i++){
    ll n0=idnums[i];
    ll n1=idnums[-i];

    ll nn=expmod(2,n0)-1;
    nn+=expmod(2,n1)-1;
    nn=(nn+MOD+1)%MOD;

    ans=ans*nn%MOD;
  }
  */
 
    for (auto it : nums) {
        long long num = it.second; // it.first が it.second 個ある
        auto iit=it.first;
        ll da=iit.first;
        ll db=iit.second;
        //cout<<da<<" ! "<<db<<" "<<num<<endl;
        pair<ll, ll> pl;
        pl.first=-db;
        pl.second=da;
        if ((pl.first<0)&(pl.second<0)){
          pl.first=-pl.first;
          pl.second=-pl.second;
        }
        ll ct=nums[pl];

        nums[iit]=0;
        nums[pl]=0;
        
        ll nn=expmod(2,num)-1;
        nn+=expmod(2,ct)-1;
        nn=(nn+MOD+1)%MOD;
        ans=ans*nn%MOD;


        //cout<<it.first<<" "<<it.second<<endl;
    }



  
  ll nn=expmod(2,azc)-1;
  nn+=expmod(2,bzc)-1;
  nn=(nn+MOD+1)%MOD;
  ans=ans*nn%MOD;

  if (abzc==0)
  {
    ans=(ans+MOD-1)%MOD;
  }
  else
  {
    ans=(ans+abzc-1)%MOD;
  }
  

  cout<<ans<<endl;
  return 0;
}


Measured memory_bytes: 53824