#include <bits/stdc++.h>
using namespace std;

using fint64 = int_fast64_t;
template<fint64 MOD>
struct ModInt {
	fint64 x;
	ModInt():x(0){}
	ModInt(fint64 x):
		x(x>=0?x%MOD:(MOD-(-x)%MOD)%MOD)
		{}
	// 負号
	ModInt operator -() const{
		return ModInt(-x);
	}
	// 加算
	ModInt &operator +=(const ModInt &rhs){
		x+=rhs.x;
		if(x>=MOD) x-=MOD;
		return (*this);
	}
	ModInt operator +(const ModInt &rhs) const{
		return ModInt(*this)+=rhs;
	}
	// 減算
	ModInt &operator -=(const ModInt &rhs){
		x+=MOD-rhs.x;
		if(x>=MOD) x-=MOD;
		return (*this);
	}
	ModInt operator -(const ModInt &rhs) const{
		return ModInt(*this)-=rhs;
	}
	// 乗算
	ModInt &operator *=(const ModInt &rhs){
		x*=rhs.x;
		if(x>=MOD) x%=MOD;
		return (*this);
	}
	ModInt operator *(const ModInt &rhs) const{
		return ModInt(*this)*=rhs;
	}
	// 除算
	ModInt &operator /=(const ModInt &rhs){
		(*this)*=rhs.inverse();
		return (*this);
	}
	ModInt operator /(const ModInt &rhs) const{
		return ModInt(*this)/=rhs;
	}
	// 等号
	bool operator ==(const ModInt &rhs){
		return x==rhs.x;
	}
	bool operator !=(const ModInt &rhs){
		return x!=rhs.x;
	}
	// 累乗
	ModInt pow(fint64 n) const{
		fint64 tmp=x;
		fint64 ret=1;
		while(n>0){
			if(n&1) ret=ret*tmp%MOD;
			tmp=tmp*tmp%MOD;
			n>>=1ll;
		}
		return ModInt(ret);
	}
	// 逆元
	ModInt inverse() const{
		fint64 a=x,b=MOD,s=1,t=0;
		while(b>0){
			fint64 u=a/b;
			a-=u*b;
			s-=u*t;
			swap(a,b);
			swap(s,t);
		}
		return ModInt(s);
	}
	// 入出力
	friend istream &operator >>(istream &lhs,ModInt<MOD> &rhs){
		fint64 x; lhs>>x;
		rhs=ModInt<MOD>(x);
		return lhs;
	}
	friend ostream &operator <<(ostream &lhs,const ModInt<MOD> &rhs){
		return lhs<<rhs.x;
	}
};

constexpr int MOD = 1e9 + 7;
using mint = ModInt<MOD>;
map<pair<int64_t, int64_t>, int> mp;
int main() {
	int n; cin >> n;
	mint zero = 0;
	for(int i = 0; i < n; ++i) {
		int64_t a, b; cin >> a >> b;
		if(a == 0 and b == 0) {
			zero += 0;
			continue;
		}
		if(a == 0) {
			++mp[{0, 1}];
		} else if(b == 0) {
			++mp[{1, 0}];
		} else {
			int64_t g = gcd(a, b);
			if((a > 0 and b > 0) or (a < 0 and b < 0)) {
				a = abs(a);
				b = abs(b);
				++mp[{a / g, b / g}];
			} else {
				a = abs(a);
				b = abs(b);
				++mp[{a / g, -b / g}];
			}
		}
	}
	mint ans = 1;
	for(auto e : mp) {
		int64_t x, y;
		tie(x, y) = e.first;
		if(mp[{x, y}] == 0) continue;
		int64_t nx = -y, ny = x;
		mint po = 2;
		if(mp.count({nx, ny})) {
			ans *= (po.pow(mp[{x, y}]) + po.pow(mp[{nx, ny}]) - 1);
			mp[{nx, ny}] = 0;
		} else if (mp.count({-nx, -ny})) {
			ans *= (po.pow(mp[{x, y}]) + po.pow(mp[{-nx, -ny}]) - 1);
			mp[{-nx, -ny}] = 0;
		} else {
			ans *= po.pow(mp[{x, y}]);
		}
	}
	cout << ans + zero - 1 << '\n';
	return 0;
}