#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <list>
#include <ctime>
#include <sstream>
#include <queue>
#include <stack>
#include <random>
#include <bitset>
#include <numeric>
#include <cassert>
using namespace std;
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef long long ll;
#define rep(x, b, e) for(int x=(b); x<(e); ++x)
#define ford(x, b, e) for(int x=((int)(b))-1; x>=(e); --x)
#define all(c) c.begin(),c.end()
#define sz(x) ((int)((x).size()))
#define pb push_back
#define st first
#define nd second
#define mp(x,y) make_pair(x,y)
typedef short int sint;

#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it) {
	*this << ((it != d.b) ? ", " : "") << *it;
  }
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "

const int mod = 1e9+7;
const int nax = 2 * 1e5 + 5;
ll dwa[nax];
map<pair<ll, ll>, int> zlicz;

int main() {
	ios_base::sync_with_stdio(false);
	int n;
	scanf("%d", &n);
	dwa[0] = 1;
	rep(i,1, nax) {
		dwa[i] = (dwa[i - 1] * 2) % mod;
	}
	// int d1 = 0, d2 = 0;
	// vector<P> gora, dol;
	int zz = 0;
	int y0=0;
	int x0=0;
	rep(i,0,n) {
		int x, y;
		scanf("%d %d", &x, &y);
		if (y < 0) {
			x *= -1;
			y *= -1;
		}
		if (x == 0 && y == 0) {
			++zz;
		} else if(y == 0) {
			++y0;
		} else if (x ==0){
			++x0;
		} else {
			int nwd = gcd(abs(x), y);
			int nx = x / nwd, ny = y / nwd;
			++zlicz[mp(x / nwd, y / nwd)];
			if (nx < 0) {
				int opx = ny, opy = -nx;
				if (zlicz.find(mp(opx, opy)) == zlicz.end()) {
					zlicz[mp(opx, opy)] = 0;
				}
			}
		}
	}
	ll res = ((dwa[x0] + dwa[y0] - 1)) % mod;
	// printf("x0: %d, y0: %d, res: %lld\n", x0, y0, res);
	for (auto xx : zlicz) {
		if (xx.st.st < 0) {
			continue;
		}
		ll curr = xx.nd;
		ll drug = zlicz[mp(-xx.st.nd , xx.st.st)];
		ll mnoz = ((dwa[curr] + dwa[drug] -1)) % mod;
		// printf("dla: %lld/%lld - %lld x %lld, mnoz: %lld\n", xx.st.st, xx.st.nd, curr, drug, mnoz);
		res = (res * mnoz) % mod;
	}
	cout << res - 1 << endl;
}