Problem p02679 (C++) — buggy submission, verdict: Runtime Error

#pragma region Macros
#pragma GCC optimize("O3")

#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define rep2(i, a, b) for (ll i = a; i <= b; ++i)
#define rep(i, n) for (ll i = 0; i < n; ++i)
#define rep3(i, a, b) for (ll i = a; i >= b; --i)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pb push_back
#define eb emplace_back
#define vi vector<int>
#define vec vector<int>
#define vll vector<ll>
#define vpi vector<pii>
#define vpll vector<pll>
#define overload2(_1, _2, name, ...) name
#define vv(a, b) vector<vector<int>>(a, vector<int>(b))
#define vv2(a, b, c) vector<vector<int>>(a, vector<int>(b, c))
#define vvl(a, b) vector<vector<ll>>(a, vector<ll>(b))
#define vvl2(a, b, c) vector<vector<ll>>(a, vector<ll>(b, c))
#define vvv(a, b, c) vector<vv(b, c)>(a)
#define vvv2(a, b, c, d) vector<vv(b, c, d)>(a)
#define vvvl(a, b, c) vector<vvl(b, c)>(a)
#define vvvl2(a, b, c, d) vector<vvl(b, c, d)>(a)
#define fi first
#define se second
#define all(c) begin(c), end(c)
#define ios ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define lb(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define ub(c, x) distance((c).begin(), upper_bound(all(c), (x)))
using namespace std;
template <class T> using pq = priority_queue<T>;
template <class T> using pqg = priority_queue<T, vector<T>, greater<T>>;
#define INT(...)                                                               \\
  int __VA_ARGS__;                                                             \\
  IN(__VA_ARGS__)
#define LL(...)                                                                \\
  ll __VA_ARGS__;                                                              \\
  IN(__VA_ARGS__)
#define ULL(...)                                                               \\
  ull __VA_ARGS__;                                                             \\
  IN(__VA_ARGS__)
#define STR(...)                                                               \\
  string __VA_ARGS__;                                                          \\
  IN(__VA_ARGS__)
#define CHR(...)                                                               \\
  char __VA_ARGS__;                                                            \\
  IN(__VA_ARGS__)
#define DBL(...)                                                               \\
  double __VA_ARGS__;                                                          \\
  IN(__VA_ARGS__)
#define LD(...)                                                                \\
  ld __VA_ARGS__;                                                              \\
  IN(__VA_ARGS__)
#define VEC(type, name, size)                                                  \\
  vector<type> name(size);                                                     \\
  IN(name)
#define VV(type, name, h, w)                                                   \\
  vector<vector<type>> name(h, vector<type>(w));                               \\
  IN(name)
