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

using lint = long long int;

class UnionFind {
private:
	vector< int > data;
	
public:
	UnionFind() {}
	UnionFind(int n) : data(n, -1) {}
	
	bool unionSet(int x, int y) {
		x = root(x); y = root(y);
		
		if (x == y) return 0;
		
		if (data[y] < data[x]) swap(x, y);
		data[x] += data[y]; data[y] = x;
		return 1;
	}
	
	bool sameSet(int x, int y) { return root(x) == root(y); }
	int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
	int size(int x) { return -data[root(x)]; }
};

int N;
vector< set< int > > X;
UnionFind uf;

void solve() {
	vector< int > max_start(N, -1);
	for (int i=0; i<N; ++i) for (int x : X[i]) if (uf.sameSet(x, i)) max_start[i] = max(max_start[i], x);
	
	/*
	for (int i=0; i<N; ++i) cerr << max_start[i] << " ";
	cerr << endl;
	*/
	
	int ans = 0, cur = -1;
	for (int i=0; i<N; ++i) {
		if (max_start[i] >= 0 && cur < max_start[i]) {
			cur = i;
			++ans;
		}
	}
	cout << ans << endl;
}

int main() {
	cin >> N;
	
	X.assign(N, set< int >());	
	uf = UnionFind(N);
	
	for (int i=0; i<N; ++i) {
		int M;
		cin >> M;
		
		for (int j=0; j<M; ++j) {
			int x;
			cin >> x;
			--x;
			if (x == i+1) uf.unionSet(i,i+1);
			else X[i].insert(x);
		}
	}
	
	solve();
}
