#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
const long long OO = 1e7 ;
const long long mod = 1e9 + 7 ;
const long double EPS = ( 1e-18 ) ;
int dcmp( long double x, long double y) { return fabs ( x - y) <= EPS ? 0 : x < y ? - 1 : 1 ; }
int dx[ ] = { 0 , 0 , 1 , - 1 , 1 , 1 , - 1 , - 1 } ;
int dy[ ] = { 1 , - 1 , 0 , 0 , - 1 , 1 , 1 , - 1 } ;
void fast( ) {
#ifndef ONLINE_JUDGE
freopen ( "F:\\ solving\\ input.txt" , "r" , stdin ) ;
freopen ( "F:\\ solving\\ output.txt" , "w" , stdout ) ;
#endif
freopen ( "maze.in" , "r" , stdin ) ;
std:: ios_base :: sync_with_stdio ( 0 ) ;
cin .tie ( NULL ) ; cout .tie ( NULL ) ;
}
const long long MAX = 100 * 1000 + 1 ;
int n, m;
int X[ 4 ] , Y[ 4 ] ;
int level[ 501 ] [ 501 ] [ ( 1 << 4 ) ] ;
char g[ 501 ] [ 501 ] ;
string s = "abc" ;
string w = "ABC" ;
map < pair< int , int > , int > mp;
bool isv( int i, int j , int mask) {
if ( i >= 0 && i < n&& j >= 0 && j < m) {
if ( g[ i] [ j] == 'A' && ( mask & 1 ) == 0 )
return 0 ;
if ( g[ i] [ j] == 'B' && ( mask & 1 << 1 ) == 0 )
return 0 ;
if ( g[ i] [ j] == 'C' && ( mask & 1 << 2 ) == 0 )
return 0 ;
return 1 ;
}
return 0 ;
}
int bfs( int i, int j ) {
memset ( level, - 1 , sizeof level) ;
queue< pair< int , pair< int , int > > > q;
q.push ( { 0 ,{ i, j } } ) ;
level[ i] [ j] [ 0 ] = 0 ;
while ( q.size ( ) > 0 ) {
auto cur = q.front ( ) ;
q.pop ( ) ;
if ( g[ cur.second .first ] [ cur.second .second ] == 'E' )
return level[ cur.second .first ] [ cur.second .second ] [ cur.first ] ;
for ( int d = 0 ; d < 4 ; d++ ) {
int ii = dx[ d] + cur.second .first , jj = dy[ d] + cur.second .second ;
if ( isv( ii, jj , cur.first ) && level[ ii] [ jj] [ cur.first ] == - 1 ) {
int tmp = cur.first ;
if ( g[ ii] [ jj] == 'a' ) {
tmp | = ( 1 << 0 ) ;
}
else if ( g[ ii] [ jj] == 'b' ) {
tmp | = ( 1 << 1 ) ;
}
else if ( g[ ii] [ jj] == 'c' ) {
tmp | = ( 1 << 2 ) ;
}
q.push ( { tmp, { ii, jj } } ) ;
level[ ii] [ jj] [ tmp] = level[ cur.second .first ] [ cur.second .second ] [ cur.first ] + 1 ;
}
}
}
return - 1 ;
}
int main( ) {
fast( ) ;
int t; cin >> t;
while ( t-- ) {
memset ( X, - 1 , sizeof X) ;
memset ( Y, - 1 , sizeof Y) ;
cin >> n >> m;
mp.clear ( ) ;
for ( int i = 0 ; i < n; i++ ) {
for ( int j = 0 ; j < m; j++ ) {
cin >> g[ i] [ j] ;
if ( g[ i] [ j] == 'S' ) {
X[ 0 ] = i, Y[ 0 ] = j;
}
}
}
int ret = bfs( X[ 0 ] , Y[ 0 ] ) ;
cout << ret << endl;
}
return 0 ;
}
I2RlZmluZSBfQ1JUX1NFQ1VSRV9OT19XQVJOSU5HUwojaW5jbHVkZTxiaXRzL3N0ZGMrKy5oPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKY29uc3QgbG9uZyBsb25nIE9PID0gMWU3Owpjb25zdCBsb25nIGxvbmcgbW9kID0gMWU5ICsgNzsKY29uc3QgbG9uZyBkb3VibGUgRVBTID0gKDFlLTE4KTsKaW50IGRjbXAobG9uZyBkb3VibGUgeCwgbG9uZyBkb3VibGUgeSkgeyByZXR1cm4gZmFicyh4IC0geSkgPD0gRVBTID8gMCA6IHggPCB5ID8gLTEgOiAxOyB9CgppbnQgZHhbXSA9IHsgMCwgMCwgMSwgLTEsIDEsIDEsIC0xLCAtMSB9OwppbnQgZHlbXSA9IHsgMSwgLTEsIDAsIDAsIC0xLCAxLCAxLCAtMSB9OwoKCnZvaWQgZmFzdCgpewojaWZuZGVmIE9OTElORV9KVURHRQoJZnJlb3BlbigiRjpcXHNvbHZpbmdcXGlucHV0LnR4dCIsICJyIiwgc3RkaW4pOwoJZnJlb3BlbigiRjpcXHNvbHZpbmdcXG91dHB1dC50eHQiLCAidyIsIHN0ZG91dCk7CgojZW5kaWYKCWZyZW9wZW4oIm1hemUuaW4iLCAiciIsIHN0ZGluKTsKCXN0ZDo6aW9zX2Jhc2U6OnN5bmNfd2l0aF9zdGRpbygwKTsKCWNpbi50aWUoTlVMTCk7IGNvdXQudGllKE5VTEwpOwp9CmNvbnN0IGxvbmcgbG9uZyBNQVggPSAgMTAwICogMTAwMCArIDE7CmludCBuLCBtOwoKaW50IFhbNF0sIFlbNF07CmludCBsZXZlbFs1MDFdWzUwMV1bKDE8PDQpXTsKY2hhciBnWzUwMV1bNTAxXTsKc3RyaW5nIHMgPSAiYWJjIjsKc3RyaW5nIHcgPSAiQUJDIjsKbWFwIDwgIHBhaXI8IGludCwgaW50PiAsIGludCA+IG1wOwoKYm9vbCBpc3YoaW50IGksIGludCBqICwgaW50IG1hc2spewoJaWYgKGkgPj0gMCAmJiBpIDwgbiYmaiA+PSAwICYmIGogPCBtKXsKCQlpZiAoZ1tpXVtqXSA9PSAnQScgJiYgKG1hc2sgJiAxKSA9PSAwKQoJCQlyZXR1cm4gMDsgCgkJaWYgKGdbaV1bal0gPT0gJ0InICYmIChtYXNrICYgMSA8PCAxKSA9PSAwKQoJCQlyZXR1cm4gMDsKCQlpZiAoZ1tpXVtqXSA9PSAnQycgJiYgKG1hc2sgJiAxIDw8IDIpID09IDApCgkJCXJldHVybiAwOwoJCXJldHVybiAxOwoJfQoJcmV0dXJuIDA7Cn0KaW50IGJmcyhpbnQgaSwgaW50IGogKXsKCW1lbXNldChsZXZlbCwgLTEsIHNpemVvZiBsZXZlbCk7CgoJcXVldWU8cGFpcjwgaW50LCBwYWlyPCBpbnQsIGludD4gPiA+cTsKCXEucHVzaCh7IDAgLHsgaSwgaiB9IH0pOwoJbGV2ZWxbaV1bal1bMF0gPSAwOwoJd2hpbGUgKHEuc2l6ZSgpID4gMCl7CgkJYXV0byBjdXIgPSBxLmZyb250KCk7CgkJcS5wb3AoKTsKCgkJaWYgKGdbY3VyLnNlY29uZC5maXJzdF1bY3VyLnNlY29uZC5zZWNvbmRdID09ICdFJykKCQkJcmV0dXJuIGxldmVsW2N1ci5zZWNvbmQuZmlyc3RdW2N1ci5zZWNvbmQuc2Vjb25kXVtjdXIuZmlyc3RdOwoJCWZvciAoaW50IGQgPSAwOyBkIDwgNDsgZCsrKXsKCQkJaW50IGlpID0gZHhbZF0gKyBjdXIuc2Vjb25kLmZpcnN0LCBqaiA9IGR5W2RdICsgY3VyLnNlY29uZC5zZWNvbmQ7CgoJCQoJCQlpZiAoaXN2KGlpLCBqaiAsIGN1ci5maXJzdCkgJiYgbGV2ZWxbaWldW2pqXVtjdXIuZmlyc3RdID09IC0xKXsKCQkJCWludCB0bXAgPSBjdXIuZmlyc3Q7CgkJCQlpZiAoZ1tpaV1bampdID09ICdhJyl7CgkJCQkJdG1wIHw9ICgxIDw8IDApOwoJCQkJfQoJCQkJZWxzZSBpZiAoZ1tpaV1bampdID09ICdiJyl7CgkJCQkJdG1wIHw9ICgxIDw8IDEpOwoJCQkJfQoJCQkJZWxzZSBpZiAoZ1tpaV1bampdID09ICdjJyl7CgkJCQkJdG1wIHw9ICgxIDw8IDIpOwoJCQkJfQoJCQkJcS5wdXNoKHsgdG1wLCB7IGlpLCBqaiB9IH0pOwoJCQkJbGV2ZWxbaWldW2pqXVt0bXBdID0gbGV2ZWxbY3VyLnNlY29uZC5maXJzdF1bY3VyLnNlY29uZC5zZWNvbmRdW2N1ci5maXJzdF0gKyAxOwoJCQl9CgkJfQoJfQoJcmV0dXJuIC0xOwp9CmludCBtYWluKCl7CglmYXN0KCk7CglpbnQgdDsgY2luID4+IHQ7Cgl3aGlsZSAodC0tKXsKCQltZW1zZXQoWCwgLTEsIHNpemVvZiBYKTsKCQltZW1zZXQoWSwgLTEsIHNpemVvZiBZKTsKCgkJY2luID4+IG4gPj4gbTsKCQltcC5jbGVhcigpOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKXsKCQkJZm9yIChpbnQgaiA9IDA7IGogPCBtOyBqKyspewoJCQkJY2luID4+IGdbaV1bal07CgkJCQlpZiAoZ1tpXVtqXSA9PSAnUycpewoJCQkJCVhbMF0gPSBpLCBZWzBdID0gajsKCQkJCX0KCQkJfQoJCX0KCQlpbnQgcmV0ID0gYmZzKFhbMF0sIFlbMF0pOwoKCQljb3V0IDw8IHJldCA8PCBlbmRsOwoJfQoJcmV0dXJuIDA7Cn0=