#include <stdio.h>
#include <stdlib.h>

#include <iostream>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <stdint.h>
#include <string.h>

#define _USE_MATH_DEFINES
#include <math.h>

#include <vector>
#include <list>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <stack>
#include <deque>
#include <string>

#include <algorithm>
#include <functional>
#include <bitset>
#include <functional>
#include <chrono>
#include <random>

#define sqr(x) (x) * (x)

typedef unsigned int u32;
typedef int i32;
typedef unsigned long long int u64;
typedef long long int i64;
typedef uint16_t u16;
typedef int16_t i16;
typedef uint8_t u8;
typedef int8_t i8;

using namespace std;
using namespace std::chrono;

const i64 mod = 1'000'000'000ll + 7;
//const i64 smod = 998244353ll;
//const i64 inf = 1'000'000'000'000'000'000ll + 7;
//const i64 inf = 1'000'000'007;

const long double eps = 1e-8;

const i64 MAXN = 100'000 + 6;

inline i64 sign(i64 x) {
    if (x > 0) {
        return 1;
    }
    if (x < 0) {
        return -1;
    }
    return 0;
}

i64 gcd(i64 a, i64 b) {
    while (b) {
        a %= b;
        swap(a, b);
    }
    return a;
}

i64 op(pair<pair<i64, i64>, i64> c, map<pair<pair<i64, i64>, i64>, i64>& q) {
    pair<pair<i64, i64>, i64> p = { {c.first.second, c.first.first}, -c.second };
    auto it = q.find(p);
    if (it == q.end()) {
        return 0;
    }

    auto r = it->second;
    q.erase(it);
    return r;
}

int main(int argc, char* argv[]) {
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cout.precision(15); cout.setf(ios::fixed);

    i64 n;
    cin >> n;

    vector<i64> a(n);
    vector<i64> b(n);

    for (i64 i = 0; i < n; i++) {
        cin >> a[i] >> b[i];
    }

    map<pair<pair<i64, i64>, i64>, i64> q;
    for (i64 i = 0; i < n; i++) {
        if (!a[i] && !b[i]) {
            continue;
        }
        if (!a[i]) {
            q[{{0, 1}, sign(sign(a[i]) * sign(b[i]))}] += 1;
            continue;
        }
        if (!b[i]) {
            q[{{1, 0}, sign(sign(a[i]) * sign(b[i]))}] += 1;
            continue;
        }

        i64 g = gcd(abs(a[i]), abs(b[i]));
        q[{{abs(a[i]) / g, abs(b[i]) / g}, sign(sign(a[i]) * sign(b[i]))}] += 1;
    }

    vector<i64> p;
    p.push_back(1);
    for (i64 i = 1; i <= n; i++) {
        p.push_back((p.back() * 2) % mod);
    }

    i64 R = 1;
    while(!q.empty()) {
        auto it = q.begin();
        auto c = *it;
        q.erase(it);
        i64 r = p[c.second] + p[op(c.first, q)] - 1;
        r %= mod;
        R *= r;
        R %= mod;
    }

    R -= 1;
    R = (R + mod) % mod;

    cout << R << endl;


    return 0;
}