#include <bits/stdc++.h>
using namespace std;
const int maxn = 450;
struct N{
long long point;
int _set;
long long id;
}x[maxn],y[maxn];
long long Vx[maxn],Vy[maxn];
bool vis[maxn][maxn];
bool cmpPoint(const N &A,const N &B){
return A.point < B.point;
}
bool cmpId(const N &A,const N &B){
return A.id < B.id;
}
void Discrete(int n,N *p,int &border,long long *V){
p[n+1].id = n+1 , p[n+1].point = border;
p[0].id = 0 , p[0].point = 1;
sort(p+1,p+n+1,cmpPoint);
int index = 1;
V[1] = 1;
for(int i=1;i<=n+1;i++){
if(p[i].point == p[i-1].point){
p[i]._set = index;
}
else if(p[i].point - p[i-1].point == 1){
p[i]._set = ++index;
V[index] = 1;
}
else{
p[i]._set = index + 2;
V[index + 2] = 1;
V[index + 1] = p[i].point - p[i-1].point - 1;
index += 2;
}
}
border = index;
sort(p+1,p+n+1,cmpId);
}
long long dfs(int sx,int sy,int R,int C){
long long sum = Vx[sx] * Vy[sy];
vis[sx][sy] = true;
for(int i=-1;i<=1;i++){
for(int j=-1;j<=1;j++){
if(i&&j) continue;
int nx = sx + i;
int ny = sy + j;
if(!vis[nx][ny] && nx>0 && ny>0 && nx<=R && ny<=C){
sum += dfs(nx,ny,R,C);
}
}
}
return sum;
}
int main()
{
ios::sync_with_stdio(false);
int T,cnt=0;
cin>>T;
while(T--){
int R,C;
cin>>R>>C;
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>x[i].point>>y[i].point;
x[i].id = y[i].id = i;
}
Discrete(n,x,R,Vx);
Discrete(n,y,C,Vy);
long long ans[maxn];
memset(ans,0,sizeof(ans));
memset(vis,false,sizeof(vis));
for(int i=1;i<=n;i++) vis[ x[i]._set ][ y[i]._set ] = true;
int index = 0;
for(int i=1;i<=R;i++){
for(int j=1;j<=C;j++){
if(!vis[i][j]) ans[index++] = dfs(i,j,R,C);
}
}
sort(ans,ans+index);
cout<<"Case #"<<++cnt<<":"<<endl;
cout<<index<<endl;
for(int i=0;i<index;i++)
cout<<ans[i]<<(i == index-1 ? "\n":" ");
}
return 0;
}