//{{{
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef vector<int> vi;
typedef pair<int, int> pii;
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define clr(a, b) memset(a, b, sizeof(a))
#ifdef LOCAL
#include "prettyprint.hpp"
#endif
// clang-format off
void _print() { cerr << "]\033[0m\n"; }
template <typename T> void __print(T x) { cerr << x; }
template <typename T, typename... V> void _print(T t, V... v) { __print(t); if (sizeof...(v)) cerr << ", "; _print(v...); }
#ifdef LOCAL
#define debug(x...) cerr << "\033[1;34m[" << #x << "] = \033[1;32m["; _print(x)
#define debug_arr(x...) cerr << "\033[1;34m[" << #x << "] = \033[1;32m" << (x) << "\033[0m\n"
#else
#define debug(x...)
#define debug_arr(x...)
#endif
// clang-format on
//}}}

const int N = 20;
const int mod = 1e9 + 7;

int n;
int a[N];

vector<pii> words[N];

bool is_h(int status, int idx) { return (status & (1 << idx)) > 0; }
bool check(int status)
{
    for (int i = 0; i < n; i++)
    {
        // check ith person
        bool is_honest = is_h(status, i);
        if (is_honest == false) continue;

        for (int j = 0; j < a[i]; j++)
        {
            int p = words[i][j].first;
            int val = words[i][j].second;

            bool is_p_h = is_h(status, p);
            if (is_p_h != val) return false;
        }
    }
    return true;
}

int main()
{
#ifdef LOCAL
    freopen("in", "r", stdin);
    // freopen("out", "w", stdout);
#endif

    while (cin >> n)
    {
        for (int i = 0; i < n; ++i)
        {
            words[i].clear();
            cin >> a[i];

            for (int j = 0; j < a[i]; ++j)
            {
                int x, y;
                cin >> x >> y;
                x--;
                words[i].push_back({x, y});
            }
        }

        int ans = -1;
        int lim = 1 << n;
        for (int st = 0; st < lim; st++)
        {
            // if (__builtin_popcount(st) <= ans) continue;

            // check
            if (check(st))
            {
                ans = max(ans, __builtin_popcount(st));
            }
        }

        // int v = __builtin_popcount(ans);
        cout << ans << endl;
    }

    return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define lint long long
#define inf 1000000007
#define mod 1000000007
#define MAX 100005
#define pb push_back
#define mp make_pair
#define vit vector<int>::iterator
typedef pair<int,int> pii;
vector<pii> V[MAX];
int pos[MAX],flg,visited[MAX];
void dfs(int u){
    visited[u]=1;
    for(auto v:V[u]){
        if(v.second){
            if(!pos[v.first]){
                pos[v.first]=1;
                dfs(v.first);
            }
            else if(pos[v.first]==1){
                if(!visited[v.first])
                    dfs(v.first);
            }
            else flg=1;
        }
        else{
            if(!pos[v.first]) pos[v.first]=2;
            else if(pos[v.first]==1) flg=1;
        }
    }
}
int possible(int k,int n){
    vector<int>vec;
    for(int i=0;i<(n-k);i++) vec.pb(0);
    for(int i=0;i<k;i++) vec.pb(1);
    do{
        flg=0;
        for(int i=1;i<=n;i++){
            visited[i]=0;
            pos[i]=vec[i-1];
        }
        for(int i=1;i<=n;i++){
            if(!visited[i] && vec[i-1]){
                dfs(i);
            }
        }
        if(!flg)
            return 1;

    }while(next_permutation(vec.begin(),vec.end()));
    return 0;
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n;
    cin>>n;

    for(int i=0;i<n;i++){
        int a;
        cin>>a;
        for(int j=0;j<a;j++){
            int x,y;
            cin>>x>>y;
            V[i+1].pb(mp(x,y));
        }
    }
    int lo,hi,mid;
    lo=0;
    hi=n;
    while(hi>lo){
        mid=(lo+hi+1)/2;
        if(possible(mid,n)) lo=mid;
        else hi=mid-1;
    }
    cout<<lo;
}
