Language: C++

#include <bits/stdc++.h>
#define rep(i, n) for (int i=0; i<(n); ++i)
#define repr(i, a, b) for (int i=a; i<(b); ++i)
#define reprev(i, n) for (int i=n-1; i>=0; --i)
#define reprrev(i, a, b) for (int i=b-1; i>=(a); --i)
using namespace std;
using ll = long long;
using P = pair<int, int>;

const int mod = 1000000007;
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;
    }
};


int main() {
    cout << fixed << setprecision(10);
    
    int N; cin >> N;
    vector<ll> A(N), B(N);
    rep(i, N){
        cin >> A[i] >> B[i];
    }

    map<double, int> mp_a_div_b, mp_b_div_a;
    rep(i, N) {
        if (A[i] == 0 || B[i] == 0) continue;
        mp_a_div_b[double(A[i])/B[i]] += 1;
        // mp[double(A[i])/B[i]].second.emplace_back(i);
        mp_b_div_a[double(B[i])/A[i]] += 1;
        // mp[double(B[i])/A[i]].second.emplace_back(i);
    }
    int a0 = 0, b0 = 0, ab00 = 0;
    rep(i, N) {
        if (A[i] == 0 && B[i] == 0) ab00 += 1;
        else if (A[i] == 0) a0 += 1;
        else if (B[i] == 0) b0 += 1;
    }

    mint ans;

    mint two = 2;
    mint p = 1;
    p += two.pow(a0) - 1;
    two = 2;
    p += two.pow(b0) - 1;
    // これは最後
    // p += ab00;
    ans = p;

    // mint ans;

    int no_pair = 0;
    vector<pair<int, int>> pairs;
    rep(i, N) {
        if (A[i] == 0 || B[i] == 0) continue;
        if (!mp_b_div_a.count(-double(A[i]) / B[i]) && !mp_a_div_b(-double(B[i])/A[i])) {
            no_pair += 1;
        }
    }
    // cout << "no pair " << no_pair << endl;

    for (auto kv: mp_a_div_b) {
        // cout << "mp " << kv.first << " " << kv.second << endl;
        double a_div_b = kv.first;
        int ab_nb = kv.second;
        // vector<int> which_i = kv.second.second;

        if (a_div_b <= 0) continue;
        if (mp_b_div_a.count(-a_div_b)) {
            // cout << " ther is pair" << endl;
            pairs.emplace_back(ab_nb, mp_b_div_a[-a_div_b]);
        }
    }

    // no_pairを選ぶかどうか
    two = 2;
    ans *= two.pow(no_pair) ;

    rep(i, int(pairs.size())) {
        auto pa = pairs[i];
        // cout << "pair " << i << " : " << pa.first << " " << pa.second << endl;
        // 選ばない通り
        mint pl = 1;

        // two = 2;
        // 片方を選ぶとき
        two = 2;
        pl += two.pow(pa.first) - 1;
        // もう片方を選ぶ通り
        two = 2;
        pl += two.pow(pa.second) - 1;
        ans *= pl;
    }

    // AB両方が0のとき
    ans += ab00;

    // 全く選ばない通りを引く
    ans -= 1;
    cout << ans.x << endl;
    return 0;
}

/*
12
3 0 
2 0
1 0
4 0
0 0 
0 0
0 5
0 6
2 3
3 2
4 4
5 5
*/

Compiler output:
a.cc: In function 'int main()':
a.cc:102:67: error: no match for call to '(std::map<double, int>) (double)'
  102 |         if (!mp_b_div_a.count(-double(A[i]) / B[i]) && !mp_a_div_b(-double(B[i])/A[i])) {
      |                                                         ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~