import kotlin.math.abs

data class Rational(val numerator: Long, val denominator: Long) {
    // 有理数クラス
    // 分子numerator, 分母denominator
    companion object Factory {
        private tailrec fun gcd(a: Long, b: Long): Long =
            when {
                b > a -> gcd(b, a)
                b == 0L -> a
                else -> gcd(b, a % b)
            }

        // 常に分子が正となるようなファクトリ
        fun create(numerator: Long, denominator: Long): Rational {
            val gcd = gcd(abs(numerator), abs(denominator))
            return if (numerator < 0) {
                Rational(numerator * -1L / gcd, denominator * -1L / gcd)
            } else {
                Rational(numerator / gcd, denominator / gcd)
            }
        }
    }
}

fun main() {
    val builder = StringBuilder()

    val mod = 1000000007L

    val n = readInputLine().toInt()

    val pow = LongArray(n + 1)
    pow[0] = 1L

    for (i in 1..n) {
        pow[i] = pow[i - 1] * 2L % mod
    }

    val cnt = mutableMapOf<Rational, Int>()

    var zeroCnt = 0L

    repeat(n) {
        val (a, b) = readInputLine().split(" ").map { it.toLong() }

        if (a == 0L && b == 0L) {
            zeroCnt++
        } else {
            val tmp = when {
                a == 0L -> Rational(0L, 1L)
                b == 0L -> Rational(1L, 0L)
                else -> Rational.create(a, b)
            }
            cnt[tmp] = (cnt[tmp] ?: 0) + 1
        }
    }

    val checked = mutableSetOf<Rational>()

    var ans = 1L

    for ((r, c) in cnt) {
        if (checked.contains(r)) {
            continue
        }
        val other = Rational.create(r.denominator * -1L, r.numerator)

        if (cnt.containsKey(other)) {
            ans = ans * (pow[c] + pow[cnt[other]!!] - 1) % mod
        } else {
            ans = ans * pow[c] % mod
        }

        checked.add(r)
        checked.add(other)
    }

    builder.appendln((ans + zeroCnt + mod - 1L) % mod)

    print(builder.toString())
}

fun readInputLine(): String {
    return readLine()!!
}
