#include <bits/stdc++.h>
using ll = long long;
using uint = unsigned int;
using graph = std::vector<std::vector<ll>>;
using wGraph = std::vector<std::vector<std::pair<ll, ll>>>;
using namespace std;
ll MOD7 = 1000000007;
ll MOD9 = 1000000009;
vector<ll> InputVec(ll N) {
  vector<ll> A(N);
  for (int i = 0; i < N; ++i) {
    cin >> A[i];
  }
  return A;
}
void OutputVec(vector<ll> A) {
  for (int i = 0; i < A.size(); ++i) {
    cout << A[i] << ",";
  }
  cout << endl;
}
vector<vector<ll>> InputVec2d(ll H, ll W) {
  vector<vector<ll>> A(H);
  for (int yi = 0; yi < H; ++yi) {
    A[yi] = vector<ll>(W);
  }
  for (int yi = 0; yi < H; ++yi) {
    for (int xi = 0; xi < W; ++xi) {
      cin >> A[yi][xi];
    }
  }
  return A;
}
vector<vector<char>> InputVec2dStr(ll H, ll W) {
  vector<vector<char>> A(H);
  for (int yi = 0; yi < H; ++yi) {
    A[yi] = vector<char>(W);
  }
  for (int yi = 0; yi < H; ++yi) {
    string S;
    cin >> S;
    for (int xi = 0; xi < W; ++xi) {
      A[yi][xi] = S[xi];
    }
  }
  return A;
}
void OutputVec2d(vector<vector<ll>> A) {
  for (int yi = 0; yi < A.size(); ++yi) {
    for (int xi = 0; xi < A[yi].size(); ++xi) {
      cout << A[yi][xi] << ",";
    }
    cout << endl;
  }
}
graph InputGraph(ll N, ll M) {
  graph G(N);
  for (int i = 0; i < M; ++i) {
    ll a, b;
    cin >> a >> b;
    a--;
    b--;
    G[a].push_back(b);
    G[b].push_back(a);
  }
  return G;
}
graph InputDGraph(ll N, ll M) {
  graph G(N);
  for (int i = 0; i < M; ++i) {
    ll a, b;
    cin >> a >> b;
    a--;
    b--;
    G[a].push_back(b);
  }
  return G;
}
wGraph InputWGraph(ll N, ll M) {
  wGraph G(N);
  for (int i = 0; i < M; ++i) {
    ll a, b, c;
    cin >> a >> b >> c;
    a--;
    b--;
    G[a].push_back(make_pair(b, c));
    G[b].push_back(make_pair(a, c));
  }
  return G;
}
wGraph InputDWGraph(ll N, ll M) {
  wGraph G(N);
  for (int i = 0; i < M; ++i) {
    ll a, b, c;
    cin >> a >> b >> c;
    a--;
    b--;
    G[a].push_back(make_pair(b, c));
  }
  return G;
}
void OutputGraph(graph G) {
  for (int i = 0; i < G.size(); ++i) {
    cout << i << ":";
    for (int j = 0; j < G[i].size(); ++j) {
      cout << G[i][j] << ",";
    }
    cout << endl;
  }
}
void OutputGraph(wGraph G) {
  for (int i = 0; i < G.size(); ++i) {
    cout << i << ":";
    for (int j = 0; j < G[i].size(); ++j) {
      cout << G[i][j].first << "/" << G[i][j].second << ",";
    }
    cout << endl;
  }
}
void OutputAnswerBool(bool b, bool isUpperCase = false) {
  if (b) {
    if (isUpperCase) {
      cout << "YES" << endl;
    } else {
      cout << "Yes" << endl;
    }
  } else {
    if (isUpperCase) {
      cout << "NO" << endl;
    } else {
      cout << "No" << endl;
    }
  }
}
ll gcd(ll a, ll b) {
  if (a < b) return gcd(b, a);
  ll r;
  while ((r = a % b)) {
    a = b;
    b = r;
  }
  return b;
}
ll lcm(ll a, ll b) {
  ll g;
  g = gcd(a, b);
  return a * b / g;
}
long long modpow(long long a, long long n, long long mod) {
  long long res = 1;
  while (n > 0) {
    if (n & 1) res = res * a % mod;
    a = a * a % mod;
    n >>= 1;
  }
  return res;
}
int main() {
  ll N;
  cin >> N;
  map<pair<pair<ll, ll>, bool>, ll> bucket;
  ll wildA = 0;
  ll wildB = 0;
  ll zero = 0;
  for (int i = 0; i < N; ++i) {
    ll a, b;
    cin >> a >> b;
    if (a == 0 && b == 0) {
      zero++;
      continue;
    }
    if (a == 0) {
      wildA++;
      continue;
    } else {
      if (b == 0) {
        wildB++;
        continue;
      }
    }
    bool isSameSign = a * b >= 0;
    a = abs(a);
    b = abs(b);
    ll g = gcd(a, b);
    a /= g;
    b /= g;
    bucket[make_pair(make_pair(a, b), isSameSign)]++;
  }
  auto begin = bucket.begin(), end = bucket.end();
  map<pair<pair<ll, ll>, bool>, ll> seen;
  ll wild = (modpow(2, wildA, MOD7) + modpow(2, wildB, MOD7) - 1 + MOD7) % MOD7;
  ll count = wild;
  count %= MOD7;
  for (auto iter = begin; iter != end; iter++) {
    ll a = iter->first.first.first;
    ll b = iter->first.first.second;
    ll sig = iter->first.second;
    if (seen[make_pair(make_pair(a, b), sig)]) {
      continue;
    }
    count *=
        (modpow(2, bucket[make_pair(make_pair(a, b), sig)], MOD7) +
         modpow(2, bucket[make_pair(make_pair(b, a), !sig)], MOD7) - 1 + MOD7) %
        MOD7;
    count %= MOD7;
    seen[make_pair(make_pair(a, b), sig)] = true;
    seen[make_pair(make_pair(b, a), !sig)] = true;
  }
  cout << (count - 1 + MOD7 + zero) % MOD7 << endl;
}
