#include <algorithm>
#include <cassert>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>

#include <limits.h>

using namespace std;

typedef long long ll;

template<class T>
inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return true;
    }
    return false;
}

template<class T>
inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return true;
    }
    return false;
}

const ll MOD = 1000000007;

// auto mod int
// ref. https://github.com/atcoder-live/library/blob/master/mint.cpp
// https://youtu.be/L8grWxBlIZ4?t=9858
// https://youtu.be/ERZuLAxZffQ?t=4807 : optimize
// https://youtu.be/8uowVvQ_-Mo?t=1329 : division
struct mint {
  ll x; // typedef long long ll;
  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
  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;
  }
};

ll calc_gcd(const ll sx, const ll sy) {
    ll x = min(sx, sy);
    ll y = max(sx, sy);
    ll tmp;
    while (x > 0) {
        tmp = y;
        y = x;
        x = tmp % x;
    }
    return y;
}

vector<pair<ll, ll>> iwashis;

// mapping from {A, B} to iwashi's indeices
map<pair<ll, ll>, vector<int>> v_to_idx;

mint solve(const int N) {
    mint ans = 1;

    map<pair<ll, ll>, bool> used;

    for (int i = 0; i < N; i++) {
        // calc patterns including iwashis[i]
        ll my_a = iwashis[i].first;
        ll my_b = iwashis[i].second;

        if (my_a == 0 && my_b == 0) {
            continue;
        }

        if (used[make_pair(my_a, my_b)]) {
            continue;
        }

        const int num_of_my = (int) v_to_idx[make_pair(my_a, my_b)].size();

        set<pair<ll, ll>> dislike_cands;
        if (my_a > 0) {
            dislike_cands.insert(make_pair(-1 * my_b, my_a));
        } else {
            dislike_cands.insert(make_pair(my_b, -1 * my_a));
        }
        // dislike_cands.insert(make_pair(-1 * my_b, my_a));
        // dislike_cands.insert(make_pair(my_b, -1 * my_a));

        int num_of_dl = 0;
        for (auto dislike : dislike_cands) {
            // printf("i: %d, dislike: {%lld, %lld}\n", i, dislike.first, dislike.second);
            vector<int> dl_idx = v_to_idx[dislike];
            num_of_dl += (int) dl_idx.size();
            used[dislike] = true;
        }
        // printf("i: %d, num_of_my: %d, num_of_dl: %d\n", i, num_of_my, num_of_dl);
        ans *= (mint(2).pow(num_of_my) - 1) + (mint(2).pow(num_of_dl) - 1) + 1;
        // printf("i: %d, ans: %lld\n", i, ans.x);
        used[make_pair(my_a, my_b)] = true;
    }
    ans -= 1;

    ans += (int) v_to_idx[make_pair(0LL, 0LL)].size();

    return ans;
}

int main(void) {
    int N;
    cin >> N;

    iwashis.resize(N);
    for (int i = 0; i < N; i++) {
        ll A, B;
        cin >> A >> B;
        if (A == 0 && B == 0) {
            // do nothing
        } else if (A == 0) {
            B = 1;
        } else if (B == 0) {
            A = 1;
        } else {
            ll gcd = calc_gcd(abs(A), abs(B));
            A /= gcd;
            B /= gcd;
        }
        if (B < 0) {
            A *= -1;
            B = abs(B);
        }
        // printf("A: %lld, B: %lld\n", A, B);
        iwashis[i] = {A, B};
        v_to_idx[make_pair(A, B)].push_back(i);
    }

    // for (auto idxes : v_to_idx) {
    //     printf("(%lld, %lld): ", idxes.first.first, idxes.first.second);
    //     for (auto idx : idxes.second) {
    //         cout << idx << " ";
    //     }
    //     cout << endl;
    // }

    cout << solve(N).x << endl;

    return 0;
}


Measured memory_bytes: 68876