#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<vector> #define M 50005 #define SZ(x) x.size() #define FF(x,xi,y) for(int x=xi;x<=y;++x) #define FFL(x,u) for(int x=head[u];x!=-1;x=edge[x].next) #define CC(x,y) memset(x,y,sizeof(x)) using namespace std; int tot,head[M],ncase,newhead[M],id[M],pre[M],low[M],n,m,nn,hash[M],top,index,stack[M]; struct pp{int v,next;}edge[5*M]; inline void addedge(int u,int v){edge[tot].v=v,edge[tot].next=head[u],head[u]=tot++;} inline void addnewedge(int u,int v){edge[tot].v=v,edge[tot].next=newhead[u],newhead[u]=tot++;} template<class T> inline void checkmax(T &x,T y){if(x<y) x=y;} template<class T> inline void checkmin(T &x,T y){if(x>y) x=y;} template<class T> inline T Min(T x,T y){return (x>y?y:x);} template<class T> inline T Max(T x,T y){return (x<y?y:x);} void dfs(int r) { pre[r]=low[r]=index++; stack[++top]=r; FFL(i,r) { if(pre[edge[i].v]==-1) { dfs(edge[i].v); checkmin(low[r],low[edge[i].v]); } else if(id[edge[i].v]==-1) checkmin(low[r],pre[edge[i].v]); } if(pre[r]==low[r]) { int v=0; while(r!=v) { if(v==-1) break; v=stack[top--]; id[v]=nn; } newhead[nn++] = -1; } } void tarian() { CC(pre,-1); CC(hash,-1); CC(id,-1); stack[0]=-1; index=0,top=0,nn=1; FF(i,1,n){if(pre[i]==-1) dfs(i); } FF(i,1,n) { FFL(j,i) { int v=edge[j].v; if(id[v]!=id[i]&&hash[id[i]]!=id[v]) { hash[id[i]]=id[v]; addnewedge(id[i],id[v]); } } } } int main() { scanf("%d",&ncase); while(ncase--) { CC(head,-1); scanf("%d%d",&n,&m); tot=0; FF(i,1,m){int u,v;scanf("%d%d",&u,&v); addedge(u,v);} tarian(); int ind[M]={},od[M]={}; FF(i,1,nn-1) { for(int j=newhead[i];j!=-1;j=edge[j].next) ind[edge[j].v]++,od[i]++; } int maxi=0,maxo=0; FF(i,1,nn-1) {if(ind[i]==0) maxi++;if(od[i]==0) maxo++;} printf("%d\n",nn==2?0:Max(maxi,maxo)); } return 0; }