#include<bits/stdc++.h>

using namespace std;
mt19937_64 rng(58);

typedef long long ll;
typedef pair<ll, ll> P;
#define X first
#define Y second

template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }

P normalize(P v) {
    if (v.X == 0 && v.Y == 0) {
        return {0, 0};
    } else if (v.X == 0) {
        return {0, 1};
    } else if (v.Y == 0) {
        return {1, 0};
    } else {
        ll g = gcd(abs(v.X), abs(v.Y));
        if (v.X < 0) {
            v = { -v.X, -v.Y };
        }
        return { v.X / g, v.Y / g };
    }
}

template <typename T>
T inverse(T a, T m) {
  T u = 0, v = 1;
  while (a != 0) {
    T t = m / a;
    m -= t * a; swap(a, m);
    u -= t * v; swap(u, v);
  }
  assert(m == 1);
  return u;
}

template<long long mod = 1000000007>
struct modint{
	long long a;
	modint() : a(0){}
	modint(long long t) { a = t % mod; if(a < 0) a += mod; }
	operator long long() const{ return a; }
	bool operator==(const modint &x) const{ return a == x.a; }
	bool operator!=(const modint &x) const{ return a != x.a; }
	modint operator-() const{ return modint(a ? (mod - a) : 0); }
	modint operator~() const{ return inverse(a, mod); }

	modint operator+(const modint &x) const{ return modint(*this) += x; }
	modint operator-(const modint &x) const{ return modint(*this) -= x; }
	modint operator*(const modint &x) const{ return modint(*this) *= x; }
	modint operator/(const modint &x) const{ return modint(*this) /= x; }

	modint &operator+=(const modint &x){
		a += x.a;
		if(a >= mod) a -= mod;
		return *this;
	}
	modint &operator-=(const modint &x){
		a -= x.a;
		if(a < 0) a += mod;
		return *this;
	}
	modint &operator*=(const modint &x){
		a = a * x.a % mod;
		return *this;
	}
	modint &operator/=(const modint &x){
		a = a * (~x).a % mod;
		return *this;
	}

	friend ostream &operator<<(ostream &os,const modint &x){
		return os << x.a;
	}
	friend istream &operator>>(istream &is,modint &x){
		long long t;
		is >> t;
		x = modint(t);
		return is;
	}

	modint pow(long long x) const{
		modint ret = 1,tmp = a;
		for(;x;tmp *= tmp,x >>= 1){
			if(x & 1) ret *= tmp;
		}
		return ret;
	}
};

string to_string(string s) { return '"' + s + '"'; }
string to_string(const char* s) { return to_string((string) s); }
string to_string(bool b) { return (b ? "true" : "false"); }
template <typename A, typename B>
string to_string(pair<A, B> p) { return "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; }
template <typename A>
string to_string(A v) { bool first = true; string res = ""; for (const auto &x : v) { if (!first) res += ", "; first = false; res += to_string(x); } return "{" + res + "}"; }
void debug_out() { cerr << endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) { cerr << " " << to_string(H); debug_out(T...); }
#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
    int n;
    cin >> n;
    map<P, ll> count;
    ll zero = 0;
    for (int i = 0; i < n; i++) {
        ll a, b;
        cin >> a >> b;
        P nv = normalize({a, b});
        if (nv.X == 0 && nv.Y == 0) {
            zero++;
        } else {
            count[nv]+=1ll;
        }
    }
    modint<1000000007> two = 2;
    modint<1000000007> ans = 1;
    for (auto s : count) {
        P v = s.first;
        ll vc = s.second;
        P u = normalize({v.Y, -v.X});

        if (count.find(u) != count.end()) {
            if (u < v) {
                ll uc = count[u];
                ans *= (two.pow(vc) + two.pow(uc) - modint<1000000007>(1));
            }
        } else {
            ans *= two.pow(vc);
        }
    }
    ans -= modint<1000000007>(1);
    ans += zero;
    cout << ans << endl;
}

Measured memory_bytes: 16120