Language: C++

//#pragma GCC optimize ("Ofast")
//#pragma GCC optimize ("unroll-loops")
//#pragma GCC target("avx,avx2,fma")

#include <bits/stdc++.h>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//#include <ext/rope>
#define pb push_back
#define F first
#define S second
#define ins insert
#define mp make_pair
#define fo(i, n1, n, x) for(int i = n1; i <= n; i += x)
#define foo(i, n, n1, x) for(int i = n; i >= n1; i -= x)
#define bit __builtin_popcount
#define md (l + ((r - l) / 2))
#define all(x) x.begin(),x.end()
#define eb emplace_back
#define ub upper_bound
#define lb lower_bound
#define ios ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define file(s) if (fopen(s".in", "r")) freopen(s".in", "r", stdin), freopen(s".out", "w", stdout)

using namespace std;
//using namespace __gnu_pbds;
//using namespace __gnu_cxx;


using ll = long long;

#define int ll

using pii = pair<int,int>;
using pll = pair<ll,ll>;
using vi = vector<int>;



const int N = 3e5 + 11, mod = 1e9 + 7, mod2 = 998244353;
const int MAX = 1e5 + 11;
const int INF1 = 2e9 + 11;
const ll INF2 = 6e18 + 11;
const double INF3 = 1e8 + 11;
const int base = 500;
const int P = 31;
const int dx[] = {1, -1, 0, 0, 1, 1, -1, -1};
const int dy[] = {0, 0, 1, -1, 1, -1, 1, -1};
const double EPS = 1e-4;
const double PI = acos(-1.0);


//template<typename T> using ordered_set = tree <T, null_type, less <T>, rb_tree_tag, tree_order_statistics_node_update>;
template<typename T1, typename T2> inline void chmin(T1 &a, T2 b) { if (a > b) a = b; }
template<typename T1, typename T2> inline void chmax(T1 &a, T2 b) { if (a < b) a = b; }


mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int n, ans;
pii a[N];
int mult(int a, int b) {
  int res = a;
  res %= mod;
  res *= b;
  res %= mod;
  if (res < 0) res += mod;
  return res % mod;
}
int add(int a, int b) {
  a %= mod;
  a += b;
  a %= mod;
  if (a < 0) a += mod;
  return a;
}
int power(int a, int b) {
  int res = 1;
  while (b) {
    if (b & 1) {
      res *= a;
      res %= mod;
    }
    a *= a;
    a %= mod;
    b >>= 1;
  }
  return res;
}
int gcd(int a, int b) {
  if (!a) return b;
  return gcd(b % a, a);
}
map<pii, int> cnt1, cnt2;
map<pii, bool> us;
main() {
  file("threesum");
  ios;
  cin >> n;
  fo(i, 1, n, 1) cin >> a[i].F >> a[i].S;
  set<pii> st;
  int zero = 0;
  fo(i, 1, n, 1) {
    if ({a[i].F, a[i].S} == {0, 0}) {
      ++zero;
      continue;
    }
    int g = gcd(abs(a[i].F), abs(a[i].S));
    a[i].F /= g;
    a[i].S /= g;
    int rot = 0;
    while (!(a[i].F >= 0 and a[i].S >= 0)) {
      ++rot;
      pii b = {-a[i].S, a[i].F};
      a[i] = b;
    }
    if (st.find(a[i]) == st.end()) st.ins(a[i]), cnt1[a[i]] = cnt2[a[i]] = 0;
    if (rot % 2 == 0) ++cnt1[a[i]];
    else ++cnt2[a[i]];
  }
  ans = 1;
  for (auto it : st) {
    if (us[it]) continue;
    us[it] = 1;
    ans *= ((add(add(power(2, cnt1[it]), power(2, cnt2[it])), -1) + mod)) % mod;
    ans %= mod;
  }
  ans = add(ans, add(zero, -1));
  ans %= mod;
  cout << ans;
  return 0;
}
/**
i.F*j.F+i.S*j.S=0
i.F*j.F==-i.S*j.S
-i.F/i.S==j.S/j.F


ai*aj + bi*bj = 0

1*2==2*-1

1*2 +
x=k*b/g
y=-k*a/g;

aj*s == -bj*f

-aj/bj*s == f

-aj/bj == f/s
*/


Compiler output:
a.cc:96:1: warning: ISO C++ forbids declaration of 'main' with no type [-Wreturn-type]
   96 | main() {
      | ^~~~
a.cc: In function 'int main()':
a.cc:104:9: error: expected primary-expression before '{' token
  104 |     if ({a[i].F, a[i].S} == {0, 0}) {
      |         ^
a.cc:104:9: error: expected ')' before '{' token
  104 |     if ({a[i].F, a[i].S} == {0, 0}) {
      |        ~^
      |         )