#include <bits/stdc++.h>
using lint = long long;
template <typename T>
void print_container(std::vector<T> vec) {
  for (auto iter = vec.begin(); iter != vec.end(); ++iter) {
    std::cout << *iter << " ";
  }
  std::cout << std::endl;
}
class Fraction {
 private:
  long long numer;
  long long denom;
  friend const bool operator==(const Fraction &a, const Fraction &b);
  friend const bool operator!=(const Fraction &a, const Fraction &b);
  friend const bool operator>=(const Fraction &a, const Fraction &b);
  friend const bool operator<=(const Fraction &a, const Fraction &b);
  friend const bool operator>(const Fraction &a, const Fraction &b);
  friend const bool operator<(const Fraction &a, const Fraction &b);
  friend const Fraction operator+(const Fraction &a, const Fraction &b);
  friend const Fraction operator-(const Fraction &a, const Fraction &b);
  friend const Fraction operator*(const Fraction &a, const Fraction &b);
  friend const Fraction operator/(const Fraction &a, const Fraction &b);

 public:
  Fraction();
  Fraction(long long);
  Fraction(long long, long long);
  Fraction(const Fraction &);
  void set(long long, long long);
  void set(const Fraction &);
  void setNumer(long long);
  void setDenom(long long);
  long long getNumer();
  long long getDenom();
  static long long gcd(long long, long long);
  static long long lcm(long long, long long);
  void normal();
  std::string toString();
  long double toLongDouble();
  bool equals(const Fraction &) const;
  long long compare(const Fraction &) const;
  Fraction &operator=(const Fraction &b);
  Fraction &operator+=(const Fraction &b);
  Fraction &operator-=(const Fraction &b);
  Fraction &operator*=(const Fraction &b);
  Fraction &operator/=(const Fraction &b);
  Fraction operator+();
  Fraction operator-();
  Fraction &operator++();
  Fraction operator++(int);
  Fraction &operator--();
  Fraction operator--(int);
};
long long Fraction::gcd(long long a, long long b) {
  a = abs(a);
  b = abs(b);
  if (a < b) std::swap(a, b);
  long long tmp;
  while (b != 0) {
    tmp = b;
    b = a % b;
    a = tmp;
  }
  return a;
}
long long Fraction::lcm(long long a, long long b) {
  a = abs(a);
  b = abs(b);
  if (a > b) std::swap(a, b);
  if (a == 1) return b;
  long long i = a;
  while (i % b != 0) {
    i += a;
  }
  return i;
}
Fraction::Fraction() { set(0, 1); }
Fraction::Fraction(long long n) { set(n, 1); }
Fraction::Fraction(long long numer, long long denom) { set(numer, denom); }
Fraction::Fraction(const Fraction &b) { set(b); }
void Fraction::set(long long numer, long long denom) {
  this->numer = numer;
  this->denom = denom;
  normal();
}
void Fraction::set(const Fraction &b) {
  this->numer = b.numer;
  this->denom = b.denom;
}
void Fraction::setNumer(long long numer) {
  this->numer = numer;
  normal();
}
void Fraction::setDenom(long long denom) {
  this->denom = denom;
  normal();
}
inline long long Fraction::getNumer() { return numer; }
inline long long Fraction::getDenom() { return denom; }
void Fraction::normal() {
  long long gcd = this->gcd(getNumer(), getDenom());
  if (gcd == 1) {
    if (denom < 0) {
      numer *= -1;
      denom *= -1;
    }
    return;
  }
  long long numer = getNumer() / gcd;
  long long denom = getDenom() / gcd;
  if (denom < 0) {
    numer *= -1;
    denom *= -1;
  }
  set(numer, denom);
}
std::string Fraction::toString() {
  std::string str = "";
  if (getDenom() == 1)
    str = std::to_string(getNumer());
  else
    str = std::to_string(getNumer()) + "/" + std::to_string(getDenom());
  return str;
}
long double Fraction::toLongDouble() {
  return (long double)getNumer() / getDenom();
}
bool Fraction::equals(const Fraction &b) const {
  return numer == b.numer && denom == b.denom;
}
long long Fraction::compare(const Fraction &b) const {
  long long lcm = this->lcm(denom, b.denom);
  return (lcm / denom) * numer - (lcm / b.denom) * b.numer;
}
const bool operator==(const Fraction &a, const Fraction &b) {
  return a.equals(b);
}
const bool operator!=(const Fraction &a, const Fraction &b) {
  return !a.equals(b);
}
const bool operator>=(const Fraction &a, const Fraction &b) {
  return a.compare(b) >= 0;
}
const bool operator<=(const Fraction &a, const Fraction &b) {
  return a.compare(b) <= 0;
}
const bool operator>(const Fraction &a, const Fraction &b) {
  return a.compare(b) > 0;
}
const bool operator<(const Fraction &a, const Fraction &b) {
  return a.compare(b) < 0;
}
Fraction &Fraction::operator=(const Fraction &b) {
  this->set(b);
  return *this;
}
const Fraction operator+(const Fraction &a, const Fraction &b) {
  long long lcm = Fraction::lcm(a.denom, b.denom);
  long long numer = a.numer * (lcm / a.denom) + b.numer * (lcm / b.denom);
  return Fraction(numer, lcm);
}
const Fraction operator-(const Fraction &a, const Fraction &b) {
  return operator+(a, Fraction(-b.numer, b.denom));
}
const Fraction operator*(const Fraction &a, const Fraction &b) {
  long long gcd = Fraction::gcd(a.numer, b.denom);
  long long numer = a.numer / gcd;
  long long denom = b.denom / gcd;
  gcd = Fraction::gcd(b.numer, a.denom);
  numer *= b.numer / gcd;
  denom *= a.denom / gcd;
  return Fraction(numer, denom);
}
const Fraction operator/(const Fraction &a, const Fraction &b) {
  return operator*(a, Fraction(b.denom, b.numer));
}
Fraction &Fraction::operator+=(const Fraction &b) { return *this = *this + b; }
Fraction &Fraction::operator-=(const Fraction &b) { return *this = *this - b; }
Fraction &Fraction::operator*=(const Fraction &b) { return *this = *this * b; }
Fraction &Fraction::operator/=(const Fraction &b) { return *this = *this / b; }
Fraction Fraction::operator+() { return Fraction(this->numer, this->denom); };
Fraction Fraction::operator-() {
  return Fraction(-(this->numer), this->denom);
};
Fraction &Fraction::operator++() { return *this += 1; }
Fraction &Fraction::operator--() { return *this += -1; }
Fraction Fraction::operator++(int) {
  Fraction tmp = *this;
  *this += 1;
  return tmp;
}
Fraction Fraction::operator--(int) {
  Fraction tmp = *this;
  *this += -1;
  return tmp;
}
long long modpow(long long a, long long n, long long p) {
  long long out = 1;
  while (n) {
    if (n & 1) {
      out = out * a % p;
    }
    a = a * a % p;
    n >>= 1;
  }
  return out;
}
int main() {
  lint n;
  scanf("%lld", &n);
  std::vector<Fraction> ab, ba;
  lint a0, b0, ab0;
  a0 = b0 = ab0 = 0;
  for (int i = 0; i < n; ++i) {
    lint a, b;
    scanf("%lld", &a);
    scanf("%lld", &b);
    if (a != 0 && b != 0) {
      ab.push_back(Fraction(a, b));
      ba.push_back(Fraction(-b, a));
    } else if (a == 0 && b == 0) {
      ab0++;
    } else if (a != 0 && b == 0) {
      b0++;
    } else {
      a0++;
    }
  }
  std::map<Fraction, lint> abm;
  std::map<Fraction, lint> bam;
  for (int i = 0; i < ab.size(); ++i) {
    auto cur = ab[i];
    if (abm.find(cur) != abm.end()) {
      abm[cur]++;
    } else {
      abm[cur] = 1;
    }
    cur = ba[i];
    if (bam.find(cur) != bam.end()) {
      bam[cur]++;
    } else {
      bam[cur] = 1;
    }
  }
  lint mod = 1e9 + 7;
  lint ans = 1;
  std::map<Fraction, lint> done;
  for (auto iter = abm.begin(); iter != abm.end(); iter++) {
    if (bam.find(iter->first) != bam.end()) {
      if (done.find(iter->first) != done.end()) {
        continue;
      } else {
        lint x = iter->second;
        lint y = bam[iter->first];
        auto f = iter->first;
        lint kake = 0;
        kake += (modpow(2, x, mod) + modpow(2, y, mod) - 1);
        ans *= kake;
        ans %= mod;
        done.insert(std::make_pair(Fraction(-f.getDenom(), f.getNumer()), 1));
      }
    } else {
      lint x = iter->second;
      lint kake = modpow(2, x, mod);
      ans *= kake;
      ans %= mod;
    }
  }
  ans *= modpow(2, ab0, mod);
  ans %= mod;
  ans *= (modpow(2, a0, mod) + modpow(2, b0, mod) - 1);
  ans %= mod;
  std::cout << ans - 1 << "\n";
  return 0;
}