int scan() { return getchar(); }
void scan(int &a) { cin >> a; }
void scan(long long &a) { cin >> a; }
void scan(char &a) { cin >> a; }
void scan(double &a) { cin >> a; }
void scan(long double &a) { cin >> a; }
void scan(char a[]) { scanf("%s", a); }
void scan(string &a) { cin >> a; }
template <class T> void scan(vector<T> &);
template <class T, size_t size> void scan(array<T, size> &);
template <class T, class L> void scan(pair<T, L> &);
template <class T, size_t size> void scan(T (&)[size]);
template <class T> void scan(vector<T> &a) {
  for (auto &i : a)
    scan(i);
}
template <class T> void scan(deque<T> &a) {
  for (auto &i : a)
    scan(i);
}
template <class T, size_t size> void scan(array<T, size> &a) {
  for (auto &i : a)
    scan(i);
}
template <class T, class L> void scan(pair<T, L> &p) {
  scan(p.first);
  scan(p.second);
}
template <class T, size_t size> void scan(T (&a)[size]) {
  for (auto &i : a)
    scan(i);
}
template <class T> void scan(T &a) { cin >> a; }
void IN() {}
template <class Head, class... Tail> void IN(Head &head, Tail &...tail) {
  scan(head);
  IN(tail...);
}
string stin() {
  string s;
  cin >> s;
  return s;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
vi iota(int n) {
  vi a(n);
  iota(all(a), 0);
  return a;
}
template <class T> void UNIQUE(vector<T> &x) {
  sort(all(x));
  x.erase(unique(all(x)), x.end());
}
int in() {
  int x;
  cin >> x;
  return x;
}
ll lin() {
  unsigned long long x;
  cin >> x;
  return x;
}
void print() { putchar(' '); }
void print(bool a) { cout << a; }
void print(int a) { cout << a; }
void print(long long a) { cout << a; }
void print(char a) { cout << a; }
void print(string &a) { cout << a; }
void print(double a) { cout << a; }
template <class T> void print(const vector<T> &);
template <class T, size_t size> void print(const array<T, size> &);
template <class T, class L> void print(const pair<T, L> &p);
template <class T, size_t size> void print(const T (&)[size]);
template <class T> void print(const vector<T> &a) {
  if (a.empty())
    return;
  print(a[0]);
  for (auto i = a.begin(); ++i != a.end();) {
    cout << " ";
    print(*i);
  }
  cout << endl;
}
template <class T> void print(const deque<T> &a) {
  if (a.empty())
    return;
  print(a[0]);
  for (auto i = a.begin(); ++i != a.end();) {
    cout << " ";
    print(*i);
  }
}
template <class T, size_t size> void print(const array<T, size> &a) {
  print(a[0]);
  for (auto i = a.begin(); ++i != a.end();) {
    cout << " ";
    print(*i);
  }
}
template <class T, class L> void print(const pair<T, L> &p) {
  cout << '(';
  print(p.first);
  cout << ",";
  print(p.second);
  cout << ')';
}
template <class T, size_t size> void print(const T (&a)[size]) {
  print(a[0]);
  for (auto i = a; ++i != end(a);) {
    cout << " ";
    print(*i);
  }
}
template <class T> void print(const T &a) { cout << a; }
int out() {
  putchar('\\n');
  return 0;
}
template <class T> int out(const T &t) {
  print(t);
  putchar('\\n');
  return 0;
}
template <class Head, class... Tail>
int out(const Head &head, const Tail &...tail) {
  print(head);
  putchar(' ');
  out(tail...);
  return 0;
}
ll gcd(ll a, ll b) {
  while (b) {
    ll c = b;
    b = a % b;
    a = c;
  }
  return a;
}
ll lcm(ll a, ll b) {
  if (!a || !b)
    return 0;
  return a * b / gcd(a, b);
}
vector<pll> factor(ll x) {
  vector<pll> ans;
  for (ll i = 2; i * i <= x; i++)
    if (x % i == 0) {
      ans.push_back({i, 1});
      while ((x /= i) % i == 0)
        ans.back().second++;
    }
  if (x != 1)
    ans.push_back({x, 1});
  return ans;
}
vector<int> divisor(int x) {
  vector<int> ans;
  for (int i = 1; i * i <= x; i++)
    if (x % i == 0) {
      ans.pb(i);
      if (i * i != x)
        ans.pb(x / i);
    }
  return ans;
}
int popcount(ll x) { return __builtin_popcountll(x); }
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int rnd(int n) { return uniform_int_distribution<int>(0, n)(rng); }
#define endl '\\n'

#ifdef _LOCAL
#undef endl
#define debug(x)                                                               \\
  cout << #x << ": ";                                                          \\
  print(x);                                                                    \\
  cout << endl;
void err() {}
template <class T> void err(const T &t) {
  print(t);
  cout << " ";
}
template <class Head, class... Tail>
void err(const Head &head, const Tail &...tail) {
  print(head);
  putchar(' ');
  out(tail...);
}
#else
#define debug(x)
template <class... T> void err(const T &...) {}
#endif
#pragma endregion

template <typename Monoid> struct SegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;

  int sz;
  vector<Monoid> seg;

  const F f;
  const Monoid M1;

  SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {
    sz = 1;
    while (sz < n)
      sz <<= 1;
    seg.assign(2 * sz, M1);
  }

  void set(int k, const Monoid &x) { seg[k + sz] = x; }

  void build() {
    for (int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  void update(int k, const Monoid &x) {
    k += sz;
    seg[k] += x;
    while (k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  Monoid query(int a, int b) {
    Monoid L = M1, R = M1;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1)
        L = f(L, seg[a++]);
      if (b & 1)
        R = f(seg[--b], R);
    }
    return f(L, R);
  }

  Monoid operator[](const int &k) const { return seg[k + sz]; }

  template <typename C>
  int find_subtree(int a, const C &check, Monoid &M, bool type) {
    while (a < sz) {
      Monoid nxt = type ? f(seg[2 * a + type], M) : f(M, seg[2 * a + type]);
      if (check(nxt))
        a = 2 * a + type;
      else
        M = nxt, a = 2 * a + 1 - type;
    }
    return a - sz;
  }

  template <typename C> int find_first(int a, const C &check) {
    Monoid L = M1;
    if (a <= 0) {
      if (check(f(L, seg[1])))
        return find_subtree(1, check, L, false);
      return -1;
    }
    int b = sz;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1) {
        Monoid nxt = f(L, seg[a]);
        if (check(nxt))
          return find_subtree(a, check, L, false);
        L = nxt;
        ++a;
      }
    }
    return -1;
  }

  template <typename C> int find_last(int b, const C &check) {
    Monoid R = M1;
    if (b >= sz) {
      if (check(f(seg[1], R)))
        return find_subtree(1, check, R, true);
      return -1;
    }
    int a = sz;
    for (b += sz; a < b; a >>= 1, b >>= 1) {
      if (b & 1) {
        Monoid nxt = f(seg[--b], R);
        if (check(nxt))
          return find_subtree(b, check, R, true);
        R = nxt;
      }
    }
    return -1;
  }
  void print(int n) {
    for (int i = 0; i < n; i++) {
      cerr << seg[i + sz] << " ";
    }
    cerr << endl;
  }
};
const ll MOD = 1e9 + 7;
const int N = 1100000;

