#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
using namespace std;
struct __INIT{__INIT(){cin.tie(0);ios::sync_with_stdio(false);cout<<fixed<<setprecision(15);}} __init;
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
constexpr int MOD=1000000007;
//constexpr int MOD=998244353;
#define INF (1<<30)
#define LINF (lint)(1LL<<56)
#define endl "\n"
#define rep(i,n) for(lint (i)=0;(i)<(n);(i)++)
#define reprev(i,n) for(lint (i)=(n-1);(i)>=0;(i)--)
#define Flag(x) (1<<(x))
#define Flagcount(x) __builtin_popcount(x)
#define pint pair<int,int>
#define pdouble pair<double,double>
#define plint pair<lint,lint>
#define fi first
#define se second
typedef long long lint;
int dx[8]={1,1,0,-1,-1,-1,0,1};
int dy[8]={0,1,1,1,0,-1,-1,-1};
const int MAX_N=2e5+5;

lint powmod(lint a,lint b){
  return b?powmod(a*a%MOD,b/2)*(b%2?a:1)%MOD:1;
}

lint fac[510000],finv[510000],inv[510000];
void COMinit(){
  fac[0]=fac[1]=1;
  finv[0]=finv[1]=1;
  inv[1]=1;
  for(int i=2;i<510000;i++){
    fac[i]=fac[i-1]*i%MOD;
    inv[i]=MOD-inv[MOD%i]*(MOD/i)%MOD;
    finv[i]=finv[i-1]*inv[i]%MOD;
  }
}
lint COM(lint n,lint k){
  if (n<k) return 0;
  if (n<0 || k<0) return 0;
  return fac[n]*(finv[k]*finv[n-k]%MOD)%MOD;
}
lint facdiv(lint n,lint k){
  if (n<k) return 0;
  if (n<0 || k<0) return 0;
  return (fac[n]*finv[k])%MOD;
}

lint LCM(lint a,lint b){
  if(a==0 || b==0) return 0;
  lint tmp,r,x;
  x=a*b;
  if(a<b) tmp=a,a=b,b=tmp;
  r=a%b;
  while(r!=0) a=b,b=r,r=a%b;
  x=x/b;
  return x;
}

lint GCD(lint a,lint b){
  if(a==0 || b==0) return max(a,b);
  else return (a*b)/LCM(a,b);
}


int main(void){
    COMinit();
    lint N;
    cin >> N;
    lint A[N],B[N];
    lint ans=(powmod(2,N)-1+MOD)%MOD;
    rep(i,N){
        cin >> A[i] >> B[i];
        bool m1=false,m2=false;
        if(A[i]<0) m1=true,A[i]*=-1;
        if(B[i]<0) m2=true,B[i]*=-1;
        lint di=__gcd(A[i],B[i]);
        A[i]/=di,B[i]/=di;
        if(m1) A[i]*=-1;
        if(m2) B[i]*=-1;
    }
    map<plint,int> vec;
    lint keisu[N];
    rep(i,N) keisu[i]=1;
    lint p=0;
    rep(i,N){
        vec[plint(A[i],B[i])]++;
        vec[plint(-A[i],-B[i])]++;
        if(vec[plint(-B[i],A[i])]>=1 &&vec[plint(-A[i],-B[i])]==1) p++;
    }
    rep(i,N){
        lint cnt=vec[plint(-B[i],A[i])];
        lint m1=vec[plint(A[i],B[i])];
        lint minus=((powmod(2,cnt)-1+MOD)*(powmod(2,N-1-i-cnt)))%MOD;
        if(p>1) minus=(minus+powmod(2,N-1-i-cnt-2))%MOD;
        ans=(ans-minus+MOD)%MOD;
        vec[plint(A[i],B[i])]--;
        vec[plint(-A[i],-B[i])]--;
        if(vec[plint(-B[i],A[i])]>=1 &&vec[plint(-A[i],-B[i])]==0) p--;
    }
    cout << ans << endl;
}
