/* 题意:给一张有向图,求这样的一个点集,使得集合中的点u,v,u->v,or v->u,or,u<->v。 对图缩点,构造一张DAG。在DAG上作dp最长路。 点权为每个强连通分量重节点的个数。*/#include <stdio.h>#include <cstring>#include <algorithm>#include <vector>using namespace std;const int maxn=1010;const int maxm=50001;struct edge{ int to,next;} e[maxm];vector<int> map[maxn];int head[maxn],low[maxn],stack[maxn],dfn[maxn],belong[maxn],dp[maxn],num[maxn];bool vis[maxn];int n,t,scnt,top,cnt;void add(int i,int j){ e[t].next=head[i]; e[t].to=j; head[i]=t++;}void tarjan(int u){ int tt; dfn[u]=low[u]=++cnt; stack[top++]=u; vis[u]=true; for(int i=head[u]; i!=-1; i=e[i].next) { int j=e[i].to; if(!dfn[j]) { tarjan(j); low[u]=min(low[u],low[j]); } else if(vis[j]) low[u]=min(low[u],low[j]); } if(low[u]==dfn[u]) { scnt++; do { tt=stack[--top]; belong[tt]=scnt; vis[tt]=false; } while(u!=tt); }}int f(int u){ if(dp[u]) return dp[u]; int ans=0; for(int i=0; i<(int)map[u].size(); i++) ans=max(ans,f(map[u][i])); return dp[u]=ans+num[u];}int main(){ int T,m,a,b; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); memset(head,-1,sizeof(head)); memset(belong,0,sizeof(belong)); memset(low,0,sizeof(low)); memset(dfn,0,sizeof(dfn)); memset(stack,0,sizeof(stack)); memset(vis,false,sizeof(vis)); memset(dp,0,sizeof(dp)); memset(num,0,sizeof(num)); top=0; cnt=scnt=t=0; while(m--) { scanf("%d%d",&a,&b); add(a,b); } for(int i=1; i<=n; i++) { if(!dfn[i]) tarjan(i); } memset(vis,false,sizeof(vis)); for(int i=1; i<=scnt; i++) map[i].clear(); for(int i=1; i<=n; i++) { for(int j=head[i]; j!=-1; j=e[j].next) { int u=e[j].to; if(belong[i]!=belong[u]) { map[belong[i]].push_back(belong[u]); vis[belong[u]]=true;//从入度为0点开始搜 } } num[belong[i]]++; } int ans=0; for(int i=1; i<=scnt; i++) if(!vis[i]) ans=max(ans,f(i)); printf("%d\n",ans); } return 0;}