/****************************************************************
▄█ █▄ ▄████████ ▄████████ ▄█ ▀█████████▄
███ ███ ███ ███ ███ ███ ███ ███ ███
███ ███ ███ ███ ███ █▀ ███ ███ ███
▄███▄▄▄▄███▄▄ ███ ███ ███ ███ ▄███▄▄▄██▀
▀▀███▀▀▀▀███▀ ▀███████████ ▀███████████ ███ ▀▀███▀▀▀██▄
███ ███ ███ ███ ███ ███ ███ ██▄
███ ███ ███ ███ ▄█ ███ ███ ███ ███
███ █▀ ███ █▀ ▄████████▀ █▀ ▄█████████▀
****************************************************************/
#include<bits/stdc++.h>
#define FOR(i, s, e) for(int i=s; i<e; i++)
#define loop(i, n) FOR(i, 0, n)
#define sf scanf
#define pf printf
#define pb push_back
#define MP make_pair
#define fr first
#define sc second
#define ll long long
#define dd double
#define all(v) v.begin(), v.end()
#define PI acos(-1.0)
#define mem(ara, value) memset(ara, value, sizeof(ara))
#define paii pair<int, int>
#define pall pair<ll, ll>
#define SZ(a) int(a.size())
#define read(nm) freopen(nm, "r", stdin)
#define write(nm) freopen(nm, "w", stdout)
#define take(args...) asdf,args
#define dump(x) cerr<<#x<<" = "<<x<<endl
#define debug(args...) cerr,args; cerr<<endl;
using namespace std;
template<typename T>
ostream& operator<<(ostream& output, vector<T>&v)
{
output<<"[ ";
if(SZ(v))
{
output<<v[0];
}
FOR(i, 1, SZ(v))
{
output<<", "<<v[i];
}
output<<" ]";
return output;
}
template<typename T1, typename T2>
ostream& operator<<(ostream& output, pair<T1, T2>&p)
{
output<<"( "<<p.fr<<", "<<p.sc<<" )";
return output;
}
template<typename T>
ostream& operator,(ostream& output, T x)
{
output<<x<<" ";
return output;
}
struct ASDF{
ASDF& operator,(int &a) {
sf("%d", &a);
return *this;
}
ASDF& operator,(long int &a){
sf("%ld", &a);
return *this;
}
ASDF& operator,(long long int &a){
sf("%lld", &a);
return *this;
}
ASDF& operator,(char &c){
sf("%c", &c);
return *this;
}
ASDF& operator,(double &d){
sf("%lf", &d);
return *this;
}
template<typename T>
ASDF& operator,(T &a){
cin>>a;
return *this;
}
}asdf;
//Header ends here
#define MAXX 10007
vector<int>graph[MAXX];
int n, m;
map<int, map<int, int> > isBridge;
bool visited[MAXX];
int low[MAXX], disc[MAXX];
int parent[MAXX];
int t;
vector<paii>bridges;
int cnt[MAXX];
void dfs_bridge(int u)
{
visited[u] = true;
low[u] = disc[u] = ++t;
loop(i, SZ(graph[u]))
{
int v = graph[u][i];
if( ! visited[v])
{
parent[v] = u;
dfs_bridge(v);
low[u] = min(low[u], low[v]);
if(low[v] > disc[u] )
{
bridges.pb(MP(u, v));
isBridge[u][v] = isBridge[v][u] = 1;
}
}
else if( v != parent[u])
{
low[u] = min(low[u], disc[v]);
}
}
}
int find(int u)
{
if(u == parent[u]) return u;
else return parent[u] = find(parent[u]);
}
int main()
{
int kases, kaseno = 0;
take(kases);
while(kases--)
{
loop(i, MAXX) graph[i].clear();
isBridge.clear();
take(n, m);
int u, v;
loop(i, m)
{
take(u, v);
graph[u].pb(v);
graph[v].pb(u);
}
mem(visited, 0);
mem(parent, -1);
t = 0;
bridges.clear();
loop(i, n)
{
if(!visited[i])
{
dfs_bridge(i);
}
}
loop(i, n)
{
parent[i] = i;
}
loop(i, n)
{
loop(j, SZ(graph[i]))
{
int v = graph[i][j];
if(isBridge[i][v] != 1)
{
//cerr<<"i is "<<i<<" and v = "<<v<<" "<<isBridge[u][v]<<endl;
int u = find(i);
v = find(v);
if( u != v)
{
parent[u] = v;
//cerr<<"connecting "<<u<<" and "<<v<<endl;
}
}
else
{
//dump(u); dump(v);
//cerr<<"here"<<endl;
}
}
}
mem(cnt, 0);
loop(i, SZ(bridges))
{
int u = bridges[i].fr, v = bridges[i].sc;
u = find(u);
v = find(v);
//dump(u); dump(v);
cnt[u]++;
cnt[v]++;
}
int ret = 0;
loop(i, n)
{
if(cnt[i] == 1)
{
ret++;
}
}
//ret = count of leaf
ret = (ret + 1)/2;
pf("Case %d: %d\n", ++kaseno, ret);
}
}