#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define ld long double
#define ar array

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

template <typename T> using oset = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define vt vector
#define pb push_back
#define all(c) (c).begin(), (c).end()
#define sz(x) (int)(x).size()

#define F_OR(i, a, b, s) for (int i=(a); (s)>0?i<(b):i>(b); i+=(s))
#define F_OR1(e) F_OR(i, 0, e, 1)
#define F_OR2(i, e) F_OR(i, 0, e, 1)
#define F_OR3(i, b, e) F_OR(i, b, e, 1)
#define F_OR4(i, b, e, s) F_OR(i, b, e, s)
#define GET5(a, b, c, d, e, ...) e
#define F_ORC(...) GET5(__VA_ARGS__, F_OR4, F_OR3, F_OR2, F_OR1)
#define FOR(...) F_ORC(__VA_ARGS__)(__VA_ARGS__)
#define EACH(x, a) for (auto& x: a)

template<class A> void read(vt<A>& v);
template<class A, size_t S> void read(ar<A, S>& a);
template<class T> void read(T& x) {
	cin >> x;
}
void read(double& d) {
	string t;
	read(t);
	d=stod(t);
}
void read(long double& d) {
	string t;
	read(t);
	d=stold(t);
}
template<class H, class... T> void read(H& h, T&... t) {
	read(h);
	read(t...);
}
template<class A> void read(vt<A>& x) {
	EACH(a, x)
		read(a);
}
template<class A, size_t S> void read(array<A, S>& x) {
	EACH(a, x)
		read(a);
}

string to_string(char c) {
	return string(1, c);
}
string to_string(bool b) {
	return b?"true":"false";
}
string to_string(const char* s) {
	return string(s);
}
string to_string(string s) {
	return s;
}
string to_string(vt<bool> v) {
	string res;
	FOR(sz(v))
		res+=char('0'+v[i]);
	return res;
}

template<size_t S> string to_string(bitset<S> b) {
	string res;
	FOR(S)
		res+=char('0'+b[i]);
	return res;
}
template<class T> string to_string(T v) {
    bool f=1;
    string res;
    EACH(x, v) {
		if(!f)
			res+=' ';
		f=0;
		res+=to_string(x);
	}
    return res;
}

template<class A> void write(A x) {
	cout << to_string(x);
}
template<class H, class... T> void write(const H& h, const T&... t) { 
	write(h);
	write(t...);
}
void print() {
	write("\n");
}
template<class H, class... T> void print(const H& h, const T&... t) { 
	write(h);
	if(sizeof...(t))
		write(' ');
	print(t...);
}

void DBG() {
	cerr << "]" << endl;
}
template<class H, class... T> void DBG(H h, T... t) {
	cerr << to_string(h);
	if(sizeof...(t))
		cerr << ", ";
	DBG(t...);
}
#ifdef _DEBUG
#define dbg(...) cerr << "LINE(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "]: [", DBG(__VA_ARGS__)
#else
#define dbg(...) 0
#endif

template<class T> void offset(ll o, T& x) {
	x+=o;
}
template<class T> void offset(ll o, vt<T>& x) {
	EACH(a, x)
		offset(o, a);
}
template<class T, size_t S> void offset(ll o, ar<T, S>& x) {
	EACH(a, x)
		offset(o, a);
}

mt19937 mt_rng(chrono::steady_clock::now().time_since_epoch().count());
ll randint(ll a, ll b) {
	return uniform_int_distribution<ll>(a, b)(mt_rng);
}
const int d4i[4]={-1, 0, 1, 0}, d4j[4]={0, 1, 0, -1};
const int d8i[8]={-1, -1, 0, 1, 1, 1, 0, -1}, d8j[8]={0, 1, 1, 1, 0, -1, -1, -1};

template<class T> T modpow(T a, T b,ll mod){
T res=1; a%=mod;
while(b){
if(b&1){ res=(res*a)%mod;}
a=(a*a)%mod;
b>>=1; 
}
return res;
}
#define lcm(a,b) ((a)*(b))/(__gcd(a,b))

ll mod=1e9+7;
const int N=20;
const ld PI=2*acos(0.0); 
vt<int> v(N,0); 
vt<int> g(N,0); 
int n; 
void solve() {
ll mx=0;
read(n); 
FOR(n){ int c; read(c); g[i]=(1<<i);  FOR(j,c){ int a,b; read(a,b); if(!b){v[i]|=(1<<(a-1)); } else{ g[i]|=(1<<(a-1)); } } }
FOR(i,1,1<<n){
int tmp1=0,tmp2=0; 
FOR(j,n){
if(i&(1<<j))  { tmp1|=g[j]; tmp2|=v[j]; }
}
if(tmp1==i&&(!(tmp1&tmp2)))mx=max(mx,(ll)__builtin_popcount(i)); 
}  
print(mx); 
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	solve();
}

#include<bits/stdc++.h>
#define rep(i,n) for(int i=0; i<(n); ++i)
#define rep2(i,n) for(int i=1; i<=(n); ++i)
#define all(x) (x).begin(),(x).end()
#define sort_u(x) sort((x).begin(),(x).end())
#define sort_d(x) sort((x).begin(),(x).end(), greater<int>())
#define pb push_back
#define INF ((1LL<<62)-(1LL<<31))  // 浮動小数点型
#define bit(n,m)(((n)>>(m))&1)  // nのmビット目が1
#define MOD 1000000007
using namespace std;
using ll = long long;
using P = pair<int,int>;
using Graph = vector<vector<P>>;

int main() {
    int n; cin >> n;
    Graph p(n);
    rep(i,n){
        int a; cin >> a;
        rep(j, a){
            int x, y; cin >> x >> y;
            x--;
            p[i].pb(P(x,y));
        }
    }
    int ans = 0;
    rep(s, 1<<n){
        vector<int> flg(n, -1);
        bool flg2 = false;
        int a = 0;
        rep(i,n){
            if(bit(s,i)){
                if(flg[i] == -1) flg[i] = 1;
                if(flg[i] != 1) {
                    flg2 = true;
                    break;
                }
                a++;
                for(auto q : p[i]){
                    if(flg[q.first] == -1) flg[q.first] = q.second;
                    if(flg[q.first] != q.second){
                        flg2 = true;
                        break;
                    }
                }
            }else{
                if(flg[i] == -1) flg[i] = 0;
                if(flg[i] != 0) {
                    flg2 = true;
                    break;
                }
                // for(auto q : p[i]){
                //     int q2 = 1;
                //     if(q.second == 1) q2 = 0;
                //     if(flg[q.first] == -1) flg[q.first] = q2;
                //     if(flg[q.first] == q.second){
                //         flg2 = true;
                //         break;
                //     }
                // }
            }
            if(flg2) break;
        }
        if(!flg2) ans = max(a,ans);
    }
    cout << ans << endl;
    
}

/*
g++ c.cpp
./a.out


oj d
g++ c.cpp
oj t
*/
