#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<stack>
#include<math.h>
#include<map>
using namespace std;
const int maxn = 115;
const int inf = 9999999;
char mat[ maxn ][ maxn ];
int vis[ maxn ][ maxn ][ 2 ][ 2 ];
const int dx[]={1,-1,0,0};
const int dy[]={0,0,1,-1};
struct Pos{
	int x,y;
};
struct Node{
	int x,y,ti;
	int D,E;//flag
};
Pos D,S,E;
void init(){
	for( int i=0;i<maxn;i++ )
		for( int j=0;j<maxn;j++ )
			mat[i][j] = 'X';
}

bool in( Node p,int n,int m ){
	if( p.x>=0&&p.x<n&&p.y>=0&&p.y<m )
		return true;
	else
		return false;
}
bool Judge1( Node tmp ){
	int x = tmp.x;
	int y1 = min( tmp.y,D.y );
	int y2 = max( tmp.y,D.y );
	for( int i=y1+1;i<y2;i++ ){
		if( mat[x][i]=='X' ) return false;
		else if( mat[x][i]=='.' ){
			if( x==D.x&&i==D.y ) return false;
			else if( x==E.x&&i==E.y ) return false;
		}
	}
	return true;
}
bool Judge2( Node tmp ){
	int x = tmp.x;
	int y1 = min( tmp.y,E.y );
	int y2 = max( tmp.y,E.y );
	for( int i=y1+1;i<y2;i++ ){
		if( mat[x][i]=='X' ) return false;
		else if( mat[x][i]=='.' ){
			if( x==D.x&&i==D.y ) return false;
			else if( x==E.x&&i==E.y ) return false;
		}
	}
	return true;
}
bool Judge3( Node tmp ){
	int y = tmp.y;
	int x1 = min( tmp.x,D.x );
	int x2 = max( tmp.x,D.x );
	for( int i=x1+1;i<x2;i++ ){
		if( mat[i][y]=='X' ) return false;
		else if( mat[i][y]=='.' ){
			if( i==D.x&&y==D.y ) return false;
			else if( i==E.x&&y==E.y ) return false;
		}
	}
	return true;
}
bool Judge4( Node tmp ){
	int y = tmp.y;
	int x1 = min( tmp.x,E.x );
	int x2 = max( tmp.x,E.x );
	for( int i=x1+1;i<x2;i++ ){
		if( mat[i][y]=='X' ) return false;
		else if( mat[i][y]=='.' ){
			if( i==D.x&&y==D.y ) return false;
			else if( i==E.x&&y==E.y ) return false;
		}
	}
	return true;
}

int bfs( int n,int m,int aim_ti ){
	Node cur,nxt;
	cur.x = S.x;
	cur.y = S.y;
	cur.ti = 0;
	cur.D = cur.E = 0;
	queue<Node>q;
	while( !q.empty() )
		q.pop();
	q.push( cur );
	int ans = inf;
	vis[ cur.x ][ cur.y ][ cur.D ][ cur.E ] = 1;
	while( !q.empty() ){
		cur = q.front();
		q.pop();
		if( cur.ti>aim_ti ) continue;
		//printf("cur:x=%d,y=%d,ti=%d\n",cur.x,cur.y,cur.ti);
		if( cur.x==D.x&&Judge1( cur )==true ) cur.D = 1;
		if( cur.x==E.x&&Judge2( cur )==true ) cur.E = 1;
		if( cur.y==D.y&&Judge3( cur )==true ) cur.D = 1;
		if( cur.y==E.y&&Judge4( cur )==true ) cur.E = 1;
		if( cur.D==1 ) {
			if( cur.E==1 ){
				if( ans>cur.ti ){
					ans = cur.ti;
				}
			}
		}
			//printf("ans:%d\n",ans);
		for( int i=0;i<4;i++ ){
			nxt = cur;
			nxt.x+=dx[i];
			nxt.y+=dy[i];
			nxt.ti++;
			if( in( nxt,n,m )==true&&mat[nxt.x][nxt.y]!='X'&&vis[nxt.x][nxt.y][nxt.D][nxt.E]==0 ){
				vis[nxt.x][nxt.y][nxt.D][nxt.E] = 1;
				q.push(nxt);
			}
		}
	}
	if( ans>aim_ti ) return -1;
	else return ans;
}

int main(){
	int ca,T;
	scanf("%d",&ca);
	T = 1;
	while( ca-- ){
		int n,m,aim_ti;
		printf("Case %d:\n",T++);
		init();
		scanf("%d%d%d",&n,&m,&aim_ti);
		for( int i=0;i<n;i++ ){
			scanf("%s",mat[i]);
			for( int j=0;j<m;j++ ){
				if( mat[i][j]=='D' ){
					D.x = i;
					D.y = j;
					mat[i][j]='X';
				}
				else if( mat[i][j]=='S' ){
					S.x = i;
					S.y = j;
					mat[i][j]='.';
				}
				else if( mat[i][j]=='E' ){
					E.x = i;
					E.y = j;
					mat[i][j]='X';
				}
			}
		}
		memset( vis,0,sizeof( vis ) );
		int ans = bfs( n,m,aim_ti );
		printf("%d\n",ans);
	}
	return 0;
}



HDU4528+BFS_JAVA