var N = 0;
var humans = [];

function parse(stdin){
    var lines = stdin.split("\n");
    for(i = 0; i < lines.length; i++){
        var line = lines[i];
        if (i === 0) N = parseInt(line);
        else {
            var input = line.split(" ");
            if (input.length === 1) humans.push([]);
            else humans[humans.length - 1].push(input.map(x => parseInt(x)))
        }
    }
}

function main() {
    var patterns = Math.pow(2, N);

    for (i = patterns - 1; i >= 0; i--) {

        // 正直者の組み合わせを仮定
        var honests = (('000' + i.toString(2)).slice(-3)).split('').map(x => parseInt(x));

        // 仮定が矛盾したか否か
        var isCont = false;

        for (j = 0; j < humans.length; j++) {
            // 嘘つきの証言は無視
            if (honests[j] === 0) continue;

            // 正直者の証言をチェック
            var words = humans[j];
            for (k = 0; k < words.length; k++) {
                var word = words[k];
                var isHonest = honests[word[0] - 1]
                // 仮定と矛盾したらbreak
                if (isHonest !== word[1]) {
                    isCont = true;
                    break;
                }
            }
        }
        // breakしなかったら矛盾してないので最大数
        if (!isCont) {
            return honests.reduce((acc, val) => acc += val, 0);
        }
    }

    return 0;
}

parse(require("fs").readFileSync("/dev/stdin", "utf8"));
console.log(main());