#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; #define maxn 5005 #define maxm 40005 struct Edge { int v, next; } edge[maxm]; int n, m; int head[maxn]; int ecount, tcount; int dfn[maxn], vis[maxn], low[maxn], ans1,degree[maxn],vis1[maxn]; void addedge(int a, int b) { edge[ecount].v = b; edge[ecount].next = head[a]; head[a] = ecount; //hash[a][b] = hash[b][a] = true; ecount++; } void input() { memset(head, -1, sizeof(head)); memset(vis1,0,sizeof(vis1)); ecount = 0; int i,j; ans1=0; scanf("%d%d", &n, &m); for (i = 0; i < m; i++) { int a, b; scanf("%d%d", &a, &b); a--; b--; vis[a]=vis[b]=1; addedge(a, b); addedge(b, a); } for(i=0;i<n;i++) { if(!vis[i]) { ans1++; } } } void dfs(int fa, int u) { vis[u] = true; low[u] = dfn[u] = tcount++; for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].v; if (v == fa) continue; if (!vis[v]) dfs(u, v); low[u] = min(low[u], low[v]); } } int tarjan() { memset(dfn, 0, sizeof(dfn)); memset(vis, 0, sizeof(vis)); memset(degree, 0, sizeof(degree)); tcount = 0; dfs(0, 0); int ret = 0; for (int i = 0; i < n; i++) for (int j = head[i]; j != -1; j = edge[j].next) { int v = edge[j].v; if (low[i] != low[v]) degree[low[i]]++; } for (int i = 0; i < n; i++) if (degree[i] == 1) ret++; ret=(ret+1)/2; if(ret)ret+=ans1; else ret=ans1+(ans1?1:0); return ret; } int main() { //freopen("t.txt", "r", stdin); int t; cin>>t; while(t--) { input(); int ans=0; ans = tarjan(); printf("%d\n", ans); } return 0; }