from __future__ import print_function
# import numpy as np
# import numpypy as np
import sys
input = sys.stdin.readline

def eprint(*args, **kwargs):
    print(*args, file=sys.stderr, **kwargs)
    return

import math
import string
import fractions
from fractions import Fraction
from fractions import gcd

def lcm(n,m):
    return int(n*m/gcd(n,m))

import re
import array
import copy
import functools
import operator

import collections
import itertools
import bisect
import heapq


from heapq import heappush
from heapq import heappop
from heapq import heappushpop
from heapq import heapify
from heapq import heapreplace

from queue import PriorityQueue as pq

def reduce(p, q):
    common = fractions.gcd(p, q)
    return (p//common , q//common )
# from itertools import accumulate
# from collections import deque

from operator import mul
from functools import reduce

def combinations_count(n, r):
    r = min(r, n - r)
    numer = reduce(mul, range(n, n - r, -1), 1)
    denom = reduce(mul, range(1, r + 1), 1)
    return numer // denom

import random

def check(index_person, x_true_or_false, bin_str):
    return (bin_str[index_person] == x_true_or_false)


def main():
    n = int(input().strip())
    ll_xy = [[] for _ in range(n)]
    for i in range(n):
        a = int(input().strip())
        for j in range(a):
            l = list(map(int, input().strip().split()))
            l[0]-=1
            ll_xy[i].append(l)
    #eprint("ll_xy ",end=": ")
    #eprint(ll_xy)

    cnt=0
    ans=0
    for i in range(2 ** n):     # 場合ループ
        #eprint("i ",end=": ")
        #eprint(i,end=" and ")

        bin_str = format(i,'b').zfill(n)
        #eprint("bin_str ",end=": ")
        #eprint(bin_str)
        failure_flag=0
        for j in range(n):      # 人ループ
            if bin_str[j]=="1":   # その人を「真実の人」だと仮定している場合
                a=len(ll_xy[j])
                for k in range(a):  # 証言ループ
                    #eprint("証言ループ")
                    p=int(bin_str[ll_xy[j][k][0]])
                    if ll_xy[j][k][1] == 0:
                        if check(p,"0",bin_str):
                            pass
                        else:
                            failure_flag=1

                    elif ll_xy[j][k][1] == 1:
                        if check(p,"1",bin_str):
                            pass
                        else:
                            failure_flag=1
                    else:
                        try:
                            #eprint("error1")
                        except Exception:
                            #eprint("errorE")
        if failure_flag==0:
            cnt+=1
            ans_temp=0
            for x in bin_str:
                if x=="1":
                    ans_temp+=1
            ans=max(ans_temp,ans)
            # #eprint("success!")
    #eprint("cnt ",end=": ")
    #eprint(cnt)
    print(ans)
    return
if __name__ == '__main__':
    main()


### FIXED CODE ###

from __future__ import print_function
# import numpy as np
# import numpypy as np
import sys
input = sys.stdin.readline

def eprint(*args, **kwargs):
    print(*args, file=sys.stderr, **kwargs)
    return

import math
import string
import fractions
from fractions import Fraction
from fractions import gcd

def lcm(n,m):
    return int(n*m/gcd(n,m))

import re
import array
import copy
import functools
import operator

import collections
import itertools
import bisect
import heapq


from heapq import heappush
from heapq import heappop
from heapq import heappushpop
from heapq import heapify
from heapq import heapreplace

from queue import PriorityQueue as pq

def reduce(p, q):
    common = fractions.gcd(p, q)
    return (p//common , q//common )
# from itertools import accumulate
# from collections import deque

from operator import mul
from functools import reduce

def combinations_count(n, r):
    r = min(r, n - r)
    numer = reduce(mul, range(n, n - r, -1), 1)
    denom = reduce(mul, range(1, r + 1), 1)
    return numer // denom

import random

def check(index_person, x_true_or_false, bin_str):
    return (bin_str[index_person] == x_true_or_false)


def main():
    n = int(input().strip())
    ll_xy = [[] for _ in range(n)]
    for i in range(n):
        a = int(input().strip())
        for j in range(a):
            l = list(map(int, input().strip().split()))
            l[0]-=1
            ll_xy[i].append(l)

    cnt=0
    ans=0
    for i in range(2 ** n):     # 場合ループ
        bin_str = list(map(int,(format(i,'b').zfill(n))))
        # eprint("bin_str ",end=": ")
        # eprint(bin_str)
        failure_flag=0
        for j in range(n):      # 人ループ
            if bin_str[j]==1:   # その人を「真実の人」だと仮定している場合
                a=len(ll_xy[j])
                for k in range(a):  # 証言ループ
                    p=ll_xy[j][k][0]
                    if ll_xy[j][k][1] == 0:
                        if check(p,0,bin_str):
                            pass
                        else:
                            failure_flag=1

                    elif ll_xy[j][k][1] == 1:
                        if check(p,1,bin_str):
                            pass
                        else:
                            failure_flag=1
        if failure_flag==0:
            cnt+=1
            ans_temp=0
            for x in bin_str:
                if x==1:
                    ans_temp+=1
            ans=max(ans_temp,ans)
    print(ans)
    return

if __name__ == '__main__':
    main()