#include "bits/stdc++.h"
#include <boost/range/irange.hpp>
using namespace std;
using boost::irange;

// 定義
typedef long long         ll;
typedef pair<ll, ll>      P;
#define ALL(x)            (x).begin(),(x).end()
#define REP(i, n)         for (ll i = 0 ; i < (ll)n ; ++i)
#define REPN(i, m, n)     for (ll i = m ; i < (ll)n ; ++i)
#define VL                vector<ll>
#define VLL               vector<vector<ll>>
#define VLLL              vector<vector<vector<ll>>>
#define INF               2e9
#define INF_LL            1LL<<60
#define MOD               1000000007

ll Ceil(ll val, ll div)   { return (val + div - 1) / div; }
ll CeilN(ll val, ll div)  { return Ceil(val, div) * div; }
ll FloorN(ll x, ll n)     { return (x - x % n); }
bool IsOdd(ll x)          { return ((x & 1) == 1); }
bool IsEven(ll x)         { return ((x & 1) == 0); }
template<class T> bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

/* 最大公約数 */
ll gcd(ll a, ll b)
{
	if (b == 0) return a;
	return gcd(b, a % b);
}

const int mod = 1000000007;
class mint {
public:
	long long x;
	mint(long long 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 {
		mint res(*this);
		return res += a;
	}
	mint operator-(const mint& a) const {
		mint res(*this);
		return res -= a;
	}
	mint operator*(const mint& a) const {
		mint res(*this);
		return res *= a;
	}
	mint pow(ll t) const {
		if (!t) return 1;
		mint a = pow(t >> 1);
		a *= a;
		if (t & 1) a *= *this;
		return a;
	}
	mint inv() const {
		return pow(mod - 2);
	}
	mint& operator/=(const mint& a) {
		return (*this) *= a.inv();
	}
	mint operator/(const mint& a) const {
		mint res(*this);
		return res /= a;
	}
};

// MODのべき乗
ll powMod(ll n, ll p)
{
	ll res = 1;
	while (p) {
		if (p & 1) (res *= n) %= MOD;
		(n *= n) %= MOD;
		p >>= 1;
	}
	return res;
}


// 処理
void Solve()
{
	int N;
	cin >> N;
	map<P, ll> mp;
	REP(i, N) {
		ll a, b;
		cin >> a >> b;
		ll yakusuu = gcd(abs(a), abs(b));
		a /= yakusuu;
		b /= yakusuu;
		mp[{a, b}]++;
	}

	ll ngAll = 0;
	vector<P> ng;
	for (const auto &one : mp) {
		P x = one.first;
		if (x.first != 0 || x.second != 0) {
			ll cnt = 0;
			P tmp1 = { x.second * -1, x.first };
			P tmp2 = { x.second, x.first * -1 };
			if (mp.count(tmp1) != 0) {
				cnt += mp[tmp1];
				mp.erase(tmp1);
			}
			if (mp.count(tmp2) != 0) {
				cnt += mp[tmp2];
				mp.erase(tmp2);
			}
			ng.emplace_back(one.second, cnt);
		}
	}

	mint ans = 1;
	for (const auto &one : ng) {
		ll ansOne;
		if (one.second == 0) {
			ansOne = powMod(2, one.first);
		} else {
			ansOne = ((powMod(2, one.first) - 1) + (powMod(2, one.second) - 1) + 1);
		}
		ansOne %= MOD;
		ans *= ansOne;
	}

	ans += mp[{0, 0}];
	cout << ans.x - 1 << endl;
}

// メイン
int main()
{
	cin.tie(nullptr);
	ios_base::sync_with_stdio(false);
	cout << fixed << setprecision(15);
	Solve();
	return 0;
}
