#include <iostream> // cin, cout, cerr
#include <algorithm> // minmax, sort, swap
#include <numeric> // iota
#include <cstdio> // printf, scanf
#include <string> // string, stoi, to_string
#include <vector> // vector
#include <queue> // queue, priority_queue
#include <deque> // deque
#include <map> // key-value pairs sorted by keys
#include <set> // set
#include <iomanip> // cout<<setprecision(n)
#include <functional> // function<void(int)>
#include <cmath>
#include <cassert>
#include <bitset>
#include <stack>

#ifdef DEBUG
#include "debug.hpp"
#else
#define debug(...)
#endif

#define int long long // at least int64 > 9*10^18
#define EL '\n'
#define rep(i,n) for(int i = 0; i < (n); i++)
#define print(i) std::cout << (i) << '\n'
#define all(v) (v).begin(), (v).end()
using Graph = std::vector<std::vector<int> >;
const int INF = 1e17;
/* libraries */

constexpr int MOD = 1e9+7;
struct mint
{
	int v;
	mint():v(0){}
	mint(int v):v((v+MOD)%MOD){}
	mint operator-()const{ return mint(0) - *this; }
	mint& operator+=(const mint& a){ if((v+=a.v)>=MOD) v-=MOD; return *this; }
	mint& operator-=(const mint& a){ if((v+=MOD-a.v)>=MOD) v-=MOD; return *this; }
	mint& operator*=(const mint& a){ (v*=a.v)%=MOD; return *this; }
	mint& operator/=(const mint& a){ (*this) *= a.inv(); return *this; }
	mint operator+(const mint& a)const{ return mint(*this) += a; }
	mint operator-(const mint& a)const{ return mint(*this) -= a; }
	mint operator*(const mint& a)const{ return mint(*this) *= a; }
	mint operator/(const mint& a)const{ return mint(*this) /= a; }
	bool operator<(const mint& a)const{ return v < a.v; }
	bool operator==(const mint& a)const{ return v == a.v; }
	mint pow(int k)const{ mint r(1),t(v); while(k){ if(k&1) r*=t; t*=t; k>>=1; } return r; }
	mint inv()const{ return pow(MOD-2); }
	static mint comb(int n, int k) {
		if(n-k<k) k=n-k;
		mint num(1), dom(1);
		for(int i=0;i<k;i++) { num*=n-i; dom*=i+1; }
		return num/dom;
	}
};
std::istream& operator>>(std::istream&i,mint&a){ int t; i>>t; a=mint(t); return i; }
std::ostream& operator<<(std::ostream&o,const mint&a){ o<<a.v; return o; }


struct P
{
	int a, b;
	P(int x, int y) {
		int g = std::gcd(x,y);
		if(g!=0) x/=g; y/=g;
		a=x;b=y;
		if(a<0) {
			a*=-1;b*=-1;
		}
	}
	bool operator<(const P rhs) const {
		if(a!=rhs.a) return a<rhs.a;
		return b<rhs.b;
	}
};

signed main() {
	int n;
	std::cin >> n;
	std::vector<std::pair<int,int> > a;
	std::map<P,int> map;
	rep(i,n) {
		int x,y;
		std::cin >> x >> y;
		a.emplace_back(x,y);
		map[P(x,y)]++;
	}


	for(auto x:map) {
		debug(x.first.a,x.first.b,x.second);
	}

	mint ans=1;
	mint ans2=0;
	if(map.count(P(0,0))) {
		ans2+=map[P(0,0)];
		map[P(0,0)]=0;
	}
	for(auto x:map) {
		if(x.second==0) continue;
		mint mul=mint(2).pow(x.second);
		P rev(-x.first.b,x.first.a);
		debug(map[rev]);
		mul+=mint(2).pow(map[rev]);
		mul-=1;
		map[rev]=0;
		ans*=mul;
	}
	debug(ans);
	print(ans+ans2-1);
	return 0;
}
