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

using namespace std;
using namespace __gnu_pbds;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> indexed_set;
mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());
const double pi = 3.14159265358979;

const int mod = 1e9 + 7;
int n;

long long gcd(long long a, long long b){
	if(b == 0) return a;
	else return gcd(b, a % b);
}

long long modpow(long long a, long long b){
	if(b == 0) return 1;
	long long ret = modpow(a, b / 2);
	ret = (ret * ret) % mod;
	if(b % 2) ret = (ret * a) % mod;
	return ret;
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cin >> n;
	map<tuple<int, long long, long long>, pair<long long, long long>> rec;
	for(int i = 0; i < n; i++){
		long long a, b;
		cin >> a >> b;
		int sig = 1;
		if(a / abs(a) != b / abs(b)) sig = -1;
		a = abs(a), b = abs(b);
		if(b == 0) a = 1, b = 0;
		else{
			long long com = gcd(a, b);
			a /= com, b /= com;
		}
		if(rec.find({sig, a, b}) == rec.end() && rec.find({-sig, b, a}) == rec.end())
			rec[{sig, a, b}].first++;
		else if(rec.find({sig, a, b}) != rec.end()) rec[{sig, a, b}].first++;
		else rec[{-sig, b, a}].second++; 
	}
	long long res = 1;
	for(auto &i : rec){
		long long fir = modpow(2, i.second.first) - 1;
		long long sec = modpow(2, i.second.second) - 1;
		res *= ((fir + sec) % mod + 1) % mod;
	}
	cout << ((res - 1) % mod + mod) % mod << "\n";
	return 0;
}