fun readString() = readLine()!!
fun readInt() = readLine()!!.toInt()
fun readLong() = readLine()!!.toLong()
fun readIntList() = readLine()!!.split(" ").map(String::toInt)
fun readLongList() = readLine()!!.split(" ").map(String::toLong)
fun <T> Array<Array<T>>.print() {
    this.forEach {
        println(it.joinToString(" "))
    }
}

fun power(x: Int, n: Int): Int = when {
    n == 0 -> 1
    n == 2 -> (x * x)
    n % 2 == 1 -> (power(x, n - 1) * x)
    else -> {
        val tmp = power(x, n / 2)
        tmp * tmp
    }
}

fun oneCount(b: Int): Int {
    var i = 0
    var cnt = 0
    while (power(2, i) <= b) {
        if ((b shr i) and 1 == 1) {
            cnt++
        }
        i++
    }
    return cnt
}

fun main(args: Array<String>) {
    val N = readInt()
    val say: MutableList<MutableList<Pair<Int, Int>>> = mutableListOf()

    for (i in 0 until N) {
        val a = readInt()
        val list: MutableList<Pair<Int, Int>> = mutableListOf()
        for (j in 0 until a) {
            val (fir, end) = readIntList()
            list.add(Pair(fir - 1, end))
        }
        say.add(list)
    }

    var res = 0
    for (b in 0 until power(2, N)) {
        var ok = true
      
        for (i in 0 until N) {
            val fromState = (b shr i) and 1
          
            for (j in 0 until say[i].size) {
                val toNum = say[i][j]
                val toState = (b shr toNum.first) and 1
                val fromSay = toNum.second

                if (fromState == 1 && toState != fromSay) {
                    ok = false
                    break
                }
            }
        }

        if (ok) {
            res = oneCount(b).coerceAtLeast(res)
        }
    }

    println(res)
}
