fun main(args: Array<String>) {
  val n = readLine()!!.toInt()
  val map = mutableMapOf<Pair<Long, Long>, Int>()
  var zero = 0
  repeat(n) {
    val (a, b) = readLine()!!.split(" ").map { it.toLong() }
    if (a == 0L && b == 0L) {
      zero++
      return@repeat
    }
    val g = gcd(a, b)
    val p = when {
      b > 0L -> a/g to b/g
      b < 0L -> -a/g to -b/g
      else -> 1L to 0L
    }
    map[p] = (map[p] ?: 0)+1
  }
  val ans = ModInt(1)
  val base = ModInt(2)
  for (p in map.keys) {
    if (p.first <= 0L && map.containsKey(p.second to -p.first)) continue
    val q = -p.second to p.first
    ans *= base.pow(map[q] ?: 0) + base.pow(map[p]!!) - 1
  }
  println(ans + zero - 1)
}

fun gcd(a: Long, b: Long): Long {
  val _a = kotlin.math.abs(a)
  val _b = kotlin.math.abs(b)
  var x = kotlin.math.max(_a, _b)
  var y = kotlin.math.min(_a, _b)
  var ret = x
  while (y > 0L) {
    ret = y
    y = x % y
    x = ret
  }
  return ret
}

class ModInt(private var value: Long = 0L) {
    companion object {
        var modulo = 1_000_000_007L
    }
    constructor(value: Byte): this(value.toLong())
    constructor(value: Short): this(value.toLong())
    constructor(value: Int): this(value.toLong())

    init { initialize() }

    private fun initialize() {
        if (value in 0L until modulo) return
        value %= modulo
        if (value < 0L) value += modulo
    }

    fun inv(): ModInt {
        var (a, b, c, n) = listOf(value, modulo, 0L, 1L)
        while (b != 0L) {
            val (x, y, z, m) = listOf(b, a % b, n - a / b * c, c)
            a = x
            b = y
            c = z
            n = m
        }
        return ModInt(n)
    }

    fun <T : Number> pow(power: T): ModInt {
        var ret = 1L
        var i = value
        var n = power.toLong()
        while (n > 0L) {
            if (n and 1L == 1L) ret = ret * i % modulo
            i = i * i % modulo
            n = n shr 1
        }
        return ModInt(ret)
    }

    override fun toString(): String = value.toString()

    operator fun unaryPlus(): ModInt = this
    operator fun unaryMinus(): ModInt = if (value == 0L) this else ModInt(modulo-value)
    operator fun inc(): ModInt = if (value == 0L) this else ModInt(modulo-value)
    operator fun dec(): ModInt = if (value == 0L) ModInt(modulo-1L) else ModInt(value-1L)
    operator fun plus(other: ModInt): ModInt = if (value + other.value < modulo) ModInt(value + other.value)
    else ModInt(value + other.value - modulo)
    operator fun minus(other: ModInt): ModInt = if (value - other.value >= 0L) ModInt(value - other.value)
    else ModInt(value - other.value + modulo)
    operator fun times(other: ModInt): ModInt = if (value * other.value < modulo) ModInt(value * other.value)
    else ModInt(value * other.value % modulo)
    operator fun div(other: ModInt): ModInt = times(other.inv())
    operator fun plusAssign(other: ModInt) {
        value += if (value + other.value < modulo) other.value else other.value - modulo
    }
    operator fun minusAssign(other: ModInt) {
        value -= if (value - other.value >= 0L) other.value else other.value - modulo
    }
    operator fun timesAssign(other: ModInt) {
        value = if (value * other.value < modulo) value * other.value else value * other.value % modulo
    }
    operator fun divAssign(other: ModInt) = timesAssign(other.inv())

    operator fun <T : Number> plus(other: T): ModInt = plus(ModInt(other.toLong()))
    operator fun <T : Number> minus(other: T): ModInt = minus(ModInt(other.toLong()))
    operator fun <T : Number> times(other: T): ModInt = times(ModInt(other.toLong()))
    operator fun <T : Number> div(other: T): ModInt = div(ModInt(other.toLong()))
    operator fun <T : Number> plusAssign(other: T) = plusAssign(ModInt(other.toLong()))
    operator fun <T : Number> minusAssign(other: T) = minusAssign(ModInt(other.toLong()))
    operator fun <T : Number> timesAssign(other: T) = timesAssign(ModInt(other.toLong()))
    operator fun <T : Number> divAssign(other: T) = divAssign(ModInt(other.toLong()))
}