template <ll Modulus> class modint {
  using u64 = ll;

public:
  u64 a;

  constexpr modint(const u64 x = 0) noexcept
      : a(((x % Modulus) + Modulus) % Modulus) {}
  constexpr u64 &value() noexcept { return a; }
  constexpr const u64 &value() const noexcept { return a; }
  constexpr modint operator+(const modint rhs) const noexcept {
    return modint(*this) += rhs;
  }
  constexpr modint operator-(const modint rhs) const noexcept {
    return modint(*this) -= rhs;
  }
  constexpr modint operator*(const modint rhs) const noexcept {
    return modint(*this) *= rhs;
  }
  constexpr modint operator/(const modint rhs) const noexcept {
    return modint(*this) /= rhs;
  }
  constexpr modint &operator+=(const modint rhs) noexcept {
    a += rhs.a;
    if (a >= Modulus) {
      a -= Modulus;
    }
    return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
    if (a < rhs.a) {
      a += Modulus;
    }
    a -= rhs.a;
    return *this;
  }
  constexpr modint &operator*=(const modint rhs) noexcept {
    a = a * rhs.a % Modulus;
    return *this;
  }
  constexpr modint &operator/=(modint rhs) noexcept {
    u64 exp = Modulus - 2;
    while (exp) {
      if (exp % 2) {
        *this *= rhs;
      }
      rhs *= rhs;
      exp /= 2;
    }
    return *this;
  }
};

