1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 using namespace std;
5
6 const int MAXN = 20005;
7
8 typedef struct _node
9 {
10 int v, next;
11 }N;
12 N edge[MAXN * 3];
13 int dfn[MAXN], low[MAXN], step;
14 int inS[MAXN], id[MAXN], scc, myS[MAXN], top;
15 int in[MAXN], out[MAXN], cntEdge, head[MAXN];
16
17 void init()
18 {
19 cntEdge = step = scc = top = 0;
20 for(int i = 0; i < MAXN; i++)
21 {
22 head[i] = -1;
23 dfn[i] = low[i] = -1;
24 id[i] = -1;
25 in[i] = out[i] = 0;
26 inS[i] = 0;
27 }
28 }
29
30 void tarjan(int n)
31 {
32 dfn[n] = low[n] = ++step;
33 myS[top++] = n;
34 inS[n] = 1;
35 for(int f = head[n]; f != -1; f = edge[f].next)
36 {
37 int son = edge[f].v;
38 if(dfn[son] == -1)
39 {
40 tarjan(son);
41 low[n] = min(low[n], low[son]);
42 }
43 else if(inS[son] != 0)
44 low[n] = min(low[n], dfn[son]);
45 }
46
47 if(low[n] == dfn[n])
48 {
49 int tmp;
50 do
51 {
52 tmp = myS[--top];
53 inS[tmp] = 0;
54 id[tmp] = scc;
55 }while(myS[top] != n);
56 scc++;
57 }
58 }
59
60 void addEdge(int u, int v)
61 {
62 edge[cntEdge].v = v;
63 edge[cntEdge].next = head[u];
64 head[u] = cntEdge++;
65 }
66
67
68
69 int main(void)
70 {
71 #ifndef ONLINE_JUDGE
72 freopen("inHDU2767.txt", "r", stdin);
73 #endif
74
75 int n, m, cas;
76 scanf("%d", &cas);
77 while(cas--)
78 {
79 scanf("%d %d", &n, &m);
80 init();
81 int u, v;
82 for(int i = 0; i < m; i++)
83 {
84 scanf("%d %d", &u, &v);
85 addEdge(u, v);
86 }
87
88 for(int i = 1; i <= n; i++)
89 {
90 if(dfn[i] == -1)
91 tarjan(i);
92 }
93 for(int i = 1; i <= n; i++)
94 {
95 for(int j = head[i]; j != -1; j = edge[j].next)
96 {
97 u = i, v = edge[j].v;
98 if(id[u] == id[v])
99 continue;
100 else
101 {
102 in[id[v]]++;
103 out[id[u]]++;
104 }
105 }
106 }
107 int inNum = 0, outNum = 0;
108 for(int i = 0; i < scc; i++)
109 {
110 if(!in[i])
111 inNum++;
112 if(!out[i])
113 outNum++;
114 }
115 if(scc >= 2)
116 printf("%d\n", max(inNum, outNum));
117 else
118 printf("0\n");
119 }
120 return 0;
121 }