import kotlin.math.pow

val M = 1000000007L

fun main() {
    val n = readLine()!!.toInt()
    var zeros = 0L
    val iwashiMap = mutableMapOf<Fraction, Int>()
    repeat(n) {
        val (a, b) = readLine()!!.split(" ")
        val aa = a.toLong()
        val bb = b.toLong()
        if (aa == 0L && bb == 0L) {
            zeros += 1
        } else {
            val f = fraction(aa, bb)
            val v = iwashiMap.getOrDefault(f, 0)
            iwashiMap[f] = v + 1
        }
    }

    val iwashiKeys = iwashiMap.keys
    var ans = 1L

    while (iwashiKeys.isNotEmpty()) {
        val f = iwashiKeys.first()
        val o = f.opposite()
        val c = iwashiMap.getValue(f)
        val oc = iwashiMap.getOrDefault(o, 0)
        iwashiKeys -= f
        iwashiKeys -= o
        ans *= pow2(c) + pow2(oc) - 1
        ans %= M
    }

    println((ans + zeros) % M - 1)
}

fun pow2(n: Int): Int = 2.0.pow(n).toInt()

data class Fraction(val m: Long, val n: Long) {
    fun opposite(): Fraction = if (m > 0) Fraction(-n, m) else Fraction(n, -m)
}

fun fraction(m: Long, n: Long): Fraction {
    return when {
        m == 0L && n == 0L -> throw Exception()
        m == 0L -> Fraction(0, 1)
        n == 0L -> Fraction(1, 0)
        else -> {
            val a = gcd(m, n)
            Fraction(m / a, n / a)
        }
    }
}

tailrec fun gcd(a: Long, b: Long): Long = if (b == 0L) a else gcd(b, a % b)
