#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
#define INF 987654321
#define MAXN 50
char map[MAXN][MAXN];
struct node{
int x;
int y;
int dir;
bool flag1;
bool flag2;
};
int dist[MAXN][MAXN][4][2][2];
int N,M;
queue<node> q;
pair<int,int> s;
int dx[] = {0,0,1,-1};
int dy[] = {1,-1,0,0};
bool flag[2];
int bfs(){
q.push({s.first,s.second,-1});
int ans = 0;
while (!q.empty()){
int x= q.front().x;
int y = q.front().y;
int cur_dir = q.front().dir;
bool flag1 = q.front().flag1;
bool flag2 = q.front().flag2;
int cur_dist;
if (cur_dir!=-1){
cur_dist = dist[x][y][cur_dir][flag1][flag2];
}
if (flag1 && flag2) return dist[x][y][cur_dir][flag1][flag2];
q.pop();
for (int k = 0; k < 4; k++){
if (cur_dir != -1 && cur_dir == k) continue;
int nx = x + dx[k];
int ny = y + dy[k];
bool n_flag1 = flag1;
bool n_flag2 = flag2;
if (nx < 0 || ny < 0 || nx>=N || ny>=M) continue;
if (dist[nx][ny][k][flag1][flag2] != -1 || map[nx][ny] == '#') continue;
if (map[nx][ny] == 'K'){
n_flag1 = true;
}
else if (map[nx][ny] == 'C') n_flag2 = true;
if (cur_dir == -1) dist[nx][ny][k][n_flag1][n_flag2] = 1;
else dist[nx][ny][k][n_flag1][n_flag2] = cur_dist + 1;
q.push({nx,ny,k,n_flag1,n_flag2});
}
}
return -1;
}
int main(){
bool b = false;
ios::sync_with_stdio(false);
cin.tie(0);
cin >> N >> M;
memset(dist,-1,sizeof(dist));
for (int i = 0 ;i <N; i++){
for (int j = 0;j <M;j++){
cin >> map[i][j];
if (map[i][j] == 'C'){
if (!b) {
b = true;
map[i][j] = 'K';
}
}
else if (map[i][j] == 'S'){
s = {i,j};
}
}
}
cout << bfs() <<"\n";
return 0;
}