#define mint modint<MOD>
mint inv[N], comb[N], prd[N], invprd[N];
void calc_inv() {
  inv[1] = 1;
  rep2(i, 2, N - 1) { inv[i] = inv[MOD % i] * (-MOD / i); }
  return;
}
void calc_product() {
  prd[0] = prd[1] = 1;
  invprd[0] = invprd[1] = 1;
  rep2(i, 2, N - 1) {
    prd[i] = prd[i - 1] * i;
    invprd[i] = inv[i] * invprd[i - 1];
  }
  return;
}
mint cmb(int a, int b) {
  if (a < b)
    return 0;
  if (a < 0 || b < 0)
    return 0;
  return {prd[a] * invprd[b] * invprd[a - b]};
}
mint modpow(mint x, ll n) {
  if (n == 0)
    return 1;
  mint res = modpow(x * x, n / 2);
  if (n & 1)
    res = res * x;
  return res;
}
void calc() {
  calc_inv();
  calc_product();
}
using vmint = vector<mint>;
ostream &operator<<(ostream &os, mint a) {
  os << a.a;
  return os;
}

signed main() {
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  cout << fixed << setprecision(15);
  int n = in();
  map<pll, int> mp;
  int dz = 0;
  rep(i, n) {
    ll a = lin(), b = lin();
    if (!a and !b) {
      dz++;
      continue;
    } else if (!a) {
      mp[{0, 1}]++;
      continue;
    } else if (!b) {
      mp[{-1, 0}]++;
      continue;
    }
    if (b < 0)
      a = -a, b = -b;
    ll g = gcd(abs(a), b);
    a /= g, b /= g;
    mp[{a, b}]++;
  }
  mint ans = 1;
  for (auto [a, b] : mp) {
    pll p;
    if (a.fi < 0)
      p = {a.se, -a.fi};
    else
      p = {-a.se, a.fi};
    if (a == p) {
      ans *= modpow(2, b);
    } else if (mp.count(p)) {
      if (a.fi < 0)
        continue;
      ans *= modpow(2, b) + modpow(2, mp[p]) - 1;
    } else {
      ans *= modpow(2, b);
    }
  }
  cout << (ans - 1 + dz) << endl;
}

Error: 0

Fixed submission:

#pragma region Macros
#pragma GCC optimize("O3")

#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define rep2(i, a, b) for (ll i = a; i <= b; ++i)
#define rep(i, n) for (ll i = 0; i < n; ++i)
#define rep3(i, a, b) for (ll i = a; i >= b; --i)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pb push_back
#define eb emplace_back
#define vi vector<int>
#define vec vector<int>
#define vll vector<ll>
#define vpi vector<pii>
#define vpll vector<pll>
#define overload2(_1, _2, name, ...) name
#define vv(a, b) vector<vector<int>>(a, vector<int>(b))
#define vv2(a, b, c) vector<vector<int>>(a, vector<int>(b, c))
#define vvl(a, b) vector<vector<ll>>(a, vector<ll>(b))
#define vvl2(a, b, c) vector<vector<ll>>(a, vector<ll>(b, c))
#define vvv(a, b, c) vector<vv(b, c)>(a)
#define vvv2(a, b, c, d) vector<vv(b, c, d)>(a)
#define vvvl(a, b, c) vector<vvl(b, c)>(a)
#define vvvl2(a, b, c, d) vector<vvl(b, c, d)>(a)
#define fi first
#define se second
#define all(c) begin(c), end(c)
#define ios ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define lb(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define ub(c, x) distance((c).begin(), upper_bound(all(c), (x)))
using namespace std;
template <class T> using pq = priority_queue<T>;
template <class T> using pqg = priority_queue<T, vector<T>, greater<T>>;
#define INT(...)                                                               \\
  int __VA_ARGS__;                                                             \\
  IN(__VA_ARGS__)
#define LL(...)                                                                \\
  ll __VA_ARGS__;                                                              \\
  IN(__VA_ARGS__)
