#include <bits/stdc++.h>

using namespace std;
using ll = long long;
const ll MOD = 1e9 + 7;

struct pair_hash {
    template <class T1, class T2>
    std::size_t operator()(const std::pair<T1, T2> &pair) const {
        return std::hash<T1>()(pair.first) ^ std::hash<T2>()(pair.second);
    }
};

int main() {
    int N;
    cin >> N;
    unordered_map<pair<ll, ll>, ll, pair_hash> slopeCount;
    ll zeroCount = 0;
    for (int i = 0; i < N; ++i) {
        ll A, B;
        cin >> A >> B;
        if (A == 0 && B == 0) {
            ++zeroCount;
        } else {
            auto gcdAB = __gcd(A, B);
            if (B < 0)
                ++slopeCount[{-A / gcdAB, -B / gcdAB}];
            else
                ++slopeCount[{A / gcdAB, B / gcdAB}];
        }
    }
    unordered_set<pair<ll, ll>, pair_hash> seen;
    ll ans = 1;
    for (const auto &p : slopeCount) {
        const auto &slope = p.first;
        if (seen.find(slope) == seen.end()) {
            // cout << p.first.first << " " << p.first.second << " " << p.second
            //      << endl;
            pair<ll, ll> vertical;
            if (slope.first < 0) {
                vertical = {slope.second, -slope.first};
            } else {
                vertical = {-slope.second, slope.first};
            }
            auto it = slopeCount.find(vertical);
            if (it != slopeCount.end()) {
                ans *= (pow(2LL, it->second) + pow(2LL, p.second) - 1);
                ans %= MOD;
                seen.insert(vertical);
            } else {
                ans *= pow(2LL, p.second);
                ans %= MOD;
            }
        }
    }
    ans -= 1;
    ans += zeroCount;
    ans %= MOD;

    cout << ans << endl;
    return 0;
}