import java.io.{BufferedReader, InputStreamReader}

import scala.collection.mutable

object Main {
  def main(args: Array[String]): Unit = {
    val in = new BufferedReader(new InputStreamReader(System.in))
    val n = in.readLine().toInt

    val evs =
      (0 until n).map { _ =>
        val a = in.readLine().toInt
        (0 until a).map { _ =>
          in.readLine().split("\\s+").map(_.toInt) match {
            case Array(x, y) => Array(x - 1, y)
          }
        }
      }

    def maxHonests(persons: Array[Int], statuses: Array[Int]): Option[Int] = {
      persons.map { i =>
        val subStatuses = statuses.clone()
        subStatuses(i) = 1

        val honestsQueue = new mutable.Queue[Int]()
        honestsQueue += i

        var inconsistence = false

        while (honestsQueue.nonEmpty) {
          val honest = honestsQueue.dequeue()
          evs(honest).foreach { ev =>
            if (ev(1) == 1) {
              if (subStatuses(ev(0)) == 2) {
                inconsistence = true
              } else if (subStatuses(ev(0)) == 0) {
                subStatuses(ev(0)) = 1
                honestsQueue += ev(0)
              }
            } else {
              if (subStatuses(ev(0)) == 1) {
                inconsistence = true
              } else if (subStatuses(ev(0)) == 0) {
                subStatuses(ev(0)) = 2
              }
            }
          }
        }

        if (inconsistence) {
          None
        } else {
          val subPersons = persons.filter(p => subStatuses(p) == 0)
          if (subPersons.nonEmpty) {
            maxHonests(subPersons, subStatuses) match {
              case Some(subMax) => Some(subMax)
              case None => Some(subStatuses.count(_ == 1))
            }
          } else {
            Some(subStatuses.count(_ == 1))
          }
        }
      }.max
    }

    System.out.println(
      maxHonests((0 until n).toArray, new Array[Int](n)) match {
        case Some(max) => max
        case None => 0
      }
    )
  }
}
