tarjan就不讲了
首先缩点,然后发现明星只可能是缩点重新建图后,出度为零的点,否则他自己无法欢迎他自己
但是如果出度为零的点>=2个,就没有受欢迎的牛了

#include<iostream>
#include<cstring>
#include<stack>
using namespace std;
int color[200000],cnt=0;
struct edge{
    int v,fail;
    edge(){
    }
    edge(int a,int b){
        v=a;
        fail=b;
    }
}e[400000];
int n,m,head[200000],len;
int N[200000];
void init(){
    len=0;
    memset(head,-1,sizeof(head));
}
int dfn[200000],low[200000],vis[200000];
void add(int a,int b){
    e[len]=edge(b,head[a]);
    head[a]=len++;
}
int Time;
stack<int> s;
void calc(){
	int t=s.top();
	s.pop();
	color[t]=cnt;
	N[cnt]++;
	vis[t]=0;
} 
void tarjan(int x){
	vis[x]=1;
	s.push(x);
	dfn[x]=low[x]=++Time;
	for(int i=head[x];~i;i=e[i].fail){
		if(!dfn[e[i].v]){
			tarjan(e[i].v);
			low[x]=min(low[x],low[e[i].v]);
		}else if(vis[e[i].v])low[x]=min(low[x],dfn[e[i].v]);
	}
	if(dfn[x]==low[x]){
		cnt++;
		while(s.top()!=x)calc();
		calc();
	}
}
int in[100000]; 
int x[100000],y[100000];
int main(){
	cin>>n>>m;
	init();
	for(int i=1;i<=m;i++){
		cin>>x[i]>>y[i];
		add(x[i],y[i]);
	}
	for(int i=1;i<=n;i++){
		if(!color[i])tarjan(i);
	}
	int ans=0;
	int tot=0;
	for(int i=1;i<=m;i++){
	//	cout<<color[i]<<endl;
		if(color[x[i]]!=color[y[i]]){
			in[color[x[i]]]++;
	//		cout<<color[x[i]]<<" to"<<color[y[i]]<<endl;
		}
	}	
	for(int i=1;i<=cnt;i++){
		if(!in[i]){
			tot++;
			ans=N[i];
		}
	}
//	cout<<cnt<<endl;
	if(tot==1)
	cout<<ans<<endl;
	else cout<<0<<endl;
	return 0;
}