#include "bits/stdc++.h"
#define rep(i,n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<int, int>;

// auto mod int
// https://youtu.be/L8grWxBlIZ4?t=9858
// https://youtu.be/ERZuLAxZffQ?t=4807 : optimize
// https://youtu.be/8uowVvQ_-Mo?t=1329 : division
const int mod = 1000000007;
struct mint {
	ll x; // typedef long long ll;
	mint(ll x = 0) :x((x%mod + mod) % mod) {}
	mint operator-() const { return mint(-x); }
	mint& operator+=(const mint a) {
		if ((x += a.x) >= mod) x -= mod;
		return *this;
	}
	mint& operator-=(const mint a) {
		if ((x += mod - a.x) >= mod) x -= mod;
		return *this;
	}
	mint& operator*=(const mint a) { (x *= a.x) %= mod; return *this; }
	mint operator+(const mint a) const { return mint(*this) += a; }
	mint operator-(const mint a) const { return mint(*this) -= a; }
	mint operator*(const mint a) const { return mint(*this) *= a; }
	mint pow(ll t) const {
		if (!t) return 1;
		mint a = pow(t >> 1);
		a *= a;
		if (t & 1) a *= *this;
		return a;
	}

	// for prime mod
	mint inv() const { return pow(mod - 2); }
	mint& operator/=(const mint a) { return *this *= a.inv(); }
	mint operator/(const mint a) const { return mint(*this) /= a; }
}; 

int gcd(int a, int b) {
	if (b == 0) return a;
	else return gcd(b, a%b);
}
istream& operator>>(istream& is, const mint& a) { return is >> a.x; }
ostream& operator<<(ostream& os, const mint& a) { return os << a.x; }

int main() {
	int N;
	cin >> N;
	vector<long long>A(N), B(N);
	pair<long long, long long>pairAB;
	map<pair<long long, long long>, pair<long long, long long>>mappair;
	int nZero = 0;
	for (int n = 0; n < N; ++n) {
		cin >> A[n] >> B[n];
		if ((0 == A[n])&&(0==B[n])) {
			nZero++;
			continue;
		}
		long long a = 0;
		long long b = 0;
		if(0 == A[n]) {
			//{0,1}
			pair<long long, long long> p(1, 0);
			auto itr = mappair.find(p);
			if (itr != mappair.end()) {//あった
				itr->second.second++;
			}
			else {//なかった
				pair<long long, long long> q(0, 1);
				mappair[p] = q;
			}
		}
		else if(0 == B[n]) {
			//{1,0}
			pair<long long, long long> p(1, 0);
			auto itr = mappair.find(p);
			if (itr != mappair.end()) {//あった
				itr->second.first++;
			}
			else {//なかった
				pair<long long, long long> q(1, 0);
				mappair[p] = q;
			}
		}
		else {
			a = A[n]/ gcd(A[n], B[n]);
			b = B[n]/ gcd(A[n], B[n]);
			bool frag = true;
			if ((a > 0)&&( b > 0)) {
			}
			else if((a < 0) && (b < 0)){
				a = -a;
				b = -b;
			}
			else if((a > 0) && (b < 0)){
				frag = false;
				long long temp = a;
				a = -b;
				b = temp;
			}
			else {//(a < 0) && (b > 0))
				frag = false;
				long long temp = -a;
				a = b;
				b = temp;
			}
			//{a,b}	
			pair<long long, long long> p(a, b);
			auto itr = mappair.find(p);
			if (itr != mappair.end()) {//あった
				if (frag) {
					itr->second.first++;
				}
				else {
					itr->second.second++;
				}
			}
			else {//なかった
				if (frag) {
					pair<long long, long long> q(1, 0);
					mappair[p] = q;
				}
				else {
					pair<long long, long long> q(0, 1);
					mappair[p] = q;
				}
			}
		}
	}
	mint nAns = 1; 
	for (auto itr = mappair.begin(); itr != mappair.end(); ++itr) {
		nAns *= ((mint(2).pow(itr->second.first) - 1) + (mint(2).pow(itr->second.second) - 1) + 1); 
	}
	nAns += nZero;
	nAns = nAns-1;
	cout << nAns << endl;
	return 0;
}

Measured memory_bytes: 21928