//  [c]
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define ll long long
#define INF 1<<31-1
#define LNF 9223372036854775807
#define PI 3.14159265358979
#define MIN(x,y) ((x)<(y)?(x):(y))
#define MAX(x,y) ((x)<(y)?(y):(x))
#define FOR(i,a,n) for(i=a;i<n;i++)
#define MOD 1000000007
//#define MOD 998244353
#define NUM 200010
 
void swap(int* a,int* b){int tmp=*a;*a=*b;*b=tmp;}
int abs(int a){if(a<0)return -a;return a;}
int dup(int a,int d){if(a%d==0)return a/d;else return a/d+1;}
int mod(int a,int m){if(a<0)return a%m+m;else return a%m;}

void swapl(ll* a,ll* b){ll tmp=*a;*a=*b;*b=tmp;}
ll absl(ll a){if(a<0)return -a;return a;}
ll dupl(ll a,ll d){if(a%d==0)return a/d;else return a/d+1;}
ll modl(ll a,ll m){if(a<0)return a%m+m;else return a%m;}
ll signl(ll a) {return a==0 ? 0 : (a>0? 1 : -1);}

ll GCD(ll a,ll b){ll c=1,tmp=MAX(a,b);b=MIN(a,b);a=tmp;while(c!=0){c=a%b;a=b;b=c;}return a;}
ll LCM(ll a,ll b){return a*b/GCD(a,b);}

ll factorial(ll n, ll m) {return n < m ? 1 : n*factorial(n-1, m);}

int upll(const void*a, const void*b){return*(ll*)a<*(ll*)b?-1:*(ll*)a>*(ll*)b?1:0;}
int downll(const void*a, const void*b){return*(ll*)a<*(ll*)b?1:*(ll*)a>*(ll*)b?-1:0;}
void sortup(ll*a,int n){qsort(a,n,sizeof(ll),upll);}
void sortdown(ll*a,int n){qsort(a,n,sizeof(ll),downll);}


typedef struct
{
    ll a;
    ll b;
} box;

int cmp(box *p,box *q){
	if((*(box*)p).a<(*(box*)q).a)return -1;
	if((*(box*)p).a>(*(box*)q).a)return 1;
	if((*(box*)p).b<(*(box*)q).b)return -1;
	if((*(box*)p).b>(*(box*)q).b)return 1;
	return 0;
}
int boxa_downll(const void*a, const void*b){return cmp((box*)a, (box*)b);}

ll pow2l(ll n){
    if (n == 0)
    {
        return 1;
    }
    return (2*pow2l(n-1)%MOD);
}

ll pom(ll a,ll n,int m){ll x=1;for(a%=m;n;n/=2)n&1?x=x*a%m:0,a=a*a%m;return x;}


int main(){
    box p[400000];
    box m[400000];
    ll pn=0, mn=0, zn0=0 , zn1=0, zn2=0, n, k;
    ll a, b, gcdab;
    ll i, j, ans=0;
    ll u, v;

    scanf("%lld", &n);    
    
    for (i = 0; i < n; i++)
    {
        scanf("%lld%lld", &a, &b);

        if (signl(a) * signl(b) == 0) {
            if(a == 0 && b==0) zn0++;
            else if(a == 0) zn1++;
            else zn2++;
        }
        else if(signl(a) * signl(b) > 0) {
            a = absl(a), b = absl(b);
            gcdab = GCD(a, b);
            a /= gcdab;
            b /= gcdab;
            p[pn].a = a;
            p[pn].b = b;
            pn++;
        }
        else
        {
            a = absl(a), b = absl(b);
            gcdab = GCD(a, b);
            a /= gcdab;
            b /= gcdab;
            // uetohatigau
            m[mn].a = b;
            m[mn].b = a;    
            mn++;
        }
    }

    qsort(p,pn,sizeof(box), boxa_downll);
    qsort(m,mn,sizeof(box), boxa_downll);

    ans = MOD - 1;
    ans = (ans + pow2l(zn1))%MOD;
    ans = (ans + pow2l(zn2))%MOD;

    i=j=0;
    while(i < pn && j < mn){
        if(cmp(&p[i], &m[j]) == 0) {
            for (u = 1; i + u < pn; u++) if (cmp(&p[i], &p[i+u]) != 0) break;
            for (v = 1; j + v < mn; v++) if (cmp(&m[j], &m[j+v]) != 0) break;
            
            k = MOD - 1;
            k = (k + pom(2, u, MOD))%MOD;
            k = (k + pom(2, v, MOD))%MOD;

            ans = ans * k % MOD;

            i += u;
            j += v;
        }
        else {
            ans = ans * 2 %MOD;

            if(cmp(&p[i], &m[j]) < 0) i++;
            else j++;
        }
    }

    ans = ans*pow2l(pn-i)%MOD;
    ans = ans*pow2l(mn-j)%MOD;

    // 0,0 の場合
    ans = (ans + zn0) % MOD;

    ans = (MOD + ans - 1) % MOD;

    printf("%lld\n", ans);

    return 0;
}