#include<bits/stdc++.h>
using namespace std;

using lnt = long long;
using Real = long double;

#define ALL(obj) (obj).begin(),(obj).end()
#define RALL(obj) (obj).rbegin(),(obj).rend()
#define REP(i, n) for(lnt i=0;i<(n);++i)
#define RANGE(i, a, b) for(lnt i=(a);i<(b);++i)
#define RREP(i, n) for(lnt i=(n)-1;i>= 0;--i)

#define ln '\n'
#define pb push_back
#define eb emplace_back
#define pque priority_queue
#define umap unordered_map
#define uset unordered_set
#define dcout cout<<fixed<<setprecision(20)
#define summon_tourist cin.tie(0);ios::sync_with_stdio(false)

constexpr int dx[]={1,0,-1,0,1,1,-1,-1}, dy[]={0,-1,0,1,1,-1,1,-1};
constexpr Real eps = 1e-9; const Real pi = acosl(-1);
constexpr lnt BIG = INT_MAX/10, BBIG = LLONG_MAX/10;

template<class T> inline T GCD(T a,T b){T c;while(b!=0){c=a%b;a=b;b=c;}return a;}
template<class T> inline T LCM(T a,T b){T c=GCD(a,b);a/=c;return a*b;}
template<class T> inline T nCr(T a,T b){T i,r=1;for(i=1;i<=b;i++){r*=(a+1-i);r/=i;}return r;}
template<class T> inline T nHr(T a,T b){return nCr(a+b-1,b);}
template<class T> inline bool chmax(T& a,T b){if(a<b){a=b;return 1;}return 0;}
template<class T> inline bool chmin(T& a,T b){if(a>b){a=b;return 1;}return 0;}

using pint = pair<int, int>; using plnt = pair<lnt, lnt>;
using vint = vector<int>; using vlnt = vector<lnt>;
constexpr lnt MOD = 1e9+7;

lnt powmod(lnt a, lnt p, lnt m){
	lnt res = 1, tmp = a;
	while(p != 0){
		if(p % 2) res = (res*tmp) % m;
		tmp = (tmp*tmp) % m;
		p /= 2;
	}
	return res;
}

int main(){
	summon_tourist;

	lnt N, A, B; cin >> N;
	lnt ans = 0;

	map<plnt, lnt> mpa, mpb;
	vector<plnt> vec;
	set<plnt> check;

	REP(i, N){
		cin >> A >> B;
		if(A == 0 and B == 0) ans++;
		else {
			lnt g = __gcd(A, B);
			A /= g; B /= g;
			if(A == 0 and B != 0){
				mpb[{A, B}]++;
			} else if(A != 0 and B == 0){
				mpa[{A, B}]++;
			} else {
				if((A>0) xor (B>0)){
					mpb[{A, B}]++;
				} else {
					mpa[{A, B}]++;
				}
			}
			vec.eb(A, B);
		}
	}

	lnt plus = 1;
	for(auto p: vec){
		if(check.count(p)) continue;

		check.insert(p);
		check.insert({-p.first, -p.second});
		check.insert({p.second, -p.first});
		check.insert({-p.second, p.first});
		lnt num = 1;

		if(!(p.first > 0 xor p.second > 0)){
			lnt a = mpa[p] + mpa[{-p.first, -p.second}];
			lnt b = mpb[{p.second, -p.first}] + mpb[{-p.second, p.first}];
			num = (powmod(2, a, MOD) + powmod(2, b, MOD) - 1) % MOD;
		} else if(p.first > 0 xor p.second > 0){
			lnt a = mpb[p] + mpb[{-p.first, -p.second}];
			lnt b = mpa[{p.second, -p.first}] + mpa[{-p.second, p.first}];
			num = (powmod(2, a, MOD) + powmod(2, b, MOD) - 1) % MOD;
		}
		plus *= num; plus %= MOD;
	}

	ans += plus; ans %= MOD;
	ans = (ans-1+MOD) % MOD;
	
	cout << ans << ln;
}