#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

#define ll long long
#define ull unsigned long long
#define db long double
#define pb push_back
#define ppb pop_back
#define F first
#define S second
#define mp make_pair
#define all(x) (x).begin(), (x).end()

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef vector <int> vi;
typedef vector <ll> vll;

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

const int N = 2e5 + 123, MOD = 1e9 + 7;
const pii mod = {1e9 + 7, 1e9 + 9};
int n;

int bp(int x, int y, int m) {
	int res = 1;
	while (y) {
		if (y & 1) {
			res = (ll)res * x % m;
		}
		x = (ll)x * x % m;
		y /= 2;
	}
	return res;
}

struct Num {
	int x = 0, y = 0;
	Num(ll a = 0) {
		if (a < 0) {
			x = (-((-a) % mod.F) + mod.F) % mod.F;
			y = (-((-a) % mod.S) + mod.S) % mod.S;
		}	else {
			x = a % mod.F;
			y = a % mod.S;
		}
	}
	Num operator + (Num const & a) const {
		Num res;
		res.x = x + a.x;
		if (res.x >= mod.F) {
			res.x -= mod.F;
		}
		res.y = y + a.y;
		if (res.y >= mod.S) {
			res.y -= mod.S;
		}
		return res;
	}
	Num neg() const {
		Num res;
		res.x = -x + mod.F;
		if (res.x >= mod.F) {
			res.x -= mod.F;
		}
		res.y = -y + mod.S;
		if (res.y >= mod.S) {
			res.y -= mod.S;
		}
		return res;
	}
	Num operator - (Num const & a) const {
		return (* this) + a.neg();
	}
	Num inv() const {
		Num res;
		res.x = bp(x, mod.F - 2, mod.F);
		res.y = bp(y, mod.S - 2, mod.S);
		return res;
	}
	Num operator * (Num const & a) const {
		Num res;
		res.x = (ll)x * a.x % mod.F;
		res.y = (ll)y * a.y % mod.S;
		return res;
	}
	pii get() const {
		return {x, y};
	}
};

Num s[N], a[N], r[N];

int cnt, w[N];
map <pii, bool> used;
map <pii, int> ind;

int main() {
	ios_base::sync_with_stdio(false), cin.tie(NULL);
	#ifdef LOCAL
		freopen("input.txt", "r", stdin);
	#endif
	
	cin >> n;
	Num X, Y;
	for (int i = 1; i <= n; i++) {
		ll x, y;
		cin >> x >> y;
		X = Num(x).inv(), Y = Num(y);
		Y = Y * X;
		s[i] = Y;
	}
	for (int i = 1; i <= n; i++) {
		if (used.count(s[i].get())) {
			int pos = ind[s[i].get()];
			w[pos] = (ll)w[pos] * 2 % MOD;
			continue;
		}
		used[s[i].get()] = true;
		a[++cnt] = s[i];
		ind[s[i].get()] = cnt;
		w[cnt] = 2;
	}
	int ans = 1;
	for (int i = 1; i <= cnt; i++) {
		r[i] = (a[i].inv()).neg();
		if (ind.count(r[i].get())) {
			int j = ind[r[i].get()];
			if (i < j) {
				int W1 = w[i], W2 = w[j];
				int res = (ll)W1 * W2 % MOD;
				res -= (ll)(W1 - 1 + MOD) * (W2 - 1 + MOD) % MOD;
				if (res < 0) {
					res += MOD;
				}
				ans = (ll)ans * res % MOD;
			}
		}	else {
			ans = (ll)ans * w[i] % MOD;
		}
	}
	cout << (ans - 1 + MOD) % MOD;
}
