import kotlin.math.pow

val M = 1000000007L
val iM = 1000000007

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()
        val f = fraction(aa, bb)
        if (f is Fraction.Zero) {
            zeros += 1
        } else {
            val v = iwashiMap.getOrDefault(f, 0)
            iwashiMap[f] = v + 1
        }
    }
    val iwashiKeys = iwashiMap.keys
    iwashiKeys.forEach { f ->
        val o = f.opposite()
        val index = iwashiKeys.indexOf(o)
        if (index != -1) f.oppositeIndex = index
    }

    val results = IntArray(2.0.pow(iwashiMap.size).toInt() - 1) { 0 }

    iwashiKeys.forEachIndexed { i, f ->
        val pn = pow2(iwashiMap.getValue(f)) - 1
        val baseIndex = pow2(i) - 1
        for (j in 0 until baseIndex) {
            results[baseIndex + j] = results[j] * pn % iM
        }
        results[pow2(i + 1) - 2] = pn
        val oppositeIndex = f.oppositeIndex
        if (oppositeIndex == null || oppositeIndex > i) return@forEachIndexed

        val excludes = pow2(oppositeIndex).let { it - 1 until it - 1 + it }.toMutableList()
        for (j in oppositeIndex + 1..i) {
            val base = pow2(j) - 1
            val curExcludes = excludes.map { it + base }
            excludes += curExcludes
            if (j == i) curExcludes.forEach { results[it] = 0 }
        }
    }

    val index = results.fold(0L) { b, a -> (a + b) % M }
    val result = (zeros + index) % M
    println(result)
}

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

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

    object ZeroOne : Fraction() {
        override fun opposite(): Fraction = OneZero
    }

    object OneZero : Fraction() {
        override fun opposite(): Fraction = ZeroOne
    }

    object Zero : Fraction() {
        override fun opposite(): Fraction = Zero
    }

    abstract fun opposite(): Fraction
    var oppositeIndex: Int? = null
}

fun fraction(m: Long, n: Long): Fraction {
    return when {
        m == 0L && n == 0L -> Fraction.Zero
        m == 0L -> Fraction.ZeroOne
        n == 0L -> Fraction.OneZero
        else -> {
            val a = gcd(m, n)
            Fraction.F(m / a, n / a)
        }
    }
}

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