#include <stdio.h>
#define swap(type, x, y)  do{ type t = x; x = y; y = t; }while(0)
#define abs(x) ((x)<0 ? -(x) : (x))
#define sign(x) ((x)<0 ? -1 : 1)
#define max(x, y) ((x)<(y) ? (y) : (x))
#define min(x, y) ((x)>(y) ? (y) : (x))

long gcd(long a, long b){
  if(a%b == 0)
    return b;
  else
    gcd(b, a%b);
}

long long int modpow(long a, long b, long c){//a^b%c
  long long re = 1;
  while(b >= 1){
    if(b & 1) re = re * a % c;
    a = a * a % c;
    b = b >> 1;
  }
  return re;
}

int main(){
  long mod = 1000000007;
  int n;  scanf("%d", &n);
  int zero = 0;
  long mp[200005][4] = {0};
  int mpsize = 0;
  for(int i=1; i<=n; i++){
    long x, y;  scanf("%ld %ld", &x, &y);
    if(!x && !y){
      zero++;
      continue;
    }
    if(x!=0 && y!=0){
      long ma = max(abs(x), abs(y)),  mi = min(abs(x), abs(y));
      long g = gcd(ma, mi);
      x /= g;
      y /= g;
    }
    if(y < 0)  y = -y,  x = -x;
    if(y==0 && x<0)  y = -y,  x = -x;
    int rot90 = (x <= 0);
    if(rot90){
      swap(long, x, y);
      y = -y;
    }
    int flag = mpsize + 1;
    for(int i=1; i<=mpsize; i++)
      if(mp[i][0]==x && mp[i][1]==y){
	flag = i;
	break;
      }
    if(flag == mpsize+1){
      mpsize++;
      mp[flag][0] = x;
      mp[flag][1] = y;
    }
    if(rot90)  mp[flag][2]++;
    else  mp[flag][3]++;
    
  }
  long ans = 1;
  for(int i=1; i<=mpsize; i++){
    int s = mp[i][2];
    int t = mp[i][3];
    int now = 1;
    now = now + modpow(2, (long)s, mod) - 1;
    now = now + modpow(2, (long)t, mod) - 1;
    ans *= now;
  }
  ans -= 1;
  ans += zero;
  
  printf("%ld\n", ans);
  return 0;
}
