
// Problem : E - ∙ (Bullet)
// Contest : AtCoder - AtCoder Beginner Contest 168
// URL : https://atcoder.jp/contests/abc168/tasks/abc168_e
// Memory Limit : 1024 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update

using namespace std;
using namespace __gnu_pbds;

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>
ordered_set;	

#define FOR(i,a,b) for(int i = (a); i <= (b); ++i)
#define FORD(i,a,b) for(int i = (a); i >= (b); --i)
#define RI(i,n) FOR(i,1,(n))
#define REP(i,n) FOR(i,0,(n)-1)
#define mini(a,b) a=min(a,b)
#define maxi(a,b) a=max(a,b)
#define pb push_back
#define st first
#define nd second
#define sz(w) (int) w.size()
typedef vector<int> vi;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<pii, int> para;
const ll inf = 1e18 + 7;
const ll maxN = 1e6 + 5;
const ll MOD = 1e9 + 7;

ll a[maxN], b[maxN];
map<pii, int> frq;

pii neg(pii p) {
	if (p.st > 0 && p.nd > 0) return {-p.nd, p.st};
	return {p.nd, -p.st};
}

ll pow2(ll a, ll b) {
	if (b == 0) return 1;
	if (b == 1) return a;
	ll d = pow2(a, b / 2);
	d = d * d % MOD;
	if (b % 2) return d * a % MOD;
	return d;	
}

ll calc(ll f1, ll f2) {
	if (f2 == 0) return pow2(2, f1);
	if (f1 == 0) return pow2(2, f2);
	return (pow2(2, f1) + pow2(2, f2) - 1 + MOD) % MOD;
}

// sprawdz MODULO!
int main() {
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	int n;
	int zeros = 0, zeroA = 0, zeroB = 0;
	cin >> n;
	REP(i, n) {
		cin >> a[i] >> b[i];
		if (a[i] == 0 && b[i] == 0) {
			zeros++;
			continue;
		}
		if (a[i] == 0) {
			zeroA++;
			continue;
		}
		if (b[i] == 0) {
			zeroB++;
			continue;
		}
		ll g = gcd(a[i], b[i]);
		a[i] /= g;
		b[i] /= g;
		if (a[i] < 0 && b[i] < 0) {
			a[i] *= -1;
			b[i] *= -1;
		}
		if (b[i] < 0 && a[i] > 0) {
			a[i] *= -1;
			b[i] *= -1;
		}
		frq[{a[i], b[i]}]++;
	}
	ll ans = 0;
	ans = (ans + calc(zeroA, zeroB)) % MOD;
	for(auto p: frq) {
		pii c = neg(p.st);
		if (p.nd == 0) continue;
		ll tmp;
		if (frq.count(c)) {
			tmp = calc(p.nd, frq[c]);
			frq[c] = 0;
		} else {
			tmp = pow2(2, p.nd);
		}
		//cout << tmp << endl;
		ans = (ans * tmp) % MOD;
	}
	ans = (ans + zeros - 1 + MOD) % MOD;
	cout << ans;
	return 0;
}
 
