#include<map>
#include<cctype>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
using i64=long long;
i64 read(){i64 x=0;int c=getchar(),f=1;while(isspace(c))c=getchar();if(c=='-')f=-1,c=getchar();while(isdigit(c))(x*=10)+=c&15,c=getchar();return f*x;}
const int N=200007,P=1000000007;
struct frac{i64 x,y;}imp[N];
int operator<(frac a,frac b){return a.x<b.x||(a.x==b.x&&a.y<b.y);}
map<frac,int>mp;
int size[N],vis[N],cnt,c1,c2,c3;
int pow(int a,int b){int r=1;for(;b;b>>=1,a=1ll*a*a%P)if(b&1)r=1ll*a*r%P;return r;}
void ins(i64 a,i64 b)
{
    frac f=frac{a,b};
    if(!mp.count(f)) mp[f]=++cnt,imp[cnt]=f,size[cnt]=1; else ++size[mp[f]];
}
int main()
{
    int n=read();i64 ans;
    for(int i=1;i<=n;++i)
    {
	i64 a=read(),b=read(),d=__gcd(a,b);
	if(!a&&!b) {++c3;continue;}
	if(!a) {++c1;continue;}
	if(!b) {++c2;continue;}
	a/=d,b/=d;
	if(a<0&&b<0) a*=-1,b*=-1;
	if(b<0) a*=-1,b*=-1;
	ins(a,b);
    }
    ans=(pow(2,c1)+pow(2,c2)-2)%P;
    for(int i=1;i<=cnt;++i)
    {
	if(vis[i]) continue;
	frac g=imp[i];int x=0;
	swap(g.x,g.y),g.x*=-1;
	if(g.y<0) g.x*=-1,g.y*=-1;
	if(mp.count(g)) x=mp[g];
	ans=((ans+1)*(pow(2,size[i])+pow(2,size[x])-1)-1)%P;
	vis[x]=vis[i]=1;
    }
    ans=((ans+1)*(c3+1)-1)%P;
    cout<<ans;
}