#define ULL(...)                                                               \\
  ull __VA_ARGS__;                                                             \\
  IN(__VA_ARGS__)
#define STR(...)                                                               \\
  string __VA_ARGS__;                                                          \\
  IN(__VA_ARGS__)
#define CHR(...)                                                               \\
  char __VA_ARGS__;                                                            \\
  IN(__VA_ARGS__)
#define DBL(...)                                                               \\
  double __VA_ARGS__;                                                          \\
  IN(__VA_ARGS__)
#define LD(...)                                                                \\
  ld __VA_ARGS__;                                                              \\
  IN(__VA_ARGS__)
#define VEC(type, name, size)                                                  \\
  vector<type> name(size);                                                     \\
  IN(name)
#define VV(type, name, h, w)                                                   \\
  vector<vector<type>> name(h, vector<type>(w));                               \\
  IN(name)
int scan() { return getchar(); }
void scan(int &a) { cin >> a; }
void scan(long long &a) { cin >> a; }
void scan(char &a) { cin >> a; }
void scan(double &a) { cin >> a; }
void scan(long double &a) { cin >> a; }
void scan(char a[]) { scanf("%s", a); }
void scan(string &a) { cin >> a; }
template <class T> void scan(vector<T> &);
template <class T, size_t size> void scan(array<T, size> &);
template <class T, class L> void scan(pair<T, L> &);
template <class T, size_t size> void scan(T (&)[size]);
template <class T> void scan(vector<T> &a) {
  for (auto &i : a)
    scan(i);
}
template <class T> void scan(deque<T> &a) {
  for (auto &i : a)
    scan(i);
}
template <class T, size_t size> void scan(array<T, size> &a) {
  for (auto &i : a)
    scan(i);
}
template <class T, class L> void scan(pair<T, L> &p) {
  scan(p.first);
  scan(p.second);
}
template <class T, size_t size> void scan(T (&a)[size]) {
  for (auto &i : a)
    scan(i);
}
template <class T> void scan(T &a) { cin >> a; }
void IN() {}
template <class Head, class... Tail> void IN(Head &head, Tail &...tail) {
  scan(head);
  IN(tail...);
}
string stin() {
  string s;
  cin >> s;
  return s;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
vi iota(int n) {
  vi a(n);
  iota(all(a), 0);
  return a;
}
template <class T> void UNIQUE(vector<T> &x) {
  sort(all(x));
  x.erase(unique(all(x)), x.end());
}
int in() {
  int x;
  cin >> x;
  return x;
}
ll lin() {
  unsigned long long x;
  cin >> x;
  return x;
}
void print() { putchar(' '); }
void print(bool a) { cout << a; }
void print(int a) { cout << a; }
void print(long long a) { cout << a; }
void print(char a) { cout << a; }
void print(string &a) { cout << a; }
void print(double a) { cout << a; }
template <class T> void print(const vector<T> &);
template <class T, size_t size> void print(const array<T, size> &);
template <class T, class L> void print(const pair<T, L> &p);
template <class T, size_t size> void print(const T (&)[size]);
template <class T> void print(const vector<T> &a) {
  if (a.empty())
    return;
  print(a[0]);
  for (auto i = a.begin(); ++i != a.end();) {
    cout << " ";
    print(*i);
  }
  cout << endl;
}
template <class T> void print(const deque<T> &a) {
  if (a.empty())
    return;
  print(a[0]);
  for (auto i = a.begin(); ++i != a.end();) {
    cout << " ";
    print(*i);
  }
}
template <class T, size_t size> void print(const array<T, size> &a) {
  print(a[0]);
  for (auto i = a.begin(); ++i != a.end();) {
    cout << " ";
    print(*i);
  }
}
template <class T, class L> void print(const pair<T, L> &p) {
  cout << '(';
  print(p.first);
  cout << ",";
  print(p.second);
  cout << ')';
}
template <class T, size_t size> void print(const T (&a)[size]) {
  print(a[0]);
  for (auto i = a; ++i != end(a);) {
    cout << " ";
    print(*i);
  }
}
template <class T> void print(const T &a) { cout << a; }
int out() {
  putchar('\\n');
  return 0;
}
template <class T> int out(const T &t) {
  print(t);
  putchar('\\n');
  return 0;
}
template <class Head, class... Tail>
int out(const Head &head, const Tail &...tail) {
  print(head);
  putchar(' ');
  out(tail...);
  return 0;
}
ll gcd(ll a, ll b) {
  while (b) {
    ll c = b;
    b = a % b;
    a = c;
  }
  return a;
}
ll lcm(ll a, ll b) {
  if (!a || !b)
    return 0;
  return a * b / gcd(a, b);
}
vector<pll> factor(ll x) {
  vector<pll> ans;
  for (ll i = 2; i * i <= x; i++)
    if (x % i == 0) {
      ans.push_back({i, 1});
      while ((x /= i) % i == 0)
        ans.back().second++;
    }
  if (x != 1)
    ans.push_back({x, 1});
  return ans;
}
vector<int> divisor(int x) {
  vector<int> ans;
  for (int i = 1; i * i <= x; i++)
    if (x % i == 0) {
      ans.pb(i);
      if (i * i != x)
        ans.pb(x / i);
    }
  return ans;
}
int popcount(ll x) { return __builtin_popcountll(x); }
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int rnd(int n) { return uniform_int_distribution<int>(0, n)(rng); }
#define endl '\\n'

#ifdef _LOCAL
#undef endl
#define debug(x)                                                               \\
  cout << #x << ": ";                                                          \\
  print(x);                                                                    \\
  cout << endl;
void err() {}
template <class T> void err(const T &t) {
  print(t);
  cout << " ";
}
template <class Head, class... Tail>
void err(const Head &head, const Tail &...tail) {
  print(head);
  putchar(' ');
  out(tail...);
}
#else
#define debug(x)
template <class... T> void err(const T &...) {}
#endif
#pragma endregion

template <typename Monoid> struct SegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;

  int sz;
  vector<Monoid> seg;

  const F f;
  const Monoid M1;

  SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {
    sz = 1;
    while (sz < n)
      sz <<= 1;
    seg.assign(2 * sz, M1);
  }

  void set(int k, const Monoid &x) { seg[k + sz] = x; }

  void build() {
    for (int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  void update(int k, const Monoid &x) {
    k += sz;
    seg[k] += x;
    while (k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  Monoid query(int a, int b) {
    Monoid L = M1, R = M1;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1)
        L = f(L, seg[a++]);
      if (b & 1)
        R = f(seg[--b], R);
    }
    return f(L, R);
  }

  Monoid operator[](const int &k) const { return seg[k + sz]; }

  template <typename C>
  int find_subtree(int a, const C &check, Monoid &M, bool type) {
    while (a < sz) {
      Monoid nxt = type ? f(seg[2 * a + type], M) : f(M, seg[2 * a + type]);
      if (check(nxt))
        a = 2 * a + type;
      else
        M = nxt, a = 2 * a + 1 - type;
    }
    return a - sz;
  }

  template <typename C> int find_first(int a, const C &check) {
    Monoid L = M1;
    if (a <= 0) {
      if (check(f(L, seg[1])))
        return find_subtree(1, check, L, false);
      return -1;
    }
    int b = sz;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1) {
        Monoid nxt = f(L, seg[a]);
        if (check(nxt))
          return find_subtree(a, check, L, false);
        L = nxt;
        ++a;
      }
    }
    return -1;
  }

  template <typename C> int find_last(int b, const C &check) {
    Monoid R = M1;
    if (b >= sz) {
      if (check(f(seg[1], R)))
        return find_subtree(1, check, R, true);
      return -1;
    }
    int a = sz;
    for (b += sz; a < b; a >>= 1, b >>= 1) {
      if (b & 1) {
        Monoid nxt = f(seg[--b], R);
        if (check(nxt))
          return find_subtree(b, check, R, true);
        R = nxt;
      }
    }
    return -1;
  }
  void print(int n) {
    for (int i = 0; i < n; i++) {
      cerr << seg[i + sz] << " ";
    }
    cerr << endl;
  }
};
const ll MOD = 1e9 + 7;
const int N = 1100000;

