import           Control.Monad      (foldM, replicateM)
import           Data.Bits          (popCount, testBit)
import           Data.IntMap.Strict ((!))
import qualified Data.IntMap.Strict as M


main :: IO ()
main = do
  n <- readLn
  ts <- replicateM n readTestimony
  print $ solve n ts

solve :: Int -> [(Int, [(Int, Int)])] -> Int
solve n ts = maximum $ map popCount xs
  where xs = filter (isValid n ts) [0 .. 2^n-1]

isValid :: Int -> [(Int, [(Int, Int)])] -> Int -> Bool
isValid n ts x = validate x $ foldM f m xys'
  where m = M.fromList [(i, Undefined) | i <- [1 .. n]]
        xys' = concat [xys | ((_, xys), i) <- zip ts [0..], testBit x i]

f :: M.IntMap Personality -> (Int, Int) -> Maybe (M.IntMap Personality)
f m (x, y)
  | z == p         = Just m
  | z == Undefined = Just $ M.insert x p m
  | otherwise      = Nothing
  where p = toEnum y
        z = m ! x

data Personality = Unkind | Honest | Undefined
  deriving (Show, Eq, Enum)

validate :: Int -> Maybe (M.IntMap Personality) -> Bool
validate _ Nothing  = False
validate x (Just m) = all (g x) $ M.toList m

g :: Int -> (Int, Personality) -> Bool
g x (i, p) = p == Undefined || p == p'
  where p' = if testBit x (i - 1) then Honest else Unkind

readTestimony :: IO (Int, [(Int, Int)])
readTestimony = do
  a <- readLn
  xys <- replicateM a readInt2
  return (a, xys)

readInt2 :: IO (Int, Int)
readInt2 = do
  [x, y] <- map read . words <$> getLine
  return (x, y)
