Problem:
Problem H: Loss
Problem
あなたは、とある会社からプログラムの作成を依頼された。
  その会社には$N$個の仕事があり、それぞれの仕事には$1$から$N$までの番号が振られている。
  仕事$i$には、$M_i$個の前提となる仕事$X_{i,j}$が存在し、仕事$i$を前提となる仕事$X_{i,j}$よりも先に行うと、仕事$i$は多大な損失を被る。
そこであなたには、損失を被る仕事の数が最小となるような順番ですべての仕事を行ったときの損失を被った仕事の数を求めてもらいたい。
Input
入力は以下の形式ですべて整数で与えられる。
$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}$
仕事の数$N$が$1$行に与えられる。
続く$N$行に前提となる仕事の情報が与えられる。$i+1$行目には仕事$i$の情報が空白区切りで与えられる。$M_i$は、仕事$i$の前提となる仕事の数、$X_{i,j}$は仕事$i$の前提となる仕事の番号を表している。
Constraints
入力は以下の条件を満たす。
$1 \le N \le 10^5$
$0 \le M_i \le N$
$M_i$の総和は$10^5$を超えない
$1 \le X_{i,j} \le min(i+1,N)$
Output
損失を被る仕事の数が最小になるような順番ですべての仕事を行ったとき、そのときの損失を被った仕事の数を一行に出力する。
Sample Input 1
2
1 1
0
Sample Output 1
1
仕事$1$のように前提となる仕事がその仕事自身となるような入力も存在する。
Sample Input 2
3
3 2 1 2
0
1 2
Sample Output 2
1
Sample Input 3
5
1 2
1 3
2 1 2
3 1 3 5
0
Sample Output 3
1
例えば、$3,2,1,5,4$の順に仕事を行うと損失を最小化できる。

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 100005



struct GROUP{
	vector<int> nodes;
};

GROUP group[NUM]; //強連結成分のグループ
int N;
vector<int> G[NUM];
vector<int> reverse_G[NUM];
stack<int> S;
map<pair<int,int>,bool> MAP;

bool check[NUM],SELF[NUM];
int table[NUM],work[NUM];
double sleep[NUM];

int group_index;

void dfs(int node_id){
	check[node_id] = true;

	for(int i = 0; i < G[node_id].size(); i++){
		if(!check[G[node_id][i]])dfs(G[node_id][i]);
	}
	S.push(node_id);
}

void reverse_dfs(int node_id){
	check[node_id] = true;

	table[node_id] = group_index;
	group[group_index].nodes.push_back(node_id); //group[group_index]にノードを突っ込む

	for(int i = 0; i < reverse_G[node_id].size(); i++){
		if(!check[reverse_G[node_id][i]])reverse_dfs(reverse_G[node_id][i]);
	}
}