template <ll Modulus> class modint {
  using u64 = ll;

public:
  u64 a;

  constexpr modint(const u64 x = 0) noexcept
      : a(((x % Modulus) + Modulus) % Modulus) {}
  constexpr u64 &value() noexcept { return a; }
  constexpr const u64 &value() const noexcept { return a; }
  constexpr modint operator+(const modint rhs) const noexcept {
    return modint(*this) += rhs;
  }
  constexpr modint operator-(const modint rhs) const noexcept {
    return modint(*this) -= rhs;
  }
  constexpr modint operator*(const modint rhs) const noexcept {
    return modint(*this) *= rhs;
  }
  constexpr modint operator/(const modint rhs) const noexcept {
    return modint(*this) /= rhs;
  }
  constexpr modint &operator+=(const modint rhs) noexcept {
    a += rhs.a;
    if (a >= Modulus) {
      a -= Modulus;
    }
    return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
    if (a < rhs.a) {
      a += Modulus;
    }
    a -= rhs.a;
    return *this;
  }
  constexpr modint &operator*=(const modint rhs) noexcept {
    a = a * rhs.a % Modulus;
    return *this;
  }
  constexpr modint &operator/=(modint rhs) noexcept {
    u64 exp = Modulus - 2;
    while (exp) {
      if (exp % 2) {
        *this *= rhs;
      }
      rhs *= rhs;
      exp /= 2;
    }
    return *this;
  }
};

