#include <iostream>
#include <vector>
#include <limits.h>
#include <algorithm>
#include <string>
#include <math.h>
#include <limits.h>
#include <queue>
#include <map>
#include <set>
#include <iomanip>
#include <bitset>
#include <cassert>
#include <random>
#include <functional>
#include <stack>
#include <iomanip>
#include <cassert>
#include <boost/multiprecision/cpp_int.hpp>
#include <complex>
#include <cstdio>
#include <list>
#include <bitset>

//< in.txt > out.txt
using namespace std;
//std::ios::sync_with_stdio(false);
//std::cin.tie(0);
const long long MOD = 1000000007;
const long long INF = 1e18;
typedef long long LL;
typedef long double LD;
typedef boost::multiprecision::cpp_int bigint;
typedef pair<LL,LL> PLL;
typedef pair<LD, LL> pdl;
typedef pair<LD, LD> pdd;
typedef vector<LL> VLL;
typedef vector<VLL> VVLL;
typedef unsigned long long ULL;
typedef pair<bigint, bigint> PBB;

LL N;
vector<PLL> fishs;
LL fish0 = 0;

bigint cross(PLL a, PLL b) {
	bigint ax = a.first, ay = a.second;
	bigint bx = b.first, by = b.second;
	return ax * by - ay * bx;
}

bigint dot(PLL a, PLL b) {
	bigint ax = a.first, ay = a.second;
	bigint bx = b.first, by = b.second;
	return ax * bx + ay * by;
}

//arg(a) < arg(b) -> true
bool argcomp(PLL a, PLL b) {
	bigint ax = a.first, ay = a.second;
	bigint bx = b.first, by = b.second;
	bigint cr = ax * by - ay * bx;
	return cr > 0;
}

LL modpow(LL base, LL p) {
	if (p == 0)return 1;
	if (p == 1)return base;
	LL ans = modpow(base, p >> 1);
	ans *= ans;
	ans %= MOD;
	if (p & 1) {
		ans *= base;
		ans %= MOD;
	}
	return ans;
}

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	cin >> N;
	for (LL n = 0; n < N; n++) {
		PLL a(0,0);
		cin >> a.first >> a.second;
		if (a.first == 0 && a.second == 0)fish0++;
		else {
			if (a.second < 0) {
				a.first *= -1;
				a.second *= -1;
			}
			else if (a.second == 0 && a.first < 0)a.first *= -1;
			fishs.push_back(a);
		}
	}
	N = fishs.size();
	LL ans = 0;
	if (N != 0) {
		ans = 1;
		sort(fishs.begin(), fishs.end(), [](PLL a, PLL b) {
			return argcomp(a, b);
		});
		typedef  pair<PLL, LL> P;
		vector<P> args;
		args.push_back(P(fishs[0], 1));
		for (LL n = 1; n < N; n++) {
			PLL cur = fishs[n];
			bigint cr = cross(args.back().first, cur);
			if (cr == 0)args.back().second++;
			else args.push_back(P(cur, 1));
		}
		vector<bool> checked(args.size(), false);
		for (LL n = 0; n < args.size(); n++) {
			if (checked[n])continue;
			LL temp = 0;
			PLL cur = args[n].first;
			LL num = args[n].second;
			if (args[n].first.first > 0) {
				//直角になるものを探す
				//arg(s) <= cur+pi/2 < arg(e)
				PLL cri(-cur.second, cur.first);
				LL s = n, e = args.size();
				while (e - s > 1) {
					LL m = (e + s) / 2;
					PLL top = args[m].first;
					if (argcomp(cri, top))e = m;
					else s = m;
				}
				PLL plls = args[s].first;
				if (dot(plls,cur) == 0) {
					temp = 1;
					temp += (modpow(2, num) - 1) + (modpow(2, args[s].second) - 1);
					checked[s] = true;
					checked[n] = true;
				}
				else {
					temp = modpow(2, num);
					checked[n] = true;
				}
			}
			else {
				temp = modpow(2, num);
				checked[n] = true;
			}
			temp %= MOD;
			ans = (ans * temp) % MOD;
		}
		ans--;
	}
	if (fish0 != 0) {
		ans += fish0;
	}
	ans %= MOD;
	if (ans < 0)ans += MOD;
	cout << ans << "\n";
	return 0;
}

Measured memory_bytes: 15068