int main(){

	scanf("%d",&N);

	int num,pre_node;

	for(int i = 0; i < N; i++){

		SELF[i] = false;

		scanf("%d",&num);

		for(int k = 0; k < num; k++){
			scanf("%d",&pre_node);
			pre_node--;

			if(pre_node == i){

				SELF[i] = true;
			}

			auto at = MAP.find(make_pair(pre_node,i));
			if(at != MAP.end())continue;

			MAP[make_pair(pre_node,i)] = true;

			G[pre_node].push_back(i);
			reverse_G[i].push_back(pre_node);
		}
	}

	for(int i = 0; i < N; i++)check[i] = false;

	for(int i = 0; i < N;i++){
		if(!check[i])dfs(i);
	}

	for(int i = 0; i < N;i++)check[i] = false;

	group_index = -1;

	while(!S.empty()){
		if(!check[S.top()]){
			group_index++;

			reverse_dfs(S.top());
		}
		S.pop();
	}

	for(int i = 0; i < N; i++){

		work[i] = -BIG_NUM;
	}

	for(int i = 0; i < N; i++){
		for(int k = 0; k < reverse_G[i].size(); k++){
			int tmp_node = reverse_G[i][k];

			if(tmp_node > i || table[i] != table[tmp_node])continue;

			work[i] = max(work[i],tmp_node);
		}
	}

	int tmp = -1;
	int ans = 0;

	for(int i = 0; i < N; i++){
		if(work[i] == -BIG_NUM)continue;
		if(tmp < work[i]){
			ans++;
			tmp = i;
		}
	}

	printf("%d\n",ans);

	return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 23496
final_rank: 15

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

using Graph=vector<vector<int>>;
int main(){
  int n;
  cin>>n;
  vector<int> upper(n+1);
  vector<int> self(n+1);
  self[n]=true;

  Graph g(n);
  for(int i=0;i<n;i++){
    int m;
    cin>>m;
    while(m--){
      int x;
      cin>>x;
      x--;
      if(x==i) self[i]=true;
      if(x<i) g[x].push_back(i);
      if(i<x) upper[i]=true;
    }
  }
  vector<int> flag(n);
  int res=0;
  int l=0;
  for(int i=0;i<=n;i++){
    if(self[i] || flag[i]){
      res++;
      while(l<i){
	for(auto to:g[l]) flag[to]=false;
	l++;
      }
    }
    else if(upper[i]){
      for(auto to:g[i]) flag[to]=true;
    }
    else{
      while(l<i){
	for(auto to:g[l]) flag[to]=false;
	l++;
      }
    }
  }
  cout<<res-1<<endl;
  
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 7460
final_rank: 7

code_snippet: #include "bits/stdc++.h"

#pragma warning(disable:4996)
using namespace std;
using ld = long double;
struct Edge {
	int src;
	int dst;
	long long int A;
	long long int B;
};
struct aa {
	int now;
	long long int cost;
};
bool operator <(const aa&l, const aa&r) {
	return l.cost>r.cost;
}
long long int ce(long long int a,long long  int b) {
	return (a-1)/b+1;
}
int main() {
	int N;cin>>N;
	vector<int>valids(N,true),need_next(N),need_pre(N);
	vector<int>l_cnts(N);
	for (int i = 0; i < N; ++i) {
		int K;cin>>K;
		vector<int>v;
		for (int k = 0; k < K; ++k) {
			int a;cin>>a;
			a--;
			v.push_back(a);
			if (a == i) {
				valids[i]=false;
			}
			if (a == i - 1) {
				need_pre[i]=true;
			}
			else if (a == i + 1) {
				need_next[i]=true;
			}
		}
		sort(v.begin(),v.end());
		v.erase(unique(v.begin(),v.end()),v.end());
		auto it=lower_bound(v.begin(),v.end(),i);
			
	
		l_cnts[i]=it==v.begin()?30000000:i-*prev(it);
	}
	vector<int>dp(N+1);
	for (int i = 0; i < N; ++i) {

		dp[i + 1] = max(dp[i+1],dp[i]);
		if (!valids[i]) {
		}
		else {
			if (need_next[i]) {
				int k=i+1;
				int sum=1;
				while (true) {
					if (l_cnts[k]<=sum) {
						dp[k+1]=max(dp[k+1],dp[i]+sum);
						break;
					}
					else {
						if (valids[k]) {
							if (need_next[k]) {
								dp[k+1]=max(dp[k+1],dp[i]+sum);
								k++;
								sum++;
								continue;
							}
							else {
								if (l_cnts[k] > sum) {

									dp[k + 1] = max(dp[k + 1],dp[i]+ sum + 1);
								}
								else {
									assert(false);
									dp[k+1]=max(dp[k+1],dp[i]+sum);
								}
								break;
							}
						}
						else {
							dp[k+1]=max(dp[k+1],dp[i]+sum);
							break;
						}
					}
				}
			}
			else {
				dp[i+1]=max(dp[i]+1,dp[i+1]);
			}
		}
	}
	cout<<N-dp[N]<<endl;
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 4728
final_rank: 2

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 100010

/* Starry Sky Tree */
//0-index

struct StarrySkyTree{
  typedef int Type;
  int segn2;
  vector<Type> data,s_data;
  function<Type(Type, Type)> merge;
  
  StarrySkyTree(function<Type(Type, Type)> merge, int n): merge(merge)
  {
    for(segn2=1;segn2<n;segn2*=2);
    data.assign(segn2*2,0);
    s_data.assign(segn2*2,0);
  }

  StarrySkyTree(int n): //Original Ver.
    StarrySkyTree([](Type a, Type b){ return max(a, b); }, n) {}
  
  //get minimum value of [a,b)
  Type query(int a,int b,int l=0,int r=-1,int k=0){
    if(r==-1) r+=segn2;
    if(r <= a || b <= l) return -INF; //大きさに注意
    if(a <= l && r <= b) return data[k] + s_data[k];
    return merge(query(a,b,l,(l+r)/2,k*2+1),query(a,b,(l+r)/2,r,k*2+2))+s_data[k];
  }
  
  //add x to [a,b)
  Type add(int a,int b,Type x,int l=0,int r=-1,int k=0){
    if(r==-1) r+=segn2;
    if(a <= l && r <= b){
      s_data[k]+=x;
    }else if(a < r && l < b){
      data[k] = merge(add(a,b,x,l,(l+r)/2,k*2+1),add(a,b,x,(l+r)/2,r,k*2+2));
    }
    return data[k] + s_data[k];
  }
  
};

bool hasnext[SIZE], hasown[SIZE];
int prevmax[SIZE];

int main(){
  int n, m, x;

  scanf("%d", &n);

  for(int i=0;i<n;i++) prevmax[i] = -1;
  
  for(int i=0;i<n;i++){
    scanf("%d", &m);
    for(int j=0;j<m;j++){
      scanf("%d", &x);
      x--;
      hasnext[i] |= x == i+1;
      hasown[i] |= x == i;
      if(x < i) prevmax[i] = max(prevmax[i], x);
    }
  }

  StarrySkyTree seg(n+1);

  seg.add(1,n+1, -INF);
  
  for(int i=0;i<n;i++){
    if(!hasown[i] && !hasnext[i]){
      seg.add(prevmax[i]+1, i+1, 1);
    }

    int res = seg.query(0,i+1);
    
    seg.add(i+1, i+2, res - seg.query(i+1, i+2));

    if(!hasown[i] && hasnext[i]){
      seg.add(prevmax[i]+1, i+1, 1);
    }
  }

  cout << n - seg.query(0,n+1) << endl;
  
  return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 5492
final_rank: 4

code_snippet: #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;
}
accuracy: 1
time_ms: 10
memory_kb: 16804
final_rank: 10

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 100010

/* Starry Sky Tree */
//0-index

struct StarrySkyTree{
  typedef int Type;
  int segn2;
  vector<Type> data,s_data;
  
  StarrySkyTree(int n){
    for(segn2=1;segn2<n;segn2*=2);
    data.assign(segn2*2,0);
    s_data.assign(segn2*2,0);
  }
  
  //get maximum value of [a,b]
  Type query(int a,int b,int l=0,int r=-1,int k=0){
    if(r==-1) r+=segn2;
    if(r<a || b<l) return -INF; //大きさに注意
    if(a<=l && r<=b) return data[k] + s_data[k];
    return max(query(a,b,l,(l+r)/2,k*2+1),query(a,b,(l+r)/2+1,r,k*2+2))+s_data[k];
  }
  
  //add x to [a,b]
  Type add(int a,int b,Type x,int l=0,int r=-1,int k=0){
    if(r==-1) r+=segn2;
    if(a<=l && r<=b){
      s_data[k]+=x;
    }else if(a<=r && l<=b){
      data[k] = max(add(a,b,x,l,(l+r)/2,k*2+1),add(a,b,x,(l+r)/2+1,r,k*2+2));
    }
    return data[k] + s_data[k];
  }
  
};

bool hasnext[SIZE], hasown[SIZE];
int prevmax[SIZE];

int main(){
  int n, m, x;

  scanf("%d", &n);

  for(int i=0;i<n;i++) prevmax[i] = -1;
  
  for(int i=0;i<n;i++){
    scanf("%d", &m);
    for(int j=0;j<m;j++){
      scanf("%d", &x);
      x--;
      hasnext[i] |= x == i+1;
      hasown[i] |= x == i;
      if(x < i) prevmax[i] = max(prevmax[i], x);
    }
  }

  StarrySkyTree seg(n+1);

  seg.add(1,n, -INF);
  
  for(int i=0;i<n;i++){
    if(!hasown[i] && !hasnext[i]){
      seg.add(prevmax[i]+1, i, 1);
    }

    int res = seg.query(0,i);
    
    seg.add(i+1, i+1, res - seg.query(i+1, i+1));

    if(!hasown[i] && hasnext[i]){
      seg.add(prevmax[i]+1, i, 1);
    }
  }

  cout << n - seg.query(0,n) << endl;
  
  return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 5432
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;

struct SCC{
  int n;
  vector<vector<int> > G,rG,T,C;
  vector<int> vs,used,belong;
  SCC(){}
  SCC(int sz):n(sz),G(sz),rG(sz),used(sz),belong(sz){}
  
  void add_edge(int from,int to){
    G[from].push_back(to);
    rG[to].push_back(from);
  }
  
  void input(int m,int offset=0){
    int a,b;
    for(int i=0;i<m;i++){
      cin>>a>>b;
      add_edge(a+offset,b+offset);
    }
  }
  
  void dfs(int v){
    used[v]=1;
    for(int i=0;i<(int)G[v].size();i++){
      if(!used[G[v][i]]) dfs(G[v][i]);
    }
    vs.push_back(v);
  }
  
  void rdfs(int v,int k){
    used[v]=1;
    belong[v]=k;
    C[k].push_back(v);
    for(int i=0;i<(int)rG[v].size();i++){
      if(!used[rG[v][i]]) rdfs(rG[v][i],k);
    }
  }
  
  int build(){
    fill(used.begin(),used.end(),0);
    vs.clear();
    for(int v=0;v<n;v++){
      if(!used[v]) dfs(v);
    }
    fill(used.begin(),used.end(),0);
    int k=0;
    for(int i=vs.size()-1;i>=0;i--){
      if(!used[vs[i]]){
	T.push_back(vector<int>());
	C.push_back(vector<int>());
	rdfs(vs[i],k++);
      }
    }
    for(int i=0;i<n;i++)
      for(int u:G[i])
	if(belong[i]!=belong[u])
	  T[belong[i]].push_back(belong[u]);
    for(int i=0;i<k;i++){
      sort(T[i].begin(),T[i].end());
      T[i].erase(unique(T[i].begin(),T[i].end()),T[i].end());
    }
    return k;
  }
};

//INSERT ABOVE HERE
signed main(){
  int n;
  cin>>n;
  vector<vector<int> > G(n);
  SCC scc(n);
  for(int i=0;i<n;i++){
    int c;
    cin>>c;
    G[i].resize(c);
    for(int j=0;j<c;j++) cin>>G[i][j],G[i][j]--;
    for(auto j:G[i]) scc.add_edge(j,i);
  }
  scc.build();
  auto &b=scc.belong;
  int ans=0,lst=-1;
  for(int v=0;v<n;v++){
    for(int u:G[v]){
      if(b[u]!=b[v]) continue;
      if(u==v+1) continue;
      if(u<=lst) continue;
      lst=v;ans++;
    }
  }
  cout<<ans<<endl;
  return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 24360
final_rank: 16

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

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

#define REP(i,n) for(int i=0;i<(int)(n);i++)
#define FOR(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define FORR(i,a,b) for(int i=(int)(b)-1;i>=(int)(a);i--)

#define CHMIN(a,b) (a)=min((a),(b))
#define CHMAX(a,b) (a)=max((a),(b))

#define MOD 1000000007

int n,m;
set<int> g[125252];

int sm[125252];
vector<int> eds[125252];

int main(){
  scanf("%d",&n);
  REP(i,n){
    scanf("%d",&m);
    while(m--){
      int x;
      scanf("%d",&x);
      g[i].insert(x-1);
    }
  }
  set<int> rm;
  REP(i,n)if(g[i].count(i)){
    rm.insert(i);
  }
  REP(i,n)if(!rm.count(i)){
    set<int>::iterator it = g[i].begin();
    while(it != g[i].end()){
      if(rm.count(*it)){
        g[i].erase(it++);
      }else{
        it++;
      }
    }
  }
  REP(i,n)if(!rm.count(i) && g[i].count(i+1)){
    sm[i+1]++;
  }
  REP(i,n+1)sm[i+1]+=sm[i];
  REP(i,n)if(!rm.count(i)){
    set<int>::iterator it = g[i].begin();
    while(it != g[i].end()){
      int x = *it; it++;
      int y = i;
      if(x==y+1)continue;
      assert(x<y);
      if(y-x == sm[y]-sm[x]){
        eds[x].push_back(y);
      }
    }
  }
  priority_queue<int> Q;
  int ans = rm.size();
  REP(i,n){
    for(int x : eds[i]){
      Q.push(-x);
    }
    if(Q.size() && -Q.top() == i){
      ans++;
      while(Q.size())Q.pop();
    }
  }
  printf("%d\n",ans);
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 16804
final_rank: 11

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

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcount

#define INF 1e16
#define mod 1000000007

int N;
vector<P> rs;

int main(){
  cin>>N;
  ll pre=0;
  rep(i,N){
    ll m;
    cin>>m;
    bool ok=false;
    rep(j,m){
      ll b;
      cin>>b;
      b--;
      if(b>=pre&&b<=i){
        rs.push_back(P(b,i));
      }else if(b==i+1){
        ok=true;
      }
    }
    if(!ok){
      pre=i+1;
    }
  }
  sort(all(rs),[](const P& a,const P& b){ return a.se < b.se; });
  ll crt=0,res=0;
  rep(i,rs.size()){
    if(crt<=rs[i].fi){
      crt=rs[i].se+1; res++;
    }
  }
  cout<<res<<endl;
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3116
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define REP(i,n) for (int i=0;i<(n);i++)
#define REP2(i,m,n) for (int i=m;i<(n);i++)
typedef long long ll;
typedef long double ld;
#define fst first
#define snd second
#define all(c) ((c).begin()), ((c).end())


struct graph {
    int n;
    vector<vector<int>> adj, rdj;
    vector<int> ord, visited, group;
    graph(int n) : n(n), adj(n), rdj(n), visited(n), group(n) { }
    void add_edge(int src, int dst) {
        adj[src].push_back(dst);
        rdj[dst].push_back(src);
    }

    vector<vector<int>> strongly_connected_components() { // kosaraju
        vector<vector<int>> scc;
        function<void(int,vector<vector<int>>&, vector<int>&)> dfs
            = [&](int u, vector<vector<int>> &adj, vector<int> &out) {
            visited[u] = true;
            for (int v: adj[u])
                if (!visited[v]) dfs(v, adj, out);
            out.push_back(u);
        };
        for (int u = 0; u < n; ++u)
            if (!visited[u]) dfs(u, adj, ord);
        fill(all(visited), false);
        for (int i = n-1; i >= 0; --i)
            if (!visited[ord[i]])
                scc.push_back({}), dfs(ord[i], rdj, scc.back());
        for (int i = 0; i < (int)scc.size(); ++i)
            for (int j = 0; j < (int)scc[i].size(); ++j)
                group[scc[i][j]] = scc[i][0];
        return scc;
    }
};

bool used[101010];
int indeg[101010];
int outdeg[101010];
vector<int> inv[101010];
vector<vector<int>> hoge;


int main() {
    int N; cin >> N;
    graph g(N);
    int ans = 0;
    hoge = vector<vector<int>>(N);

    REP(i, N) {
        int m; cin >> m;
        REP(_, m) {
            int j;
            cin >> j;
            --j;
            hoge[i].push_back(j);
            if (i == j) {
                used[i] = true;
            }
        }
        sort(hoge[i].begin(), hoge[i].end());
        hoge[i].erase(unique(hoge[i].begin(), hoge[i].end()), hoge[i].end());
    }

    REP(i, N) ans += used[i];

    REP(i, N) if (!used[i]) {
        for (auto j: hoge[i]) if (!used[j]) g.add_edge(j, i);
        for (auto j: hoge[i]) if (!used[j]) inv[i].push_back(j);
    }

    vector<vector<int>> scc = g.strongly_connected_components();

    REP(i, (int)scc.size()) {
        priority_queue<pair<int, int>> pq;
        REP(j, (int)scc[i].size()) {
            indeg[scc[i][j]] = 0;
            for (auto k: inv[scc[i][j]]) if (g.group[k] == g.group[scc[i][j]]) indeg[scc[i][j]]++;
            pq.push(make_pair(-indeg[scc[i][j]], scc[i][j]));
        }
        while (!pq.empty()) {
            auto p = pq.top();
            pq.pop();
            auto deg = -p.first;
            auto j = p.second;
            if (used[j]) continue;
            vector<int> del = {j};
            vector<int> cand;
            for (auto to: inv[j]) {
                if (used[to] || g.group[j] != g.group[to]) continue;
                del.push_back(to);
                used[to] = true;
            }
            ans += deg;
            used[j] = true;
            for (auto d: del) {
                for (auto e: g.adj[d])  {
                    if (used[e] || g.group[d] != g.group[e]) continue;
                    indeg[e] -= 1;
                    cand.push_back(e);
                }
            }
            sort(cand.begin(), cand.end());
            cand.erase(unique(cand.begin(), cand.end()), cand.end());
            for (auto c: cand) pq.push(make_pair(-indeg[c], c));
        }
    }

    cout << ans << endl;
}
accuracy: 1
time_ms: 80
memory_kb: 25588
final_rank: 18

code_snippet: // g++ -std=c++11 a.cpp
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>	
#include<map>
#include<set>
#include<unordered_map>
#include<utility>
#include<cmath>
#include<random>
#include<cstring>
#include<queue>
#include<stack>
#include<bitset>
#include<cstdio>
#include<sstream>
#include<iomanip>
#include<assert.h>
#include<typeinfo>
#define loop(i,a,b) for(int i=a;i<b;i++) 
#define rep(i,a) loop(i,0,a)
#define FOR(i,a) for(auto i:a)
#define pb push_back
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
#define show1d(v) rep(i,v.size())cout<<" "<<v[i];cout<<endl<<endl;
#define show2d(v) rep(i,v.size()){rep(j,v[i].size())cout<<" "<<v[i][j];cout<<endl;}cout<<endl;
using namespace std;
//kaewasuretyuui
typedef long long ll;
//#define int ll
typedef int Def;
typedef pair<Def,Def> pii;
typedef vector<Def> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef vector<string> vs;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef pair<Def,pii> pip;
typedef vector<pip>vip;
// #define mt make_tuple
// typedef tuple<int,int,int> tp;
// typedef vector<tp> vt;
template<typename A,typename B>bool cmin(A &a,const B &b){return a>b?(a=b,true):false;}
template<typename A,typename B>bool cmax(A &a,const B &b){return a<b?(a=b,true):false;}
//template<class C>constexpr int size(const C &c){return (int)c.size();}
//template<class T,size_t N> constexpr int size(const T (&xs)[N])noexcept{return (int)N;}
const double PI=acos(-1);
const double EPS=1e-9;
Def inf = sizeof(Def) == sizeof(long long) ? 2e18 : 1e9+10;
int dx[]={0,1,0,-1};
int dy[]={1,0,-1,0};

int main(){
	int n;
	cin>>n;
	vvi G(n);
	vi h(n);
	int co=0;
	rep(i,n){
		int m;
		cin>>m;
		vi t(m);
		bool q=false;
		rep(j,m)cin>>t[j];
		rep(j,m)if(i+1==t[j])q=true;
		if(q)co++;
		else{
			rep(j,m){
				int a=t[j];
				if(i+2==a)h[i]=1;
				else if(i+1==a){
					co++;
				}else G[a-1].pb(i);
			}
		}
	}
//	show1d(h);
//	show2d(G);

	rep(i,n)if(h[i]){
		int l=i,r;
		while(h[i])i++;
		r=i;
		vp in;
		loop(j,l,r)rep(k,G[j].size())
			if(G[j][k]<=r)in.pb({G[j][k],j});
		
		sort(all(in));
//		cout<<l<<" "<<r<<endl;
//		rep(j,in.size())cout<<" "<<in[j].first<<" "<<in[j].second<<endl;
//		cout<<endl;
		int t=-1;
		rep(j,in.size()){
			if(t<in[j].second){
				co++;
				t=in[j].first;
			}
		}
	}
	cout<<co<<endl;
	
}
accuracy: 1
time_ms: 30
memory_kb: 6828
final_rank: 5

code_snippet: #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();
}
accuracy: 1
time_ms: 30
memory_kb: 12260
final_rank: 9

code_snippet: #include <iostream>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <stdio.h>
using namespace std;
#define int long long
int MOD = 1000000007;
signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	int N;
	cin >> N;
	vector<vector<int> > A(N);
	int res = 0;
	for (int i = 0; i < N; i++) {
		int M;
		cin >> M;
		int a;
		for (int j = 0; j < M; j++) {
			cin >> a;
			a--;
			A[i].push_back(a);
		}
		sort(A[i].begin(), A[i].end());
		A[i].erase(unique(A[i].begin(), A[i].end()), A[i].end());
	}
	int mx = -1;
	vector<int> E(N, 1);
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < A[i].size(); j++) {
			if (A[i][j] == i) {
				E[i] = 0;
				break;
			}
		}
	}
	for (int i = N - 1; i >= 0; i--) {
		if (E[i] == 0) {
			mx = -1;
		}
		else if ((int)A[i].size() == 0) {
			res++;
			mx = -1;
		}
		else if (A[i].back() == i + 1 && E[i + 1] == 1) {
			if (mx == i) {
				mx = -1;
				E[i] = 0;
				//cerr << "erase " << i << endl;
			}
			else {
				int x = (int)A[i].size() - 2;
				while (x >= 0 && E[A[i][x]] == 0) {
					x--;
				}
				if (x >= 0) {
					mx = max(mx, A[i][x]);
				}
				res++;
			}
		}
		else {
			res++;
			int x = (int)A[i].size() - 1;
			while (x >= 0 && E[A[i][x]] == 0) {
				x--;
			}
			if (x >= 0) {
				mx = A[i][x];
			}
		}
	}
	cout << N - res << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 7656
final_rank: 6

code_snippet: #include <bits/stdc++.h>

using namespace std;

using namespace std;
using Int = long long;

//BEGIN CUT HERE
template< typename T >
struct MonotoneMinima {
  using F = function< T(int, int) >;
  int n;
  F dist;
  T INF;
  vector< T > dp;

  // dist(i,l) + dist(j,k) >= dist(i,k) + dist(j,l)
  // if( i<=j && k<=l )
  MonotoneMinima(int n, F dist, T INF) :
      n(n), dist(dist), INF(INF), dp(n + 1, INF) {}

  void dfs(int l, int r, int a, int b) {
    if(l == r) return;
    int m = (l + r) >> 1;
    T ma = INF;
    int mi = -1;
    for(int i = a; i < b; i++) {
      T tmp = dp[i + 1] + dist(i, m);
      if(tmp < ma) ma = tmp, mi = i;
    }
    dp[m] = min(dp[m], ma);
    dfs(l, m, a, mi + 1);
    dfs(m + 1, r, mi, b);
  }

  void solve(int l, int r) {
    if(l + 1 == r) {
      dp[l] = min(dp[l], dp[r] + dist(l, l));
      return;
    }
    int m = (l + r) >> 1;
    solve(m, r);
    dfs(l, m, m, r);
    solve(l, m);
  }

  T solve() {
    dp[n] = 0;
    solve(0, n);
    return dp[0];
  }
};

struct SuccinctIndexableDictionary {
  size_t length;
  size_t blocks;
  vector< unsigned > bit, sum;

  SuccinctIndexableDictionary() {
  }

  SuccinctIndexableDictionary(size_t _length) {
    length = _length;
    blocks = (length + 31) >> 5;
    bit.assign(blocks, 0U);
    sum.assign(blocks, 0U);
  }

  void set(int k) {
    bit[k >> 5] |= 1U << (k & 31);
  }

  void build() {
    sum[0] = 0U;
    for(int i = 1; i < blocks; i++) {
      sum[i] = sum[i - 1] + __builtin_popcount(bit[i - 1]);
    }
  }

  bool operator[](int k) const {
    return (bool((bit[k >> 5] >> (k & 31)) & 1));
  }

  int rank(int k) {
    return (sum[k >> 5] + __builtin_popcount(bit[k >> 5] & ((1U << (k & 31)) - 1)));
  }

  int rank(bool val, int k) {
    return (val ? rank(k) : k - rank(k));
  }

  int select(bool val, int k) {
    if(k < 0 || rank(val, length) <= k) return (-1);
    int low = 0, high = length;
    while(high - low > 1) {
      int mid = (low + high) >> 1;
      if(rank(val, mid) >= k + 1) high = mid;
      else low = mid;
    }
    return (high - 1);
  }

  int select(bool val, int i, int l) {
    return select(val, i + rank(val, l));
  }
};

template< class T, int MAXLOG >
struct WaveletMatrix {
  size_t length;
  SuccinctIndexableDictionary matrix[MAXLOG];
  int zs[MAXLOG];
  int buff1[MAXLOG], buff2[MAXLOG];

  void max_dfs(int d, int l, int r, int &k, T val, vector< T > &vs) {
    if(l >= r || !k) return;
    if(d == MAXLOG) {
      while(l++ < r && k > 0) vs.push_back(val), k--;
      return;
    }
    int lc = matrix[d].rank(1, l), rc = matrix[d].rank(1, r);
    max_dfs(d + 1, lc + zs[d], rc + zs[d], k, 1ULL << (MAXLOG - d - 1) | val, vs);
    max_dfs(d + 1, l - lc, r - rc, k, val, vs);
  }

  T max_dfs(int d, int l, int r, T val, T a, T b) {
    if(r - l <= 0 || val >= b) return -1;
    if(d == MAXLOG) return val >= a ? val : -1;
    int lc = matrix[d].rank(1, l), rc = matrix[d].rank(1, r);
    T ret = max_dfs(d + 1, lc + zs[d], rc + zs[d], 1ULL << (MAXLOG - d - 1) | val, a, b);
    if(~ret) return ret;
    return max_dfs(d + 1, l - lc, r - rc, val, a, b);
  }

  int freq_dfs(int d, int l, int r, T val, T a, T b) {
    if(l == r) return 0;
    if(d == MAXLOG) return (a <= val && val < b) ? r - l : 0;
    T nv = 1ULL << (MAXLOG - d - 1) | val, nnv = ((1ULL << (MAXLOG - d - 1)) - 1) | nv;
    if(nnv < a || b <= val) return 0;
    if(a <= val && nnv < b) return r - l;
    int lc = matrix[d].rank(1, l), rc = matrix[d].rank(1, r);
    return freq_dfs(d + 1, l - lc, r - rc, val, a, b) +
           freq_dfs(d + 1, lc + zs[d], rc + zs[d], nv, a, b);
  }

  void list_dfs(int d, int l, int r, T val, T a, T b, vector< pair< T, int>> &vs) {
    if(val >= b || r - l <= 0) return;
    if(d == MAXLOG) {
      if(a <= val) vs.push_back(make_pair(val, r - l));
      return;
    }
    T nv = val | (1LL << (MAXLOG - d - 1)), nnv = nv | (((1LL << (MAXLOG - d - 1)) - 1));
    if(nnv < a) return;
    int lc = matrix[d].rank(1, l), rc = matrix[d].rank(1, r);
    list_dfs(d + 1, l - lc, r - rc, val, a, b, vs);
    list_dfs(d + 1, lc + zs[d], rc + zs[d], nv, a, b, vs);
  }


  WaveletMatrix(vector< T > data) {
    length = data.size();
    vector< T > l(length), r(length);
    for(int depth = 0; depth < MAXLOG; depth++) {
      matrix[depth] = SuccinctIndexableDictionary(length + 1);
      int left = 0, right = 0;
      for(int i = 0; i < length; i++) {
        bool k = (data[i] >> (MAXLOG - depth - 1)) & 1;
        if(k) r[right++] = data[i], matrix[depth].set(i);
        else l[left++] = data[i];
      }
      zs[depth] = left;
      matrix[depth].build();
      swap(l, data);
      for(int i = 0; i < right; i++) data[left + i] = r[i];
    }
  }

  T access(int k) {
    int ret = 0;
    bool bit;
    for(int depth = 0; depth < MAXLOG; depth++) {
      bit = matrix[depth][k];
      ret = (ret << 1) | bit;
      k = matrix[depth].rank(bit, k) + zs[depth] * bit;
    }
    return (ret);
  }

  int rank(T val, int k) {
    int l = 0, r = k;
    for(int depth = 0; depth < MAXLOG; depth++) {
      buff1[depth] = l, buff2[depth] = r;
      bool bit = (val >> (MAXLOG - depth - 1)) & 1;
      l = matrix[depth].rank(bit, l) + zs[depth] * bit;
      r = matrix[depth].rank(bit, r) + zs[depth] * bit;
    }
    return (r - l);
  }

  int select(T val, int kth) {
    rank(val, length);
    for(int depth = MAXLOG - 1; depth >= 0; depth--) {
      bool bit = (val >> (MAXLOG - depth - 1)) & 1;
      kth = matrix[depth].select(bit, kth, buff1[depth]);
      if(kth >= buff2[depth] || kth < 0) return (-1);
      kth -= buff1[depth];
    }
    return (kth);
  }

  int select(T val, int k, int l) {
    return (select(val, k + rank(val, l)));
  }


  int quantile(int left, int right, int kth) {
    if(right - left <= kth || kth < 0) return (-1);
    T ret = 0;
    for(int depth = 0; depth < MAXLOG; depth++) {
      int l = matrix[depth].rank(1, left);
      int r = matrix[depth].rank(1, right);
      if(r - l > kth) {
        left = l + zs[depth];
        right = r + zs[depth];
        ret |= 1ULL << (MAXLOG - depth - 1);
      } else {
        kth -= r - l;
        left -= l;
        right -= r;
      }
    }
    return (ret);
  }

  vector< T > topk(int l, int r, int k) {
    if(r - l < k) k = r - l;
    if(k < 0) return (vector< T >());
    vector< T > ret;
    max_dfs(0, l, r, k, 0, ret);
    return (ret);
  }

  vector< pair< T, int > > freq_list(int l, int r, T a, T b) {
    vector< pair< T, int > > ret;
    list_dfs(0, l, r, 0, a, b, ret);
    return (ret);
  }

  vector< pair< int, T > > get_rect(int l, int r, T a, T b) {
    vector< pair< T, int > > res = freq_list(l, r, a, b);
    vector< pair< int, T > > ret;
    for(auto &e : res) {
      for(int i = 0; i < e.second; i++) {
        ret.emplace_back(select(e.first, i, l), e.first);
      }
    }
    return (ret);
  }

  int rangefreq(int left, int right, T lower, T upper) {
    return (freq_dfs(0, left, right, 0, lower, upper));
  }
};


int main() {
  int N;
  vector< int > g[100000];
  bool nxt[100000] = {};


  cin >> N;
  for(int i = 0; i < N; i++) {
    int x;
    cin >> x;
    bool flag = false;
    while(x--) {
      int v;
      cin >> v;
      --v;
      if(v == i + 1) nxt[i] = true;
      else g[i].emplace_back(v);
    }
  }
  vector< int > near(N);
  for(int i = 0; i < N; i++) {
    sort(begin(g[i]), end(g[i]));
    near[i] = 0;
    if(g[i].size()) near[i] = g[i].back() + 1;
  }
  WaveletMatrix< int, 19 > mat(near);

  auto dist = [&](int r, int l) {
    int cost = nxt[r] | near[r] - 1 >= l;
    cost += mat.rangefreq(l, r, l + 1, N + 5);
    return cost;
  };
  using int64 = long long;
  const int64 INF = 1LL << 60;
  MonotoneMinima< int64 > beet(N, dist, INF);
  cout << beet.solve() << endl;
}
accuracy: 1
time_ms: 1030
memory_kb: 8856
final_rank: 13

code_snippet: #include<bits/stdc++.h>
#define X first
#define Y sevcond
#define pb emplace_back
#define eb pb
#define rep(X,Y) for(int X=0;X<(Y);++X)
#define reps(X,O,Y) for(int X=(O);X<(Y);++X)
#define all(X) (X).begin(),(X).end()
#define rall(X) (X).rbegin(),(X).rend()

using namespace std;
using ll=long long;
const ll MOD=1e9+7;
using Graph=vector<vector<int>>;

#include<chrono>
using namespace chrono;
system_clock::time_point starttime=system_clock::now();

int main(){
	int n;
	cin>>n;
	Graph g(n);
	rep(i,n){
		int m;
		cin>>m;
		rep(j,m){
			int v;
			cin>>v; --v;
			g[v].pb(i);
		}
	}
	vector<int> vst(n),in(n,-1);
	int ans=0;
	function<int(int,int)> dfs=
		[&](int v,int d)->int{
			if(vst[v]) return -1;
			in[v]=d;
			vst[v]=1;
			// cout<<v<<","<<d<<endl;
			int re=-1;
			for(int w:g[v]){
				// cout<<v<<":"<<w<<","<<in[w]<<endl;
				if(in[w]>=0) re=max(re,in[w]);
				else re=max(re,dfs(w,d+1));
			}
			// cout<<v<<","<<d<<","<<re<<endl;
			in[v]=-1;
			if(re==d){
				++ans;
				re=-1;
			}
			return re;
		};
	int re=MOD;
	vector<int> ind(n); iota(all(ind),0);
	// ind={4,1,2,3,0};
	// rep(i,n) dfs(ind[i],0);
	// cout<<ans<<endl;
	// return 0;
	while((duration_cast<milliseconds>(system_clock::now()-starttime).count())<1900){
		ans=0;
		fill(all(vst),0);
		fill(all(in),-1);
		rep(i,n) dfs(ind[i],0);
		re=min(re,ans);
		// if(ans==0){
		// 	rep(i,n) cout<<ind[i]<<",";cout<<endl;
		// 	exit(0);
		// }
		random_shuffle(all(ind));
		rep(i,n) random_shuffle(all(g[i]));
	}
	cout<<re<<endl;
}
accuracy: 0.3939393939393939
time_ms: 1890
memory_kb: 3196
final_rank: 20

code_snippet: #include<bits/stdc++.h>
#define X first
#define Y sevcond
#define pb emplace_back
#define eb pb
#define rep(X,Y) for(int X=0;X<(Y);++X)
#define reps(X,O,Y) for(int X=(O);X<(Y);++X)
#define all(X) (X).begin(),(X).end()
#define rall(X) (X).rbegin(),(X).rend()

using namespace std;
using ll=long long;
const ll MOD=1e9+7;
using Graph=vector<vector<int>>;

#include<chrono>
using namespace chrono;
system_clock::time_point starttime=system_clock::now();

int main(){
	int n;
	cin>>n;
	Graph g(n);
	rep(i,n){
		int m;
		cin>>m;
		rep(j,m){
			int v;
			cin>>v; --v;
			g[v].pb(i);
		}
	}
	vector<int> vst(n),in(n,-1);
	int ans=0;
	function<int(int,int)> dfs=
		[&](int v,int d)->int{
			if(vst[v]) return -1;
			in[v]=d;
			vst[v]=1;
			// cout<<v<<","<<d<<endl;
			int re=-1;
			for(int w:g[v]){
				// cout<<v<<":"<<w<<","<<in[w]<<endl;
				if(in[w]>=0) re=max(re,in[w]);
				else re=max(re,dfs(w,d+1));
			}
			// cout<<v<<","<<d<<","<<re<<endl;
			in[v]=-1;
			if(re==d){
				++ans;
				re=-1;
			}
			return re;
		};
	int re=MOD;
	vector<int> ind(n); iota(all(ind),0);
	// ind={4,1,2,3,0};
	// rep(i,n) dfs(ind[i],0);
	// cout<<ans<<endl;
	// return 0;
	while((duration_cast<milliseconds>(system_clock::now()-starttime).count())<1900){
		ans=0;
		fill(all(vst),0);
		fill(all(in),-1);
		rep(i,n) dfs(ind[i],0);
		re=min(re,ans);
		// if(ans==0){
		// 	rep(i,n) cout<<ind[i]<<",";cout<<endl;
		// 	exit(0);
		// }
		random_shuffle(all(ind));
	}
	cout<<re<<endl;
}
accuracy: 0.3939393939393939
time_ms: 1890
memory_kb: 3148
final_rank: 19

code_snippet: #include <bits/stdc++.h>
#define GET_MACRO(_1,_2,_3,_4,_5,_6,_7,_8,NAME,...) NAME
#define pr(...) cerr<< GET_MACRO(__VA_ARGS__,pr8,pr7,pr6,pr5,pr4,pr3,pr2,pr1)(__VA_ARGS__) <<endl
#define pr1(a) (#a)<<"="<<(a)<<" "
#define pr2(a,b) pr1(a)<<pr1(b)
#define pr3(a,b,c) pr1(a)<<pr2(b,c)
#define pr4(a,b,c,d) pr1(a)<<pr3(b,c,d)
#define pr5(a,b,c,d,e) pr1(a)<<pr4(b,c,d,e)
#define pr6(a,b,c,d,e,f) pr1(a)<<pr5(b,c,d,e,f)
#define pr7(a,b,c,d,e,f,g) pr1(a)<<pr6(b,c,d,e,f,g)
#define pr8(a,b,c,d,e,f,g,h) pr1(a)<<pr7(b,c,d,e,f,g,h)
using namespace std;
using Int = long long;
using _int = int;
using ll = long long;
using Double = long double;
const Int INF = (1LL<<55)+1e9; // ~ 3.6 * 1e16
const Int mod = (1e9)+7;
const Double EPS = 1e-8;
const Double PI = 6.0 * asin((Double)0.5);
using P = pair<Int,Int>;
using T = tuple<Int,Int,Int>;
template<class T> T Max(T &a,T b){return a=max(a,b);}
template<class T> T Min(T &a,T b){return a=min(a,b);}
template<class T1, class T2> ostream& operator<<(ostream& o,pair<T1,T2> p){return o<<"("<<p.first<<","<<p.second<<")";}
template<class T1, class T2, class T3> ostream& operator<<(ostream& o,tuple<T1,T2,T3> t){
  return o<<"("<<get<0>(t)<<","<<get<1>(t)<<","<<get<2>(t)<<")";}
template<class T1, class T2> istream& operator>>(istream& i,pair<T1,T2> &p){return i>>p.first>>p.second;}
template<class T> ostream& operator<<(ostream& o,vector<T> &a){Int i=0;for(T t:a)o<<(i++?" ":"")<<t;return o;}
template<class T> istream& operator>>(istream& i,vector<T> &a){for(T &t:a)i>>t;return i;}
template<class T>void prArr(T a,string s=" "){Int i=0;for(T t:a)cout<<(i++?s:"")<<t;cout<<endl;}


class SCC{
public:
  int V,K;                      //頂点数, scc後の頂点数
  vector<vector<int> > G;       //グラフの隣接リストの表現
  vector<vector<int> >rG;       //辺の向きを逆にしたグラフ
  vector<vector<int> >DAG;      //scc後のグラフの隣接リストの表現
  vector<vector<int> >rDAG;     //scc後の辺の向きを逆にしたグラフ
  vector<int> vs;               //帰りがけ順の並び
  vector<int>used;              //すでに調べたか
  vector<int> cmp;              //属する強連結成分のトポロジカル順
  vector<vector<int> > member;  //scc後の同じグループのノードの集合
  int ok;                       //buildされているか。
  SCC(){V = K = -1;}
  SCC(int V):V(V),G(V),rG(V),used(V,0),cmp(V),ok(0){}
  
  void add_edge(int from,int to){
    assert(from<V && to<V);
    G[from].push_back(to);
    rG[to].push_back(from);
  }

  void dfs(int v){
    used[v]=true;
    for(int nx:G[v]) if(!used[nx]) dfs(nx);
    vs.push_back(v);
  }

  void rdfs(int v,int k){
    used[v]=true;
    cmp[v]=k;
    for(int nx:rG[v]) if(!used[nx]) rdfs(nx,k);
  }

  int build(bool makeDAG = 0){ //DAGのグラフも作りたかったらmakeDAGを1にする
    ok = true;
    used.clear(); used.resize(V,0);
    vs.clear();
    for(int v=0;v<V;v++) if(!used[v]) dfs(v);
    
    used.clear(); used.resize(V,0);
    int &k= K = 0;
    for(int i=vs.size()-1;i>=0;i--)if(!used[vs[i]]) rdfs(vs[i],k++);

    member.clear();
    member.resize(k);
    for(int i=0;i<V;i++) member[cmp[i]].push_back(i);
    
    if(makeDAG) DAG = getDAG(G), rDAG = getDAG(rG); //O(ElogE)
    
    return k;
  }

  bool same(int u, int v){assert(ok);return cmp[u] == cmp[v];}

private:
  vector<vector<int> > getDAG(const vector<vector<int> > &G){
    assert(K>=0);
    vector<vector<int> >res(K);
    for(int from=0;from<V;from++)
      for(int to:G[from]) if(cmp[from]!=cmp[to]) res[cmp[from]].push_back(cmp[to]);
    
    for(int i=0;i<K;i++){
      sort(res[i].begin(),res[i].end());
      res[i].erase(unique(res[i].begin(),res[i].end()),res[i].end());
    }
    return res;
  }
};


signed main(){
  srand((unsigned)time(NULL));
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);
  
  int n;
  cin>>n;

  SCC scc(n);
  vector<vector<int> > G(n);
  for(int i=0;i<n;i++){
    int m;
    cin>>m;
    for(int j=0;j<m;j++){
      int to;
      cin>>to; to--;
      assert(i >= to -1);
      scc.add_edge(i, to);
      G[i].push_back(to);
    }
  }

  scc.build();
  vector<P> A;
  for(int i=0;i<n;i++){
    for(int to:G[i]){
      if(!scc.same(i, to)) continue;
      if(i < to) continue;
      int l = to, r = i;
      A.push_back(P(r, l));
    }
  }
  
  sort(A.begin(), A.end());
  int ans = 0;
  int last = -1;
  for(P p:A){
    int r, l; tie(r, l) = p;
    if(last < l){
      ans++;
      last = r;
    }
  }

  cout<<ans<<endl;
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 20728
final_rank: 12

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;

struct SCC{
  int n;
  vector<vector<int> > G,rG,T,C;
  vector<int> vs,used,belong;
  SCC(){}
  SCC(int sz):n(sz),G(sz),rG(sz),used(sz),belong(sz){}
  
  void add_edge(int from,int to){
    G[from].push_back(to);
    rG[to].push_back(from);
  }
  
  void input(int m,int offset=0){
    int a,b;
    for(int i=0;i<m;i++){
      cin>>a>>b;
      add_edge(a+offset,b+offset);
    }
  }
  
  void dfs(int v){
    used[v]=1;
    for(int i=0;i<(int)G[v].size();i++){
      if(!used[G[v][i]]) dfs(G[v][i]);
    }
    vs.push_back(v);
  }
  
  void rdfs(int v,int k){
    used[v]=1;
    belong[v]=k;
    C[k].push_back(v);
    for(int i=0;i<(int)rG[v].size();i++){
      if(!used[rG[v][i]]) rdfs(rG[v][i],k);
    }
  }
  
  int build(){
    fill(used.begin(),used.end(),0);
    vs.clear();
    for(int v=0;v<n;v++){
      if(!used[v]) dfs(v);
    }
    fill(used.begin(),used.end(),0);
    int k=0;
    for(int i=vs.size()-1;i>=0;i--){
      if(!used[vs[i]]){
	T.push_back(vector<int>());
	C.push_back(vector<int>());
	rdfs(vs[i],k++);
      }
    }
    for(int i=0;i<n;i++)
      for(int u:G[i])
	if(belong[i]!=belong[u])
	  T[belong[i]].push_back(belong[u]);
    for(int i=0;i<k;i++){
      sort(T[i].begin(),T[i].end());
      T[i].erase(unique(T[i].begin(),T[i].end()),T[i].end());
    }
    return k;
  }
};

//INSERT ABOVE HERE
signed main(){
  int n;
  cin>>n;
  vector<vector<int> > G(n);
  SCC scc(n);
  for(int i=0;i<n;i++){
    int c;
    cin>>c;
    G[i].resize(c);
    for(int j=0;j<c;j++) cin>>G[i][j],G[i][j]--;
    for(auto j:G[i]) scc.add_edge(j,i);
  }
  scc.build();
  auto &b=scc.belong;
  int ans=0,lst=-1;
  for(int v=0;v<n;v++){
    for(int u:G[v]){
      if(b[u]!=b[v]) continue;
      if(u==v+1) continue;
      if(u<=lst) continue;
      lst=v;ans++;
    }
  }
  cout<<ans<<endl;
  return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 24248
final_rank: 17

code_snippet: #include <bits/stdc++.h>
#define GET_MACRO(_1,_2,_3,_4,_5,_6,_7,_8,NAME,...) NAME
#define pr(...) cerr<< GET_MACRO(__VA_ARGS__,pr8,pr7,pr6,pr5,pr4,pr3,pr2,pr1)(__VA_ARGS__) <<endl
#define pr1(a) (#a)<<"="<<(a)<<" "
#define pr2(a,b) pr1(a)<<pr1(b)
#define pr3(a,b,c) pr1(a)<<pr2(b,c)
#define pr4(a,b,c,d) pr1(a)<<pr3(b,c,d)
#define pr5(a,b,c,d,e) pr1(a)<<pr4(b,c,d,e)
#define pr6(a,b,c,d,e,f) pr1(a)<<pr5(b,c,d,e,f)
#define pr7(a,b,c,d,e,f,g) pr1(a)<<pr6(b,c,d,e,f,g)
#define pr8(a,b,c,d,e,f,g,h) pr1(a)<<pr7(b,c,d,e,f,g,h)
using namespace std;
using Int = long long;
using _int = int;
using ll = long long;
using Double = long double;
const Int INF = (1LL<<55)+1e9; // ~ 3.6 * 1e16
const Int mod = (1e9)+7;
const Double EPS = 1e-8;
const Double PI = 6.0 * asin((Double)0.5);
using P = pair<Int,Int>;
using T = tuple<Int,Int,Int>;
template<class T> T Max(T &a,T b){return a=max(a,b);}
template<class T> T Min(T &a,T b){return a=min(a,b);}
template<class T1, class T2> ostream& operator<<(ostream& o,pair<T1,T2> p){return o<<"("<<p.first<<","<<p.second<<")";}
template<class T1, class T2, class T3> ostream& operator<<(ostream& o,tuple<T1,T2,T3> t){
  return o<<"("<<get<0>(t)<<","<<get<1>(t)<<","<<get<2>(t)<<")";}
template<class T1, class T2> istream& operator>>(istream& i,pair<T1,T2> &p){return i>>p.first>>p.second;}
template<class T> ostream& operator<<(ostream& o,vector<T> &a){Int i=0;for(T t:a)o<<(i++?" ":"")<<t;return o;}
template<class T> istream& operator>>(istream& i,vector<T> &a){for(T &t:a)i>>t;return i;}
template<class T>void prArr(T a,string s=" "){Int i=0;for(T t:a)cout<<(i++?s:"")<<t;cout<<endl;}


class SCC{
public:
  int V,K;                      //頂点数, scc後の頂点数
  vector<vector<int> > G;       //グラフの隣接リストの表現
  vector<vector<int> >rG;       //辺の向きを逆にしたグラフ
  vector<vector<int> >DAG;      //scc後のグラフの隣接リストの表現
  vector<vector<int> >rDAG;     //scc後の辺の向きを逆にしたグラフ
  vector<int> vs;               //帰りがけ順の並び
  vector<int>used;              //すでに調べたか
  vector<int> cmp;              //属する強連結成分のトポロジカル順
  vector<vector<int> > member;  //scc後の同じグループのノードの集合
  int ok;                       //buildされているか。
  SCC(){V = K = -1;}
  SCC(int V):V(V),G(V),rG(V),used(V,0),cmp(V),ok(0){}
  
  void add_edge(int from,int to){
    assert(from<V && to<V);
    G[from].push_back(to);
    rG[to].push_back(from);
  }

  void dfs(int v){
    used[v]=true;
    for(int nx:G[v]) if(!used[nx]) dfs(nx);
    vs.push_back(v);
  }

  void rdfs(int v,int k){
    used[v]=true;
    cmp[v]=k;
    for(int nx:rG[v]) if(!used[nx]) rdfs(nx,k);
  }

  int build(bool makeDAG = 0){ //DAGのグラフも作りたかったらmakeDAGを1にする
    ok = true;
    used.clear(); used.resize(V,0);
    vs.clear();
    for(int v=0;v<V;v++) if(!used[v]) dfs(v);
    
    used.clear(); used.resize(V,0);
    int &k= K = 0;
    for(int i=vs.size()-1;i>=0;i--)if(!used[vs[i]]) rdfs(vs[i],k++);

    member.clear();
    member.resize(k);
    for(int i=0;i<V;i++) member[cmp[i]].push_back(i);
    
    if(makeDAG) DAG = getDAG(G), rDAG = getDAG(rG); //O(ElogE)
    
    return k;
  }

  bool same(int u, int v){assert(ok);return cmp[u] == cmp[v];}

private:
  vector<vector<int> > getDAG(const vector<vector<int> > &G){
    assert(K>=0);
    vector<vector<int> >res(K);
    for(int from=0;from<V;from++)
      for(int to:G[from]) if(cmp[from]!=cmp[to]) res[cmp[from]].push_back(cmp[to]);
    
    for(int i=0;i<K;i++){
      sort(res[i].begin(),res[i].end());
      res[i].erase(unique(res[i].begin(),res[i].end()),res[i].end());
    }
    return res;
  }
};


signed main(){
  srand((unsigned)time(NULL));
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);
  
  int n;
  cin>>n;

  SCC scc(n);
  vector<vector<int> > G(n);
  for(int i=0;i<n;i++){
    int m;
    cin>>m;
    for(int j=0;j<m;j++){
      int to;
      cin>>to; to--;
      assert(i >= to -1);
      scc.add_edge(i, to);
      G[i].push_back(to);
    }
  }

  scc.build();
  vector<P> A;
  for(int i=0;i<n;i++){
    for(int to:G[i]){
      if(!scc.same(i, to)) continue;
      if(i < to) continue;
      int l = to, r = i;
      A.push_back(P(r, l));
    }
  }
  
  sort(A.begin(), A.end());
  int ans = 0;
  int last = -1;
  for(P p:A){
    int r, l; tie(r, l) = p;
    if(last < l){
      ans++;
      last = r;
    }
  }

  cout<<ans<<endl;
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 20964
final_rank: 14

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define all(v) (v).begin(), (v).end()

using Pi = pair<int, int>;
using vint = vector<int>;
using Graph = vector<vint>;

Graph get_rev(const Graph& G) {
  int V = G.size();
  Graph H(V);
  for(int v = 0; v < V; ++v) {
    for(int u : G[v]) H[u].push_back(v);
  }
  return H;
}
void dfs(const Graph& G, int v, vint& ord, vint& used) {
  used[v] = 1;
  for(int u : G[v]) if(!used[u]) dfs(G, u, ord, used);
  ord.push_back(v);
}
void rdfs(const Graph& H, int v, int id, vint& cmp) {
  cmp[v] = id;
  for(int u : H[v]) if(cmp[u] == -1) rdfs(H, u, id, cmp);
}
vint decompose(const Graph& G) {
  Graph H = get_rev(G);
  int V = G.size();
  vint ord, used(V, 0);
  for(int v = 0; v < V; ++v) if(!used[v]) dfs(G, v, ord, used);
  reverse(all(ord));
  int sz = 0;
  vint cmp(V, -1);
  for(int v : ord) if(cmp[v] == -1) rdfs(H, v, sz++, cmp);

  return cmp;
}

int main() {
  int N;
  cin >> N;
  Graph G(N);
  for(int i = 0; i < N; ++i) {
    int k;
    cin >> k;
    for(int j = 0; j < k; ++j) {
      int job;
      cin >> job; --job;
      G[job].push_back(i);
    }
  }
  vint cmp = decompose(G);
  vector<Pi> vec;
  for(int l = 0; l < N; ++l) {
    for(int r : G[l]) {
      if(cmp[l] != cmp[r] || l > r) continue;
      vec.emplace_back(r, l);
    }
  }
  sort(all(vec));
  int ans = 0, last = -1;
  for(Pi p : vec) {
    if(last < p.second) ++ans, last = p.first;
  }
  cout << ans << endl;
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 11684
final_rank: 8