#include <bits/stdc++.h>
using namespace std;
 
#define REP(i, s) for (int i = 0; i < s; ++i)
#define ALL(v) (v).begin(), (v).end()
#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl
#define EACH(i, s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)
#define DEBUG
#define int long long
#define INF 1e18
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
template<class T1, class T2> ostream& operator << (ostream &s, pair<T1,T2> P)
{ return s << '<' << P.first << ", " << P.second << '>'; }
template<class T> ostream& operator << (ostream &s, vector<T> P)
{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }
template<class T> ostream& operator << (ostream &s, vector<vector<T> > P)
{ for (int i = 0; i < P.size(); ++i) { s << endl << P[i]; } return s << endl; }
template<class T> ostream& operator << (ostream &s, set<T> P)
{ EACH(it, P) { s << "<" << *it << "> "; } return s << endl; }
template<class T1, class T2> ostream& operator << (ostream &s, map<T1,T2> P)
{ EACH(it, P) { s << "<" << it->first << "->" << it->second << "> "; } return s << endl; }
template<class T>void show(vector<T>v){for (int i = 0; i < v.size(); i++){cerr<<v[i]<<" ";}cerr<<"\n";}
typedef long long ll;

const int MAX = 510000;
const int MOD = 1000000007;

long long fac[MAX], finv[MAX], inv[MAX];

// テーブルを作る前処理
void COMinit()
{
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for (int i = 2; i < MAX; i++)
    {
        fac[i] = fac[i - 1] * i % MOD;
        inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
        finv[i] = finv[i - 1] * inv[i] % MOD;
    }
}

// 二項係数計算
long long COM(int n, int k)
{
    if (n < k)
        return 0;
    if (n < 0 || k < 0)
        return 0;
    return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}

ll add(ll x, ll y)
{
    x += y;
    if (x >= MOD)
        return x - MOD;
    return x;
}
ll sub(ll x, ll y)
{
    x -= y;
    if (x < 0)
        return x + MOD;
    return x;
}
ll mult(ll x, ll y)
{
    return (x * y) % MOD;
}
ll bin_pow(ll x, ll p)
{
    if (p == 0)
        return 1;
    if (p & 1)
        return mult(x, bin_pow(x, p - 1));
    return bin_pow(mult(x, x), p / 2);
}

//int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }

signed main()
{
    
    int n;
    cin >> n;
    vector<int> a(n), b(n);
    map<pair<int, int>, pair<int,int>> mp;
    int zero = 0;
    REP(i, n)
    {
        cin >> a[i] >> b[i];
        int x = gcd(a[i], b[i]);
        if(a[i]== 0 && b[i] == 0){
            zero++;
            continue;
        }
        a[i] /= x;
        b[i] /= x;
        if(a[i]==0){
            mp[{0, 1}].second++;
        }
        else if(b[i]==0){
            mp[{0, 1}].first++;
        }
        else{
            if(b[i]<0){

            a[i] = -a[i];
            b[i] = -b[i];
            }
        bool rot90 = (a[i] <= 0);
        if(rot90){
            int tmp = -a[i];
            a[i] = b[i];
            b[i] = tmp;
        }
        if (rot90){
            mp[{a[i], b[i]}].first++;
        }
        else{
            mp[{a[i], b[i]}].second++;
        }
            }
        
    }
    
    int ans = 1;
    map<pair<int, int>, bool> mp2;
    for (auto u : mp)
    {
        //cerr << mp.size();
        int s = u.second.first;
        int t = u.second.second;
        
        //cerr << u.first.first << " " << u.first.second << " " << s << " " << t << endl;
        ans *= (bin_pow(2, s) + bin_pow(2, t) +MOD - 1) % MOD;
        ans %= MOD;
    }
    cout << (ans - 1 +MOD + zero)%MOD << endl;

    return 0;
}

Measured memory_bytes: 21920