#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <array>
#include <tuple>
#include <string>
#include <algorithm>
#include <functional> // greater など
#include <cmath>      // abs など
#include <numeric>    // accumulate など
#include <stdexcept>
#include <cassert> // assert
using namespace std;

#include <boost/multiprecision/cpp_int.hpp>
using namespace boost::multiprecision;

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
// typedef long long ll;
typedef int128_t ll;

// #define NDEBUG 1
// debug用出力 https://trap.jp/post/998/
void debug_out() { cerr << endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T)
{
    cerr << H << " ";
    debug_out(T...);
}
#ifdef NDEBUG
#define debug(...)
#else
#define debug(...) debug_out(__VA_ARGS__)
#endif

//////////////// //////////////// //////////////// //////////////// ////////////////
//////////////// //////////////// //////////////// //////////////// ////////////////

typedef pair<ll, ll> coord;
constexpr inline ll MOD = 1000000007;

// constexpr int MAX_N = 200'000 + 9;
int n;
map<coord, int> dir;
ll ans = 1;

ll gcd(ll a, ll b)
{
    a = abs(a); b = abs(b);
    while (b > 0)
    {
        ll tmp = a;
        a = b;
        b = tmp % b;
    }
    return a;
}

ll pw(ll b, int a)
{
    ll res = 1;
    while (a > 0)
    {
        if (a & 1)
        {
            res = res * b % MOD;
            a--;
        }
        else
        {
            b = b * b % MOD;
            a /= 2;
        }
    }
    return res;
}

int main()
{
    // 入出力
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n;
    REP(i, n)
    {
        ll a,b;
        cin >> a >> b;
        ll g = gcd(a,b);
        a = (g == 0) ? 0 : (a / g);
        b = (g == 0) ? 0 : (b / g);
        if (! ((a >= 0 && b >= 0) || (a < 0 && b > 0)))
        {
            a = -a;
            b = -b;
        }
        dir[coord(a, b)]++;
    }

    for (auto tup : dir)
    {
        ll a = tup.first.first;
        ll b = tup.first.second;
        int cnt = tup.second;
        ll c = (a > 0) ? (-b) : b;
        ll d = abs(a);
        if ((a == 0 && b == 0) || (a <= 0 && (dir.count(coord(c, d)) > 0)))
        {
            continue;
        }
        auto it = dir.find(coord(c, d));
        int cnt2 = (it == dir.end()) ? 0 : it->second;
        ans = ans * (pw(2, cnt) + pw(2, cnt2) - 1) % MOD;
    }
    ans = (ans + dir[coord(0, 0)] - 1) % MOD;

    cout << ans << endl;

    return 0;
}

