import qualified Data.Vector as V
import qualified Data.Map as MP
import Control.Monad
import Data.Bits
import Debug.Trace

toBitV :: Int -> Int -> V.Vector Int
toBitV n l
    | l == 0 = V.empty 
    | otherwise = V.snoc (toBitV (shiftR n 1) (l - 1)) (n .&. 1)

solve :: V.Vector (V.Vector (Int,Int)) -> Int -> Int -> Int
solve vec n i 
  | cond1 && (not cond2) = V.length $ V.filter (==1) bs
  | otherwise = 0
  where
    bs = toBitV i n

    zs :: V.Vector (Int, V.Vector (Int, Int))
    zs = V.zip bs vec

    init = foldl (\m k -> MP.insert k [] m) MP.empty [1..n]

    res :: MP.Map Int [Int]
    res = V.foldl step init zs

    step :: MP.Map Int [Int] -> (Int, V.Vector (Int, Int)) -> MP.Map Int [Int]
    step mp (b,xs) = V.foldl (step' b) mp xs

    step' :: Int -> MP.Map Int [Int] -> (Int, Int) -> MP.Map Int [Int]
    step' b mp (p,s)
      | b == 0 && s == 0 = MP.adjust (1:) p mp
      | b == 0 && s == 1 = MP.adjust (0:) p mp
      | b == 1 && s == 0 = MP.adjust (0:) p mp
      | b == 1 && s == 1 = MP.adjust (1:) p mp

    cond1 = MP.foldl (\b vs -> b && ((all (==1) vs) || (all (==0) vs))) True res
    cond2 = MP.foldl (\b vs ->  b && (all (==0) vs)) True res

main = do
  n <- readLn :: IO Int
  vec <- V.replicateM n $ do
    a <- readLn :: IO Int
    xs <- V.replicateM a $ do
      [x,y] <- map read . words <$> getLine :: IO [Int]
      return (x,y)
    return xs
  let res = [solve vec n i | i <- [1..2^n-1]] 
  print $ maximum res
