#include <bits/stdc++.h>
using namespace std;
const int MOD = 1000000007;
const long double PI = atan((long double)1.0) * 4.0;
const long double divbyinf = 1.0e-19L;
vector<long long> Power2;
void initPower2(int expmax) {
  long long power2buf = 1;
  for (int i = 0; i < expmax; i++) {
    Power2.push_back(power2buf);
    power2buf *= 2;
    power2buf %= MOD;
  }
}
bool mysearchset(set<long double> sset, long double svalue) {
  bool res = false;
  if (sset.lower_bound(svalue - divbyinf) !=
      sset.upper_bound(svalue + divbyinf))
    res = true;
  return res;
}
int main(void) {
  int N;
  long long Abuf, Bbuf;
  vector<long double> Sociability;
  vector<int> Hatred;
  vector<int> Friendship;
  int Gloomy = 0;
  initPower2(200001);
  cin >> N;
  for (int i = 0; i < N; i++) {
    cin >> Abuf >> Bbuf;
    if ((Abuf != 0) || (Bbuf != 0)) {
      Sociability.push_back(atan2((long double)Bbuf, (long double)Abuf));
    } else {
      Gloomy++;
    }
  }
  sort(Sociability.begin(), Sociability.end());
  for (int i = 0; i < N; i++) {
    int Hbuf = upper_bound(Sociability.begin(), Sociability.end(),
                           Sociability[i] + PI / 2.0 + divbyinf) -
               lower_bound(Sociability.begin(), Sociability.end(),
                           Sociability[i] + PI / 2.0 - divbyinf);
    Hbuf += upper_bound(Sociability.begin(), Sociability.end(),
                        Sociability[i] - PI / 2.0 + divbyinf) -
            lower_bound(Sociability.begin(), Sociability.end(),
                        Sociability[i] - PI / 2.0 - divbyinf);
    Hbuf += upper_bound(Sociability.begin(), Sociability.end(),
                        Sociability[i] + 3.0 * PI / 2.0 + divbyinf) -
            lower_bound(Sociability.begin(), Sociability.end(),
                        Sociability[i] + 3.0 * PI / 2.0 - divbyinf);
    Hbuf += upper_bound(Sociability.begin(), Sociability.end(),
                        Sociability[i] - 3.0 * PI / 2.0 + divbyinf) -
            lower_bound(Sociability.begin(), Sociability.end(),
                        Sociability[i] - 3.0 * PI / 2.0 - divbyinf);
    Hatred.push_back(Hbuf);
    int Fbuf =
        upper_bound(Sociability.begin(), Sociability.end(), Sociability[i]) -
        lower_bound(Sociability.begin(), Sociability.end(), Sociability[i]);
    Fbuf += upper_bound(Sociability.begin(), Sociability.end(),
                        Sociability[i] + PI) -
            lower_bound(Sociability.begin(), Sociability.end(),
                        Sociability[i] + PI);
    Fbuf += upper_bound(Sociability.begin(), Sociability.end(),
                        Sociability[i] - PI) -
            lower_bound(Sociability.begin(), Sociability.end(),
                        Sociability[i] - PI);
    Friendship.push_back(Fbuf);
  }
  set<long double> setSociability;
  long long res = 1;
  for (int i = 0; i < Sociability.size(); i++) {
    if (mysearchset(setSociability, Sociability[i]) ||
        mysearchset(setSociability, Sociability[i] + PI) ||
        mysearchset(setSociability, Sociability[i] - PI))
      continue;
    if (mysearchset(setSociability, Sociability[i] + PI / 2.0) ||
        mysearchset(setSociability, Sociability[i] - PI / 2.0) ||
        mysearchset(setSociability, Sociability[i] + 3.0 * PI / 2.0) ||
        mysearchset(setSociability, Sociability[i] - 3.0 * PI / 2.0))
      continue;
    setSociability.insert(Sociability[i]);
    long long casebuf = Power2[Hatred[i]] + Power2[Friendship[i]] - 1;
    casebuf %= MOD;
    res *= casebuf;
    res %= MOD;
  }
  cout << res + Gloomy - 1 << endl;
  return 0;
}
