#include <iostream>
#include <set>
using namespace std;

/*
Idea general:
    Una vez cargado el terreno en una matriz tridimensional, por cada casillero que corresponde a un mineral,
realizo un recorrido en profundidad (dfs) por sus casillas adyacentes contando la cantidad de casilleros
que forman el grupo y desmarcandolas con el caracter '*' de material sin interes.
    Estas cantidades deben ser mostradas de mayor a menor por cada material, por eso la estructura mas conve
niente para almacenar estos valores enteros es el multiset<int> que permite valores repetidos e iterando sobre
sus elementos accedemos ordenadamente a estos.
*/

int p,k,m;
char terreno[50][50][50];

//un arreglo de 4 multisets, uno por cada material ('a','b','c','d')
multiset<int> resultados[4];

/*dfs es una funcion recursiva que recorre la matriz terreno en profundidad por los casilleros que comparten
el mismo valor de material, retornando la cantidad de casilleros y desmarcandolos para que no se vuelva a pasar
por ellos.*/
int dfs(int x,int y,int z);

int main(){
    //las siguientes variables se necesitan por cuestiones de presentacion:
    int numcaso=0;
    bool primero=true;

    while(cin>>p>>k>>m){

        //las siguientes sentencias se necesitan por cuestiones de presentacion:
        if(!primero)
            cout<<endl;
        else
            primero=false;
        numcaso++;

        //entrada (se carga el terreno):
        for(int z=0;z<m;z++)
            for(int y=0;y<p;y++)
                for(int x=0;x<k;x++)
                    cin>>terreno[x][y][z];

        //proceso:
        for(int i=0;i<4;i++)
            resultados[i].clear();
        for(int z=0;z<m;z++)
            for(int y=0;y<p;y++)
                for(int x=0;x<k;x++){
                    if(terreno[x][y][z]!='*'){
                        char aux=terreno[x][y][z]-97;
                        resultados[aux].insert(dfs(x,y,z));
                    }
                }

        //salida:
        cout<<"Case "<<numcaso<<":"<<endl;
        for(char a='a';a<='d';a++){
            cout<<a;
            if(resultados[a-97].empty())
                cout<<" 0";
            else
                for(multiset<int>::reverse_iterator it=resultados[a-97].rbegin();it!=resultados[a-97].rend();it++)
                    cout<<" "<<*it;
            cout<<endl;
        }
    }
    return 0;
};

int dfs(int x,int y,int z){
    char aux=terreno[x][y][z];
    terreno[x][y][z]='*';
    int suma=1;
    if(x-1>=0 && aux==terreno[x-1][y][z])
        suma+=dfs(x-1,y,z);
    if(y-1>=0 && aux==terreno[x][y-1][z])
        suma+=dfs(x,y-1,z);
    if(x-1>=0 && aux==terreno[x][y][z-1])
        suma+=dfs(x,y,z-1);
    if(x+1<k && aux==terreno[x+1][y][z])
        suma+=dfs(x+1,y,z);
    if(y+1<p && aux==terreno[x][y+1][z])
        suma+=dfs(x,y+1,z);
    if(z+1<m && aux==terreno[x][y][z+1])
        suma+=dfs(x,y,z+1);
    return suma;
};

