// https://atcoder.jp/contests/past-sample/tasks/abc129_d

// config 

const int __SETW__ = 6;

// IO
#include <iostream>      // cin, cout
#include <iomanip>       // setw
// MATH & ALGROTHM
#include <cmath>
#include <complex>
#include <numeric>
#include <algorithm>
// CONTAINER 
#include <tuple>
#include <string>      
#include <vector>
#include <deque>
#include <queue>  
#include <stack>
#include <map>       
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <list>
// FUNCTION
#include <functional>
// META
#include <type_traits>
 
/////// 
using std::cin;
using std::cout;
using std::endl;

using INT = long long int;
const INT INF = INT(1) << 60;

#define FOR(i, N) for( INT i = 0; i < N; i++ )
#define RANGE(v) begin(v), end(v)

using VEC = std::vector<INT>;
using VECVEC = std::vector<VEC>;

template< class T >
T safe_get ( const std::vector<T>& v, INT idx, T def = -1 ){
    if( idx < 0 || v.size() <= idx ){
        return def;
    } else {
        return v[idx];
    }
}
template< class T >
T safe_get ( const std::vector< std::vector<T> >& vv, INT idx1, INT idx2, T def = -1 ){
    if( idx1 < 0 || vv.size() <= idx1 ){
        return def;
    } else {
        return safe_get(vv[idx1], idx2, def );
    }
}

template< class T, class F >
inline bool ANY( T sequence, F func ){
    for(  auto&& t : sequence ){
        if( func(t) ){ return true; }
    }
    return false;
}
template< class T, class F >
inline bool ALL( T sequence, F func ){
    for(  auto&& t : sequence ){
        if( ! func(t) ){ return false; }
    }
    return true;
}

template< class T >
std::ostream& operator<< ( std::ostream& lhs, const std::priority_queue<T>& rhs ){
    std::queue<T> copy = rhs;
    while( !copy.empty() ){
        lhs << std::setw(__SETW__) << copy.front() << " ";
        copy.pop();
    }
    return lhs;
}
template< class T >
std::ostream& operator<< ( std::ostream& lhs, const std::queue<T>& rhs ){
    std::queue<T> copy = rhs;
    while( !copy.empty() ){
        lhs << std::setw(__SETW__) << copy.front() << " ";
        copy.pop();
    }
    return lhs;
}
template< class T >
std::ostream& operator<< ( std::ostream& lhs, const std::stack<T>& rhs ){
    std::stack<T> copy = rhs;
    while( !copy.empty() ){
        lhs << std::setw(__SETW__) << copy.top() << " ";
        copy.pop();
    }
    return lhs;
}

template< class T >
std::ostream& operator<< ( std::ostream& lhs, const std::vector< std::vector<T> >& rhs ){
    for( auto&& v : rhs ){
        lhs << v << endl;
    }
    return lhs;
}
template< class T >
std::ostream& operator<< ( std::ostream& lhs, const std::vector<T>& rhs ){
    for( auto&& t : rhs ){
        lhs << std::setw(__SETW__) << t << " ";
    }
    return lhs;
}
template< class T >
std::ostream& operator<< ( std::ostream& lhs, const std::list<T>& rhs ){
    for( auto&& t : rhs ){
        lhs << std::setw(__SETW__) << t << " ";
    }
    return lhs;
}

template< class T1, class T2 >
std::ostream& operator<< ( std::ostream& lhs, const std::map<T1, T2>& rhs ){
    for( auto&& m : rhs ){
        lhs << std::setw(__SETW__) << m.first << ":" << std::setw(__SETW__) << m.second << endl;
    }
    return lhs;
}
template< class T1, class T2 >
std::ostream& operator<< ( std::ostream& lhs, const std::multimap<T1, T2>& rhs ){
    for( auto&& m : rhs ){
        lhs << std::setw(__SETW__) << m.first << ":" << std::setw(__SETW__) << m.second << endl;
    }
    return lhs;
}
template< class T >
std::ostream& operator<< ( std::ostream& lhs, const std::set<T>& rhs ){
    for( auto&& t : rhs ){
        lhs << std::setw(__SETW__) << t << " ";
    }
    return lhs;
}
template< class T >
std::ostream& operator<< ( std::ostream& lhs, const std::multiset<T>& rhs ){
    for( auto&& t : rhs ){
        lhs << std::setw(__SETW__) << t << " ";
    }
    return lhs;
}

