n = int(eval(input()))

g = [[-1] * n for _ in range(n)]  # Graph for testimonies.

for i in range(n):

    m = int(eval(input()))

    for _ in range(m):

        x, y = [int(z) for z in input().split()]

        x -= 1  # Zero-indexed.

        g[i][x] = y  # Person i says that person x is honest or not.



ans = set()

for bb in range(2 ** n):

    tmp = [0] * n

    possible = True

    for shift in range(n):

        if bb >> shift & 1:

            tmp[shift] = 1  # Assumes person i is honest or not.

    for i, j in enumerate(tmp):

        if j:  # Assumed honest.

            for k in range(n):

                if g[i][k] == -1:

                    # No testimony.

                    continue

                if g[i][k] != tmp[k]:

                    # Contradiction!

                    possible = False

    if possible:

        ans.add(bin(bb).count('1'))



print((max(ans)))

def main():

    n = int(eval(input()))

    ttn = [[-1] * n for _ in range(n)]  # Testimonies.

    for i in range(n):

        a = int(eval(input()))

        for j in range(a):

            x, y = [int(z) for z in input().split()]

            x -= 1

            ttn[i][x] = y  # i says that x is honest guy or not.

    ans = set()

    # for else で頑張ったが，フラグを作ったほうがずっと分かりやすいだろう。

    for i in range(2 ** n):

        tmp = [i >> j & 1 for j in range(n)]  # Bit-shift.

        for k, tm in enumerate(tmp):

            if tm:

                for l, tt in enumerate(ttn[k]):

                    if tt == -1:

                        continue

                    if tt != tmp[l]:

                        break

                else:

                    continue

                break

        else:

            ans.add(bin(i).count('1'))

    return max(ans)





if __name__ == '__main__':

    print((main()))

n = int(eval(input()))
g = [[-1] * n for _ in range(n)]  # Graph for testimonies.
for i in range(n):
    m = int(eval(input()))
    for _ in range(m):
        x, y = [int(z) for z in input().split()]
        x -= 1  # Zero-indexed.
        g[i][x] = y  # Person i says that person x is honest or not.
ans = set()
for bb in range(2**n):
    tmp = [0] * n
    possible = True
    for shift in range(n):
        if bb >> shift & 1:
            tmp[shift] = 1  # Assumes person i is honest or not.
    for i, j in enumerate(tmp):
        if j:  # Assumed honest.
            for k in range(n):
                if g[i][k] == -1:
                    # No testimony.
                    continue
                if g[i][k] != tmp[k]:
                    # Contradiction!
                    possible = False
    if possible:
        ans.add(bin(bb).count("1"))
print((max(ans)))

def main():
    n = int(eval(input()))
    ttn = [[-1] * n for _ in range(n)]  # Testimonies.
    for i in range(n):
        a = int(eval(input()))
        for j in range(a):
            x, y = [int(z) for z in input().split()]
            x -= 1
            ttn[i][x] = y  # i says that x is honest guy or not.
    ans = set()
    # for else で頑張ったが，フラグを作ったほうがずっと分かりやすいだろう。
    for i in range(2**n):
        tmp = [i >> j & 1 for j in range(n)]  # Bit-shift.
        for k, tm in enumerate(tmp):
            if tm:
                for l, tt in enumerate(ttn[k]):
                    if tt == -1:
                        continue
                    if tt != tmp[l]:
                        break
                else:
                    continue
                break
        else:
            ans.add(bin(i).count("1"))
    return max(ans)


if __name__ == "__main__":
    print((main()))

-n = int(eval(input())) -g = [[-1] * n for _ in range(n)]  # Graph for testimonies. -for i in range(n): -    m = int(eval(input())) -    for _ in range(m): -        x, y = [int(z) for z in input().split()] -        x -= 1  # Zero-indexed. -        g[i][x] = y  # Person i says that person x is honest or not. -ans = set() -for bb in range(2**n): -    tmp = [0] * n -    possible = True -    for shift in range(n): -        if bb >> shift & 1: -            tmp[shift] = 1  # Assumes person i is honest or not. -    for i, j in enumerate(tmp): -        if j:  # Assumed honest. -            for k in range(n): -                if g[i][k] == -1: -                    # No testimony. +def main(): +    n = int(eval(input())) +    ttn = [[-1] * n for _ in range(n)]  # Testimonies. +    for i in range(n): +        a = int(eval(input())) +        for j in range(a): +            x, y = [int(z) for z in input().split()] +            x -= 1 +            ttn[i][x] = y  # i says that x is honest guy or not. +    ans = set() +    # for else で頑張ったが，フラグを作ったほうがずっと分かりやすいだろう。 +    for i in range(2**n): +        tmp = [i >> j & 1 for j in range(n)]  # Bit-shift. +        for k, tm in enumerate(tmp): +            if tm: +                for l, tt in enumerate(ttn[k]): +                    if tt == -1: +                        continue +                    if tt != tmp[l]: +                        break +                else: -                if g[i][k] != tmp[k]: -                    # Contradiction! -                    possible = False -    if possible: -        ans.add(bin(bb).count("1")) -print((max(ans))) +                break +        else: +            ans.add(bin(i).count("1")) +    return max(ans) + + +if __name__ == "__main__": +    print((main()))