import java.math.BigInteger
import kotlin.math.abs

val MOD = 1000000007L.toBigInteger()

fun main() {
    val n = readLine()!!.toInt()

    val group = mutableMapOf<Pair<Long, Long>, Int>()
    var worstIwashiCount = 0L

    repeat(n) {
        var (a, b) = readLine()!!.split(" ").map { it.toLong() }

        if (a == 0L && b == 0L) {
            worstIwashiCount++
        } else if (a == 0L) {
            increment(0L to -1L, group)
        } else if (b == 0L) {
            increment(1L to 0L, group)
        } else {
            val gcd = gcd(a, b)
            a /= gcd
            b /= gcd
            if (a < 0) {
                a *= -1
                b *= -1
            }
            increment(a to b, group)
        }
    }
    var ans = BigInteger.ONE

    while (group.isNotEmpty()) {
        val (k, count) = group.entries.first()
        val (a, b) = k
        group.remove(k)

        val pairCount = group.remove(
            if (b < 0) -b to a else b to -a
        ) ?: 0

        ans *= (pow2(count) + pow2(pairCount) - BigInteger.ONE) % MOD
        ans %= MOD
    }
    println(((ans + worstIwashiCount.toBigInteger() - BigInteger.ONE) % MOD).toInt())
}

fun pow2(n: Int): BigInteger {
    val two = BigInteger.valueOf(2)
    return two.pow(n) % MOD
}

fun <K> increment(key: K, m: MutableMap<K, Int>) {
    val n = m.getOrDefault(key, 0)
    m[key] = n + 1
}

fun gcd(a: Long, b: Long): Long {
    tailrec fun go(c: Long, d: Long): Long = if (d == 0L) c else go(d, c % d)
    return go(abs(a), abs(b))
}
