#include <bits/stdc++.h>
#define _USE_MATH_DEFINES
using namespace std;
// 型シノニム
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> P;
// 定数
constexpr ll INF   = 1e16;
constexpr ll INM   = 114514;
constexpr ll MOD   = 1e9 + 7;
constexpr ld EPS   = 1e-12;
constexpr ll dx[4] = {1, 0, -1, 0};
constexpr ll dy[4] = {0, 1, 0, -1};
// 便利関数
void IOS() { ios::sync_with_stdio(false), cin.tie(0); }
template <typename T>
void dump(T x) { cout << x << endl; }
void dumpf(ld x, ll t) { cout << setprecision(t) << fixed << x << endl; }
template <typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val) {
	fill((T *)array, (T *)(array + N), val);
}
vector<string> split(const string &s, char delim) {
	vector<string> elems;
	string item;
	for (char ch : s) {
		if (ch == delim) {
			if (!item.empty())
				elems.push_back(item);
			item.clear();
		} else {
			item += ch;
		}
	}
	if (!item.empty())
		elems.push_back(item);
	return elems;
}
ll powm(ll a, ll b, ll m) {
	if (b == 0) {
		return 1;
	} else if (b % 2 == 0) {
		ll d = powm(a, b / 2, m);
		return (d * d) % m;
	} else {
		return (powm(a, b - 1, m) * a) % m;
	}
}

// 本体

void updatemp(map<P, P> &mp, P key, bool is1) {
	if (mp.find(key) == mp.end()) {
		mp[key] = P(0, 0);
	}
	if (is1) {
		mp[key].first++;
	} else {
		mp[key].second++;
	}
}

int main() {
	IOS();
	ll n;
	cin >> n;
	map<P, P> mp;
	ll zero = 0;
	for (int i = 0; i < n; i++) {
		ll a, b;
		cin >> a >> b;
		if (a == 0 && b == 0) {
			zero++;
		} else if (a == 0) {
			updatemp(mp, P(1, 0), true);
		} else if (b == 0) {
			updatemp(mp, P(1, 0), false);
		} else {
			ll za = abs(a), zb = abs(b);
			ll na = za / gcd(za, zb), nb = zb / gcd(za, zb);
			if (a * b > 0) {
				updatemp(mp, P(na, nb), true);
			} else {
				updatemp(mp, P(nb, na), false);
			}
		}
	}
	ll ans = 1;
	for (const auto &[key, val] : mp) {
		ans *= powm(2, val.first, MOD) + powm(2, val.second, MOD) - 1;
		ans %= MOD;
	}
	dump(ans + zero - 1);
}