//  Copyright © 2020 Diego Garcia Rodriguez del Campo. All rights reserved.
#include<bits/stdc++.h>
#define MAX 200005
#define optimiza_io cin.tie(0); ios_base::sync_with_stdio(0);
#define what_is(x) cerr << #x << " is " << x << endl;
#define pii pair < ll , ll >
#define fi first
#define se second
using namespace std;
typedef long long ll;

const ll MOD = 1e9 + 7;
ll N;
pii a[MAX];
ll pw[MAX];
map < pii , bool > dead;
map < pii , ll > mp;

int main()
{
    optimiza_io
    cin >> N;
    pw[0] = 1;
    for( ll i = 1; i <= N; i ++ )
        pw[i] = ( pw[i - 1] * 2 ) % MOD;
    for( ll i = 1; i <= N; i ++ ) {
        cin >> a[i].fi >> a[i].se;
        ll g = __gcd( a[i].fi , a[i].se );
        a[i].fi /= g;
        a[i].se /= g;
        mp[a[i]]++;
    }
    sort( a + 1 , a + N + 1 );
    
    ll ans = 1;
    ll l = 1;
    while( l <= N ) {
        ll r = l;
        while( r + 1 <= N && a[l].fi == a[r + 1].fi && a[l].se == a[r + 1].se )
            r++;
        if( dead[a[l]] ) {
            l = r + 1;
            continue;
        }
        ll tam = r - l + 1;
        dead[a[l]] = 1;
        pii nxt = a[l];
        swap( nxt.fi , nxt.se );
        nxt.fi *= -1;
        ll g = __gcd( nxt.fi , nxt.se );
        nxt.fi /= g;
        nxt.se /= g;
        ll tam2 = mp[nxt];
        dead[nxt] = 1;
        ll man = ( ( tam + 1 ) * ( tam2 + 1 ) ) % MOD;
        if( tam2 )
            man = ( man - 1 + MOD ) % MOD;
        ans = ( ans * man ) % MOD;
        l = r + 1;
    }
    
    ans = ( ans - 1 + MOD ) % MOD;
    cout << ans << "\n";
    
    //for( ll i = 1; i <= N; i ++ )  
    //    cout << i << ": " << a[i].fi << " " << a[i].se << "\n";
    return 0;
}

// CHECAR LIMITES 