P1018

#include <bits/stdc++.h>

const int N = 1000010, M = 1000010;
int t, n, m;
int head[N], nxt[M], to[M], idx;
int dfn[N], low[N], tsp;
int stk[N], top;
bool ins[N];
int scc_cnt, ans;

void init(int x) {
    tsp = idx = top = 0;
    ans = scc_cnt = 0;
    for (int i = 1; i <= x; ++ i) {
        head[i] = -1;
        dfn[i] = low[i] = 0;
        ins[i] = false;
    }
    return;
}
void add(int u, int v) {
    nxt[idx] = head[u];
    to[idx] = v;
    head[u] = idx;
    ++ idx;
    return;
}
void dfsearch(int x) {
    ++ tsp;
    dfn[x] = low[x] = tsp;
    ++ top;
    stk[top] = x;
    ins[x] = true;
    for (int i = head[x]; i != -1; i = nxt[i]) {
        int e = to[i];
        if (dfn[e] == 0) {
            dfsearch(e);
            low[x] = std::min(low[x], low[e]);
        } else if (ins[e]) {
            low[x] = std::min(low[x], dfn[e]);
        }
    }
    if (dfn[x] == low[x]) {
        ++ scc_cnt;
        int y, large = 0;
        do {
            y = stk[top];
            -- top;
            ins[y] = false;
            ++ large;
        } while (y != x);
        if (large > 1) {
            ++ ans;
        }
    }
    return;
}

int main(void) {
    scanf("%d", &t);
    while (t --) {
        scanf("%d%d", &n, &m);
        init(n);
        for (int i = 1, inpu, inpv; i <= m; ++ i) {
            scanf("%d%d", &inpu, &inpv);
            add(inpu, inpv);
        }
        for (int i = 1; i <= n; ++ i) {
            if (dfn[i] == 0) {
                dfsearch(i);
            }
        }
        printf("%d\n", ans);
    }

    return 0;
}