Problem: Problem

You were asked by a company to create a program. The company has $ N $ jobs, and each job is numbered from $ 1 $ to $ N $. There are $ M_i $ prerequisite jobs $ X_ {i, j} $ in job $ i $, and work $ X_ {i, j} $ is performed before job $ X_ {i, j} $. And work $ i $ suffers a great loss.

So ask you to find the number of jobs you lost when you did all the jobs in the order that minimized the number of jobs you lost.

Constraints

The input satisfies the following conditions.

* $ 1 \ le N \ le 10 ^ 5 $
* $ 0 \ le M_i \ le N $
* Sum of $ M_i $ does not exceed $ 10 ^ 5 $
* $ 1 \ le X_ {i, j} \ le min (i + 1, N) $

Input

All inputs are given as integers in the following format:


$ N $
$ M_1 $ $ X_ {1,1} $ $ X_ {1,2} $ ... $ X_ {1, M_1} $
$ M_2 $ $ X_ {2,1} $ $ X_ {2,2} $ ... $ X_ {2, M_2} ​​$
::
$ M_N $ $ X_ {N, 1} $ $ X_ {N, 2} $ ... $ X_ {N, M_N} $


The number of jobs $ N $ is given to the $ 1 $ line.
The following $ N $ line gives information on the prerequisite work. Information on work $ i $ is given on the $ i + 1 $ line, separated by blanks. $ M_i $ represents the number of jobs that are the premise of work $ i $, and $ X_ {i, j} $ is the number of jobs that are the premise of job $ i $.

Output

When all the jobs are done in the order that minimizes the number of jobs incurred, the number of jobs incurred at that time is output in one line.

Examples

Input

2
1 1
0


Output

1


Input

3
3 2 1 2
0
1 2


Output

1


Input

5
1 2
1 3
2 1 2
3 1 3 5
0


Output

1

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
#define MOD 1000000007LL
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

class segtree{
public:
	static const int N=1<<18;
	int dp[1<<19];
	int lazy[1<<19];
	segtree(){
		memset(dp,0,sizeof(dp));
		for(int i=0;i<N*2;i++){
			dp[i]=11451419;
			lazy[i]=11451419;
		}
	}

	void lazy_eval(int k){
		dp[k]=min(dp[k],lazy[k]);
		if(k<N-1){
			lazy[k*2+1]=min(lazy[k*2+1],lazy[k]);
			lazy[k*2+2]=min(lazy[k*2+2],lazy[k]);
		}
	}

	void lazy_upd(int k){
		dp[k]=min(dp[k*2+1],dp[k*2+2]);
	}
	void update(int a,int b,int v,int k=0,int l=0,int r=N){
		lazy_eval(k);
		if(b<=l || r<=a)return;
		if(a<=l && r<=b){
			lazy[k]=min(lazy[k],v);
			lazy_eval(k);
			return;
		}
		int mid=(l+r)/2;
		update(a,b,v,k*2+1,l,mid);
		update(a,b,v,k*2+2,mid,r);
		lazy_upd(k);
	}

	int query(int a,int b,int k=0,int l=0,int r=N){
		lazy_eval(k);
		if(b<=l || r<=a)return 11451419;
		if(a<=l && r<=b)return dp[k];
		int mid=(l+r)/2;
		int vl=query(a,b,k*2+1,l,mid);
		int vr=query(a,b,k*2+2,mid,r);
		lazy_upd(k);
		return min(vl,vr);
	}
};

int n;
set<int> g[100005];
set<int> gg[100005];
segtree seg;
bool self[100005];

int main(void){
	scanf("%d",&n);
	int selfc=0;
	int pr=0;
	for(int i=0;i<n;i++){
		int m;
		scanf("%d",&m);
		bool flag=false;
		for(int j=0;j<m;j++){
			int x;
			scanf("%d",&x);
			x--;
			if(x==i){
				self[i]=true;
				g[i].insert(x);
			}else if(x==i+1){
				flag=true;
			}else if(x>=pr && !self[i]){
				g[i].insert(x);
			}
		}
		if(!flag){
			pr=i+1;
		}
	}
	for(int i=0;i<n;i++){
		for(set<int>::iterator it=g[i].begin();it!=g[i].end();it++){
			int v=*it;
			gg[v].insert(i);
		}
	}
	int mini_m=11451419;
	for(int i=n-1;i>=0;i--){
		for(set<int>::iterator it=gg[i].begin();it!=gg[i].end();it++){
			int v=*it;
			mini_m=min(v,mini_m);
		}
		if(*(gg[i].begin())>mini_m){
			gg[i].insert(mini_m);
		}
	}
	seg.update(0,1,0);
	int prv=0;
	int cnt=0;
	for(int i=0;i<n;i++){
		if(gg[i].size()==0)continue;
		int v=seg.query(prv,prv+1);
		int nxt=*(gg[i].begin());
		//printf("%d %d %d\n",i,nxt,v);
		seg.update(i+1,nxt+2,v+1);
		prv=i+1;
	}
	printf("%d\n",seg.query(prv,prv+1));
	return 0;
}