/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author aryssoncf
 */

#include <bits/stdc++.h>
//
// Created by aryssoncf on 28/10/2019.
//

#include <type_traits>


#include <iterator>
#include <utility>

template<typename T>
constexpr auto hasBegin(int) -> decltype(std::begin(std::declval<T>()), true) {
    return true;
}

constexpr bool hasBegin(...) {
    return false;
}

template<typename T>
using IsContainer = std::integral_constant<bool, hasBegin<T>(0)>;


#ifndef JHELPER_EXAMPLE_PROJECT_IO_HPP
#define JHELPER_EXAMPLE_PROJECT_IO_HPP

#endif //JHELPER_EXAMPLE_PROJECT_IO_HPP

template<class X, class Y>
std::ostream &operator<<(std::ostream &os, std::pair<X, Y> const &p) {
    return os << p.first << " " << p.second;
}

template<class Ch, class Tr, class Container>
std::basic_ostream<Ch, Tr> &operator<<(std::basic_ostream<Ch, Tr> &os, Container const &x) {
    bool first = true;
    for (auto &y : x) {
        if (first) {
            first = false;
        } else {
            os << " ";
        }
        os << y;
    }
    return os;
}

using namespace std;

class CHonestOrUnkind2 {
    vector<vector<int>> X, Y;
    vector<int> type;
    queue<int> honest;

    bool valid(int mask) {
        fill(type.begin(), type.end(), 0);
        int n = type.size();
        while (not honest.empty()) {
            honest.pop();
        }
        for (int i = 0; i < n; ++i) {
            if (mask & (1 << i)) {
                type[i] = 1;
                honest.push(i);
            }
        }
        while (not honest.empty()) {
            int u = honest.front();
            honest.pop();
            for (int i = 0; i < X[u].size(); ++i) {
                int x = X[u][i];
                if (Y[u][i]) {
                    if (type[x] == -1) {
                        return false;
                    }
                    if (type[x] == 0) {
                        type[x] = 1;
                        honest.push(x);
                    }
                } else {
                    if (type[x] == 1) {
                        return false;
                    }
                    type[x] = -1;
                }
            }
        }
        return true;
    }

public:
    void solve(std::istream &in, std::ostream &out) {
        int n;
        in >> n;
        X.resize(n);
        Y.resize(n);
        for (int u = 0; u < n; ++u) {
            int m;
            in >> m;
            X[u].resize(m);
            Y[u].resize(m);
            for (int i = 0; i < m; ++i) {
                in >> X[u][i] >> Y[u][i];
                --X[u][i];
            }
        }
        type.resize(n);
        int res = -1;
        for (int mask = 0; mask < (1 << n); ++mask) {
            if (valid(mask)) {
                res = max(res, __builtin_popcount(mask));
            }
        }
        out << res << "\n";
    }

    static void setup() {}
};


int main() {
    std::ios_base::sync_with_stdio(false);
    CHonestOrUnkind2 solver;
    solver.setup();
    std::istream &in(std::cin);
    std::ostream &out(std::cout);
    in.tie(nullptr);
    out << std::fixed;
    out.precision(20);
    solver.solve(in, out);
    return 0;
}


Measured memory_bytes: 256