#define mint modint<MOD>
mint inv[N], comb[N], prd[N], invprd[N];
void calc_inv() {
  inv[1] = 1;
  rep2(i, 2, N - 1) { inv[i] = inv[MOD % i] * (-MOD / i); }
  return;
}
void calc_product() {
  prd[0] = prd[1] = 1;
  invprd[0] = invprd[1] = 1;
  rep2(i, 2, N - 1) {
    prd[i] = prd[i - 1] * i;
    invprd[i] = inv[i] * invprd[i - 1];
  }
  return;
}
mint cmb(int a, int b) {
  if (a < b)
    return 0;
  if (a < 0 || b < 0)
    return 0;
  return {prd[a] * invprd[b] * invprd[a - b]};
}
mint modpow(mint x, ll n) {
  if (n == 0)
    return 1;
  mint res = modpow(x * x, n / 2);
  if (n & 1)
    res = res * x;
  return res;
}
void calc() {
  calc_inv();
  calc_product();
}
using vmint = vector<mint>;
ostream &operator<<(ostream &os, mint a) {
  os << a.a;
  return os;
}

signed main() {
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  cout << fixed << setprecision(15);
  int n = in();
  map<pll, int> mp;
  rep(i, n) {
    ll a = lin(), b = lin();
    if (b < 0)
      a = -a, b = -b;
    ll g = gcd(abs(a), b);
    a /= g, b /= g;
    mp[{a, b}]++;
  }
  mint ans = 1;
  for (auto [a, b] : mp) {
    pll p;
    if (a.fi < 0)
      p = {a.se, -a.fi};
    else
      p = {-a.se, a.fi};
    if (a == p) {
      ans *= modpow(2, b);
    } else if (mp.count(p)) {
      if (a.fi < 0)
        continue;
      ans *= modpow(2, b) + modpow(2, mp[p]) - 1;
    } else {
      ans *= modpow(2, b);
    }
  }
  cout << (ans - 1) << endl;
}