import algorithm, macros, math, sequtils, strutils, tables
# import bitops, lenientops, deques,
#   heapqueue, sets, sugar
 
let read* = iterator: string {.closure.} =
  while true: (for s in stdin.readLine.split: yield s)
 
template input*(T: static[typedesc]): untyped = 
  when T is int: read().parseInt
  elif T is float: read().parseFloat
  elif T is string: read()
  elif T is char: read()[0]
 
macro dump*(args: varargs[typed]): untyped =
  result = newNimNode(nnkStmtList)
  for x in args:
    let s = toStrLit(x)
    result.add quote do: stderr.write `s`, " = ", `x`, " "
  result.add quote do: stderr.write "\n"
 
proc `|=`*(n: var int, m: int) = n = n or m
proc `|=`*(n: var bool, m: bool) = n = n or m
proc `&=`*(n: var int, m: int) = n = n and m
proc `&=`*(n: var bool, m: bool) = n = n and m
proc `^=`*(n: var int, m: int) = n = n xor m
proc `^=`*(n: var bool, m: bool) = n = n xor m
proc `%=`*(n: var int, m: int) = n = n mod m
proc `/=`*(n: var int, m: int) = n = n div m
proc `<<=`*(n: var int, m: int) = n = n shl m
proc `>>=`*(n: var int, m: int) = n = n shr m
proc `<?=`*(n: var SomeNumber, m: SomeNumber) = n = min(n, m)
proc `>?=`*(n: var SomeNumber, m: SomeNumber) = n = max(n, m)
proc newSeq2*[T](n1, n2: Natural): seq[seq[T]] = newSeqWith(n1, newSeq[T](n2))
proc newSeq3*[T](n1, n2, n3: Natural): seq[seq[seq[T]]] = newSeqWith(n1, newSeqWith(n2, newSeq[T](n3)))
proc newSeq4*[T](n1, n2, n3, n4: Natural): seq[seq[seq[seq[T]]]] = newSeqWith(n1, newSeqWith(n2, newSeqWith(n3, newSeq[T](n4))))
 
# -------------------------------------------------- #

const p = 10 ^ 9 + 7

proc modPow(A: int, N: int, P: int): int =
  var (a, n, p) = (A, N, P)
  result = 1
  while n > 0:
    if (n and 1) == 1:
      result = result * a mod p
    a = a * a mod p
    n = n shr 1

let N = input(int)
var cnt = initCountTable[tuple[a, b, h: int]]()
var used = initTable[tuple[a, b, h: int], bool]()

var res = 1
var c1 = 0
var c2 = 0

for i in 1 .. N:
  var c, d = input(int)
  var h =
    if c > 0 and d > 0: 1
    elif c < 0 and d < 0: 1
    elif c == 0 or d == 0: 0
    else: -1
  var e = gcd(abs(c), abs(d))
  var a, b: int
  if c == 0 and d == 0:
    discard
  elif h == 0:
    if c != 0 and d == 0:
      c1 += 1
    elif c == 0 and d != 0:
      c2 += 1
    else:
      assert false
  else:
    a = abs(c) div e
    b = abs(d) div e
    cnt.inc((a, b, h))
    used[(a, b, h)] = true

res *= (modPow(2, c1, p) - 1) + (modPow(2, c2, p) - 1) + 1
res %= p

for key in cnt.keys:
  let (a, b, h) = key
  if used[(a, b, h)] == false:
    #dump("skip", key)
    continue
  var coe = 0
  coe += modpow(2, cnt[(a, b, h)], p) - 1
  coe %= p
  if h != 0 and used.haskey((b, a, -h)) and used[(b, a, -h)] == true:
    coe += modpow(2, cnt[(b, a, -h)], p) - 1
    coe %= p
    used[(b, a, -h)] = false
  coe += 1
  coe += p
  coe += p
  coe %= p
  res *= coe
  res %= p
  used[(a, b, h)] = false
res = (res - 1 + p) mod p
echo res