#include<iostream>
#include<queue>
#include<memory>
#include<map>
#include<set>
#include<unordered_map>
#include<array>
#include<vector>
#include<algorithm>
#include<list>
#include<limits>
#include<stdio.h>
#include<math.h>
#include<string>

using namespace std;
using ll = long long;
using vec = vector<ll>;
using mat = vector<vec>;
using lst = list<ll>;
using pr  = pair<ll, ll>;

const ll MOD = 1000000007;


ll gcd(ll a, ll b)
{
	if (a%b == 0)return b;
	else return gcd(b, a%b);
}


int main()
{
	int N;
	cin >> N;

	map<pr, int> cnt;

	ll ans = 1;

	vec Two(N, 1);
	for (int i = 1; i < N; ++i)
	{
		Two[i] = 2 * Two[i - 1] % MOD;
	}

	for (int i = 0; i < N; ++i)
	{
		ll A, B;
		cin >> A >> B;

		if (A == 0 && B == 0)
		{
			cnt[pr(0, 0)]++;
		}
		else if (A == 0)
		{
			cnt[pr(0, 1)]++;
		}
		else if (B == 0)
		{
			cnt[pr(1, 0)]++;
		}
		else
		{
			ll g = gcd(A, B);
			A /= g;
			B /= g;

			if (A < 0)
			{
				A *= -1;
				B *= -1;
			}

			ll Aj = -B, Bj = A;
			if (Aj < 0) { Aj *= -1; Bj *= -1; }

			cnt[pr(A, B)]++;
			cnt[pr(Aj, Bj)];
		}
	}

	ll ans0 = cnt[pr(0, 0)];
	cnt.erase(pr(0, 0));
	while (!cnt.empty())
	{
		ll A = (cnt.begin()->first.first);
		ll B = (cnt.begin()->first.second);

		ll Aj = -B;
		ll Bj = A;
		if (Aj < 0) { Aj *= -1; Bj *= -1; }

		ans = ((Two[cnt[pr(A, B)]] + Two[cnt[pr(Aj, Bj)]] - 1) % MOD)*ans%MOD;

		cnt.erase(pr(A, B));
		cnt.erase(pr(Aj, Bj));
	}
	cout << ans - 1 + ans0 << endl;

	return 0;
}