#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAXN 50
char map[MAXN][MAXN];
int parent[252];
bool visited[MAXN][MAXN];
int N,M;
int num[MAXN][MAXN];
struct node{
int u;
int v;
int w;
bool operator < (const node& a) const{
return w < a.w;
};
};
vector<node> adj;
vector<pair<int,int> > coord;
int dx[] = {0,0,1,-1};
int dy[] = {1,-1,0,0};
int find(int x){
if (x == parent[x]) return x;
return parent[x] = find(parent[x]);
}
bool merge(int u, int v){
u = find(u);
v = find(v);
if (u == v) return false;
parent[u] = v;
return true;
}
bool bfs(int start){
queue<pair<int,int> > q;
memset(visited,false,sizeof(visited));
bool flag = false;
q.push(coord[start]);
visited[coord[start].first][coord[start].second] = true;
int cnt = 0;
while (!q.empty()){
int q_size = q.size();
while (q_size--){
int x = q.front().first;
int y = q.front().second;
q.pop();
for (int k =0 ;k<4 ;k++){
int nx = x+ dx[k];
int ny = y + dy[k];
if (nx < 0 || ny < 0 || nx>=N || ny>=N) continue;
if (map[nx][ny] == '1' || visited[nx][ny]) continue;
visited[nx][ny] = true;
if (map[nx][ny] == 'K'){
adj.push_back({start,num[nx][ny],cnt+1});
flag = true;
}
else{
q.push({nx,ny});
}
}
}
cnt++;
}
return flag;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin >> N >> M;
int idx = 0;
for (int i =0 ;i<N;i++){
for (int j=0;j<N;j++){
cin >> map[i][j];
if (map[i][j] == 'S' || map[i][j] == 'K'){
if (map[i][j] == 'S') map[i][j] = 'K';
num[i][j] = idx++;
coord.push_back({i,j});
}
}
}
for (int i = 0 ;i < coord.size(); i++){
if (!bfs(i)){
cout << "-1\n";
return 0;
}
}
sort(adj.begin(),adj.end());
for (int i = 0 ;i < idx; i++){
parent[i] = i;
}
int ans = 0;
for (int i = 0 ; i < adj.size(); i++){
if (merge(adj[i].u,adj[i].v)){
ans += adj[i].w;
}
}
cout << ans <<"\n";
return 0;
}