#pragma GCC optimize ("O3")
#pragma GCC target ("avx2")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)
#define rep1(i, n) for(int i = 1; i <= (n); i++)
#define co(x) cout << (x) << "\n"
#define cosp(x) cout << (x) << " "
#define ce(x) cerr << (x) << "\n"
#define cesp(x) cerr << (x) << " "
#define pb push_back
#define mp make_pair
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
#define Would
#define you
#define please

const int mod = 1e9 + 7;
constexpr ll modpow(ll A, ll B) {
	ll kotae = 1;
	while (B > 0) {
		if (B & 1) kotae = kotae * A % mod;
		A = A * A % mod;
		B >>= 1;
	}
	return kotae;
}

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);


	int N;
	cin >> N;
	map<pair<ll, ll>, int> MP;
	int a0 = 0, b0 = 0;

	rep(i, N) {
		ll a, b;
		cin >> a >> b;

		if (a == 0 && b == 0) continue;
		if (a == 0) {
			a0++;
			continue;
		}
		if (b == 0) {
			b0++;
			continue;
		}

		ll G = __gcd(a, b); cesp(G);
		a /= G;
		b /= G;
		if (a < 0) {
			a = -a;
			b = -b;
		}
		MP[mp(a, b)]++;
	}

	ll kotae = 1;

	map<pair<ll, ll>, int> MP2 = MP;

	for (auto p : MP) {
		int k1 = p.second;
		int k2;
		if (p.first.second > 0) {
			k2 = MP2[mp(p.first.second, -p.first.first)];
		}
		else {
			k2 = MP2[mp(-p.first.second, p.first.first)];
		}
		if (k2 == 0) {
			kotae = kotae * modpow(2, k1) % mod;
			continue;
		}
		if (p.first.second < 0) continue;
		ll tmp = (modpow(2, k1) + modpow(2, k2) - 1) % mod;
		kotae = kotae * tmp % mod;
	}

	if (a0 && b0) {
		ll tmp = (modpow(2, a0) + modpow(2, b0) - 1) % mod;
		kotae = kotae * tmp % mod;
	}
	else if (a0) {
		kotae = kotae * modpow(2, a0) % mod;
	}
	else if (b0) {
		kotae = kotae * modpow(2, b0) % mod;
	}

	co((kotae - 1 + 2 * mod) % mod);

	Would you please return 0;
}