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

typedef long long int ll; 
#define MOD 1000000007
#define ON 200000
#define rep(i,n) fp(i,0,n)  
#define fp(i,a,b) for(ll i=(a);i<(b);++i)
#define fn(i,a,b) for(ll i=(a);i>(b);i--)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define FF first
#define SS second
typedef pair<ll, ll> pll; 
typedef vector<pll> vpll;
typedef vector<ll> vll;
#define rs(t) string t;cin>>t
#define ri(t) int t;cin>>t
#define rll(t) long long int t;cin>>t
#define MK make_pair
#define PB push_back
#define PO pop_back
template<typename T> istream &operator>>(istream &is, vector<T> &vec){ for (auto &v : vec) is >> v; return is; }
///// This part below is only for debug, not used /////
template<typename T> ostream &operator<<(ostream &os, const vector<T> &vec){ os << "["; for (auto v : vec) os << v << ","; os << "]"; return os; }
template<typename T> ostream &operator<<(ostream &os, const deque<T> &vec){ os << "deq["; for (auto v : vec) os << v << ","; os << "]"; return os; }
template<typename T> ostream &operator<<(ostream &os, const set<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template<typename T> ostream &operator<<(ostream &os, const unordered_set<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template<typename T> ostream &operator<<(ostream &os, const multiset<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template<typename T> ostream &operator<<(ostream &os, const unordered_multiset<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template<typename T1, typename T2> ostream &operator<<(ostream &os, const pair<T1, T2> &pa){ os << "(" << pa.first << "," << pa.second << ")"; return os; }
template<typename TK, typename TV> ostream &operator<<(ostream &os, const map<TK, TV> &mp){ os << "{"; for (auto v : mp) os << v.first << "=>" << v.second << ","; os << "}"; return os; }
template<typename TK, typename TV> ostream &operator<<(ostream &os, const unordered_map<TK, TV> &mp){ os << "{"; for (auto v : mp) os << v.first << "=>" << v.second << ","; os << "}"; return os; }
#define dbg(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ") " << __FILE__ << endl;
///// END /////

struct subset 
{ 
    ll parent; 
    ll rank; 
};

ll find(struct subset subsets[], ll i) 
{ 
    if (subsets[i].parent != i) 
        subsets[i].parent = find(subsets, subsets[i].parent); 
  
    return subsets[i].parent; 
} 
  
void Union(struct subset subsets[], ll x, ll y) 
{ 
    ll xroot = find(subsets, x); 
    ll yroot = find(subsets, y); 
  
   
    if (subsets[xroot].rank < subsets[yroot].rank) 
        subsets[xroot].parent = yroot; 
    else if (subsets[xroot].rank > subsets[yroot].rank) 
        subsets[yroot].parent = xroot;  
    else
    { 
        subsets[yroot].parent = xroot; 
        subsets[xroot].rank++; 
    } 
} 

ll ans = 0; 


void recur(vector <vpll> &v2, vll v, ll i,ll n, ll h){
	// cout << i << h << endl;
	
	if(i>n){
		ans = max(ans,h);
		return;
	}
	if(v[i]==0){
		recur(v2,v,i+1,n,h);
		return;		
	}
	if(v[i]==-1){
		
		v[i]=0;
		recur(v2,v,i+1,n,h);
		v[i]=-1;	
	}

	for(int j=0;j<v2[i].size();j++){
		if(v[v2[i][j].FF]==-1){
			v[v2[i][j].FF] = v2[i][j].SS; 
		}
		else if(v[v2[i][j].FF]!=v2[i][j].SS){
			return;
		}
	}
	v[i] = 1;
	// cout << i << h << endl;
	recur(v2,v,i+1,n,h+1);		
	
}

int main(){
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  rll(n);
  vll v(n+1,-1);

  vector <vpll> v2(n+1);	
  for(int i =1;i<=n;i++){
  	rll(a);
  	vpll tv(a);
  	rep(i,a){
  		cin >> tv[i].FF >> tv[i].SS;
  	}
  	v2[i] = tv;
  }


  recur(v2,v,1,n,0);
  cout << ans << endl;  
  
  return 0;
  
}

Measured memory_bytes: 256