#include <cmath>
#include <cstdio>
#include <cstring>
#include <cassert>
#include <iostream>
#include <algorithm>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <vector>
using namespace std;
typedef long long int64;
typedef long double ldb;
typedef pair<int,int> pii;
typedef pair<int64, int64> pll;

const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
const int SIZE = 19260817;

const int MAX_N = 2e5;

map<ldb,int> cnt[SIZE];
int64 A[MAX_N], B[MAX_N];
int64 gcd(int64 a,int64 b){
	if(b == 0)	return a;
	return gcd(b,a%b);
}
int power(int64 a,int64 n,int64 M){
	a %= M;
	int64 ret = 1;
	while(n){
		if(n&1)	ret = a*ret%M;
		a = a*a%M;
		n >>= 1;
	}
	return ret;
}

int my_hash(int64 x,int64 y){
	x %= SIZE, y %= SIZE;
	if(x < 0)	x += SIZE;
	if(y < 0)	y += SIZE;
	return y%SIZE*power(x,SIZE-2,SIZE)%SIZE;
}

int solve(int N){
	int zero = 0, X = 0, Y = 0;
	int64 ret = 1;
	for (int i = 0; i < N; ++i){
		if(A[i] == 0 && B[i] == 0)	++zero;
		else if(A[i] == 0)	++X;
		else if(B[i] == 0)	++Y;
		else{
			int64 d = gcd(abs(A[i]),abs(B[i]));

			A[i] /= d, B[i] /= d;
			ldb k = ldb(B[i])/ldb(A[i]);

			int h = my_hash(A[i],B[i]);
			cnt[h][k] = cnt[h][k]+1;
		}
	}
	for(int h = 0; h < SIZE; ++h)
	for (map<ldb,int>::iterator itr = cnt[h].begin();
			itr != cnt[h].end(); ++itr){
		ldb k = itr->first; int num = itr->second;
		int rh = (SIZE-power(h,SIZE-2,SIZE))%SIZE;
		ret = ret*((power(2,num,MOD)+power(2,cnt[rh][-1/k],MOD)-1)%MOD)%MOD;
		cnt[h][k] = cnt[rh][-1/k] = 0;
	}

	ret = ret*(power(2,X,MOD)+power(2,Y,MOD)-1)%MOD;
	ret = (ret+power(2,zero,MOD)-1)%MOD;
	ret = (ret-1+MOD)%MOD;
	assert(ret > 0);
	return ret;
}

int main(){
	int N;
	scanf("%d",&N);
	for (int i = 0; i < N; ++i)	scanf("%lld%lld",A+i,B+i);

	int ans = solve(N);
	printf("%d\n",ans);
}