local mmi, mma = math.min, math.max
local bls, brs = bit.lshift, bit.rshift
local bxor = bit.bxor

local function grayCode(x)
  return bxor(x, brs(x, 1))
end

-- add_func(idx), rm_func(idx), work_func()
local function grayWalk(size, add_func, rm_func, work_func)
  local prv = 0
  local total = bls(1, size) - 1
  local bpos = {}
  for i = 1, size do
    bpos[bls(1, i - 1)] = i
  end
  work_func()
  for i = 1, total do
    local v = grayCode(i)
    if prv < v then
      prv, v = v, v - prv
      add_func(bpos[v])
    else
      prv, v = v, prv - v
      rm_func(bpos[v])
    end
    work_func()
  end
end

local n = io.read("*n")
local t = {}
local maps = {}
for i = 1, n do
  t[i] = 0
  local a = io.read("*n")
  maps[i] = {}
  for j = 1, a do
    local p, q = io.read("*n", "*n")
    maps[i][p] = q
  end
end

local function add_func(idx)
  t[idx] = 1
end
local function rm_func(idx)
  t[idx] = 0
end
local ret = 0
local function work_func()
  local valid = true
  local c = 0
  for i = 1, n do
    if t[i] == 1 then
      c = c + 1
      for k, v in pairs(maps[i]) do
        if t[k] ~= v then
          valid = false break
        end
      end
    end
    if not valid then break end
  end
  if valid then
    ret = mma(ret, c)
  end
end

grayWalk(n, add_func, rm_func, work_func)
print(ret)