template< class T >
std::ostream& operator<< ( std::ostream& lhs, const std::complex<T>& rhs ){
    std::streamsize ss = lhs.precision();
    lhs << "(" << std::setw(5) << std::setprecision(4) << rhs.real() << ","
               << std::setw(5) << std::setprecision(4) << rhs.imag() << ") ";
    lhs.precision(ss);
    return lhs;
}
template< class T1, class T2 >
std::ostream& operator<< ( std::ostream& lhs, const std::pair<T1, T2>& rhs ){
    lhs << "(" << rhs.first << "," << rhs.second << ")";
    return lhs;
}


template<class T>
struct conbination_generator{
    std::vector<T> vec;
    unsigned int n;
    std::vector<unsigned int> idxs;
    bool isFinished;

    conbination_generator( const std::vector<T>& vec, unsigned int n )
    : vec(vec), n(n), idxs(n), isFinished(false)
    { 
        for( unsigned int i = 0; i < n; i++){
            idxs[i] = i;
        }
    }

    std::vector<T> get_combination(void) const {
        std::vector<T> ret(n);
        for( unsigned int i = 0; i < n; i++){
            ret[i] = vec[idxs[i]];
        }
        return ret;
    }
    std::vector<T> operator* (void) const {
        return get_combination();
    }

    operator bool() const {
        return ! isFinished;
    }

    conbination_generator<T>& operator++ (void){
        unsigned int N = vec.size();
        unsigned int i = 1; // 1 -> n //
        
        while(true) {
            idxs[n-i]++;
            for( unsigned int j = 1; j < i; j++ ){
                idxs[n-i+j] = idxs[n-i] + j;
            }
            if( idxs[n-i] > N-i ){
                i++;
                if( i > n ){
                    isFinished = true;
                    return *this;
                }
            } else {
                break;
            }
        }
        return *this;
    }
    
    conbination_generator<T>& operator++ (int){
        return ++(*this);
    }
};

int main(){
    INT N;
    cin >> N;

    VEC honest(N, 0);
    VEC unkind(N, 0);

    FOR(i, N){
        INT A;
        cin >> A;
        FOR(j, A) {
            INT x, y;
            cin >> x >> y;
            x -= 1;
            if( y == 1){
                honest[i] |= (1 << x);
            } else {
                unkind[i] |= (1 << x);
            }
            // 自分は無条件で信じる
            honest[i] |= (1 << i);
        }
    }

    // cout << honest << endl;
    // cout << unkind << endl;

    FOR(i, N){
        FOR(j, N){
            FOR(_, N){
                if( honest[i] & (1<<j) ){
                    honest[i] |= honest[j];
                    unkind[i] |= unkind[j];
                }
            }
        }
    }
    
    // cout << honest << endl;
    // cout << unkind << endl;

    std::vector<INT> tmp(N);
    FOR(i, N) tmp[i] = i;

    for( INT i = N; i >= 1; i-- ){
        conbination_generator<INT> comb( tmp, i );
        do {
            std::vector<INT> idxs = *comb;
            INT h = 0, u = 0, h2 = 0, u2 = 0;
            for( auto idx : idxs ){
                h |= honest[idx];
                h2 |= ( 1 << idx );
                u |= unkind[idx];
            }
            if(  h2 & u || (h & h2) != h ){
                // NOP //
                // 矛盾あり
            } else {
                cout << i << endl;
                return 0;
            }

            comb++;
        } while( comb );
    }

    cout << 0 << endl;
    

    return 0;
}


Measured memory_bytes: 256