#include <iostream>
#include <iomanip>
#include <vector>
#include <set>
#include <string>
#include <queue>
#include <algorithm>
#include <map>
#include <cmath>
#include <numeric>
#include <list>
#include <stack>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <tuple>
#include <deque>

using namespace std;

/*
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
*/

typedef long long ll;
typedef vector<ll> vll;
typedef vector<vll> vvll;
typedef pair<long long, long long> pll;
typedef vector<pll> vpll;

typedef long double ld;
typedef vector<ld> vld;

typedef vector<bool> vb;

#define rep(i, n) for (ll i = 0; i < (n); i++)
#define reps(i, n) for (ll i = 1; i <= (n); i++)
#define rrep(i, n) for (ll i = (n) - 1; i >= 0; i--)
#define rreps(i, n) for (ll i = (n); i >= 1; i--)
#define all(v) (v).begin(), (v).end()

template <class T> void chmin(T& a, T b) { a = min(a, b);}
template <class T> void chmax(T& a, T b) { a = max(a, b);}

constexpr int INF = 1 << 30;
constexpr ll INFL = 1LL << 60;
constexpr ll MOD = 1000000007;
constexpr ld EPS = 1e-12;
constexpr ld PI = 3.14159265358979323846;

struct mint {
	ll x;
	mint(ll x=0):x((x%MOD+MOD)%MOD){}
	mint operator-() const { return mint(-x);}
	mint& operator+=(const mint a) {if ((x+=a.x)>=MOD) x-=MOD; return *this;}
	mint& operator-=(const mint a) {if ((x+=MOD-a.x)>=MOD) x-=MOD; return *this;}
	mint& operator*=(const mint a) {(x*=a.x)%=MOD; return *this;}
	mint operator+(const mint a) const {mint res(*this); return res+=a;}
	mint operator-(const mint a) const {mint res(*this); return res-=a;}
	mint operator*(const mint a) const {mint res(*this); return res*=a;}
	mint pow(ll t) const {
		if (!t) return 1;
		mint a = pow(t>>1);
		a *= a;
		if (t&1) a *= *this;
 		return a;
	}

	// For prime mod.
	// Do not use if MOD is not prime number !!
	mint inv() const { return pow(MOD-2);}
	mint& operator/=(const mint a) { return (*this) *= a.inv();}
	mint operator/(const mint a) const {mint res(*this); return res/=a;}
};

void solve() {
    ll n;
    cin >> n;
    vll va, vb;
    ll zero = 0;
    for(ll i = 0; i < n; i++) {
        ll a, b;
        cin >> a >> b;
        if(a == 0 && b == 0) {
            zero++;
            continue;
        }
        else if(a == 0) {
            va.push_back(0);
            vb.push_back(1);
        }
        else if(b == 0) {
            va.push_back(1);
            vb.push_back(0);
        }
        else {
            ll g = __gcd(a, b);
            a /= g;
            b /= g;
            if(a < 0) {
                a = -a;
                b = -b;
            }
            va.push_back(a);
            vb.push_back(b);
        }
    }
    map<pll, ll> m;
    for(auto i = 0; i < va.size(); i++) m[make_pair(va[i], vb[i])]++;

    pll z1 = make_pair(0, 1);
    pll z2 = make_pair(1, 0);
    mint ans = mint(2).pow(m[z1]) + mint(2).pow(m[z2]) - 1;
    m[z1] = 0;
    m[z2] = 0;
    for(auto i = 0; i < va.size(); i++) {
        pll p1 = make_pair(va[i], vb[i]);
        pll p2 = vb[i] > 0 ? make_pair(vb[i], -va[i]) : make_pair(-vb[i], va[i]);
        ans *= mint(2).pow(m[p1]) + mint(2).pow(m[p2]) - 1;
        m[p1] = 0;
        m[p2] = 0;
    }
    ans += zero - 1;
    cout << ans.x << endl;
    return;
}

int main() {
    std::cin.tie(nullptr);
    std::ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(15);
    solve();
}

Measured memory_bytes: 31192