#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define pi acos(-1.0)
#define eps 1e-9
#define ll long long
#define ull unsigned long long
#define sf scanf
#define pf printf
#define nl printf("\n")
#define ps(s) printf("%s",s.c_str())
#define	inf (ll)1e15
#define mod 1000000007
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend() 
#define sz(x) (int)(x).size()
#define test_case int ___t;scanf("%d", &___t);for(int cs=1;cs<=___t;cs++)

using namespace __gnu_pbds;
using namespace std;

inline string str_inp(int n){char ch[n+5];sf(" %s",ch);return string(ch);}
inline string line_inp(int n)
{char ch[n+5];fgets(ch,n+5,stdin);string s=string(ch);s.pop_back();return s;}

//typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> new_data_set;
typedef pair<ll,ll>pll;

const int S=200100;
ll p2[S+5];

pll Normalize(ll a,ll b)
{
	if(a==0 && b==0)return pll(a,b);
	else if(a<0 && b<0)
	{
		a=-a;
		b=-b;
	}
	else if(b<0)
	{
		a=-a;
		b=-b;
	}

	ll g=__gcd(abs(a),abs(b));
	return pll(a/g,b/g);
}

int main()
{
    //#ifndef ONLINE_JUDGE
    freopen("input.txt","r",stdin);
    //#endif
    p2[0]=1;
	for(int i=1;i<=S;i++)
	{
		p2[i]=p2[i-1]*2;
		p2[i]%=mod;
	}

	int n;
	while(~sf("%d",&n))
	{
		map<pll,ll>mp;
		for(int i=0;i<n;i++)
		{
			ll a,b;
			sf("%lld %lld",&a,&b);
			tie(a,b)=Normalize(a,b);
			mp[pll(a,b)]++;
		}

		ll ans=1,zero=0;
		for(auto e:mp)
		{
			ll a,b;
			tie(a,b)=e.first;
			ll val=e.second;
			
			if(a==0 && b==0)zero=val;
			else
			{
				ll x=0;
				x=p2[val];
				mp[pll(a,b)]=0;
				
				//complement of pair (a,b)
				ll xc=0;

				ll ac,bc;
				if(a>0)ac=-b,bc=a;
				else ac=b,bc=-a;

				xc=mp[pll(ac,bc)];
				xc=p2[xc];
				mp[pll(ac,bc)]=0;

				ll sum=(x+xc-1)%mod;
				ans=(ans*sum)%mod;
			}
		}
		pf("%lld\n",(ans+zero-1+mod)%mod);
	}
    return 0;
}
 




































