Problem:
問題文
キュゥべえ
はなかなか契約を結んでくれない
鹿目まどか
にしびれを切らせて，ソウルジェムゲームと称して
佐倉杏子
と
美樹さやか
のソウルジェムの中身 (魂) を
W
列
H
段のロッカーの中に隠してしまった．そこで，
まどか
は
杏子
と
さやか
を助け出したい．しかし，契約を結ばずに助けるにはロッカーボックスの壁を操作して
2
人のソウルジェムの中身を，指定されたロッカーボックスに正しく移さなければならない．ロッカーはロッカーボックスが
W
列
H
段に並ぶことで構成され，隣り合うロッカーボックスは壁で仕切られている．
まどか
は，
1
回の操作でいずれかの隣りあった
2
つのロッカーボックスの壁を取り除くか取り付けることができる．ただし，ロッカーボックスの壁を開けるには制約があり，各ロッカーボックスから隣接する上下左右の壁のうち，高々
2
枚までの壁しか同時に開けておくことはできない．ロッカーボックスには上の段から下の段に向かって重力が働いている．ソウルジェムの中身は液体と同じような動きをし，隣りあった
2
つのロッカーボックスの壁が取り除かれている時，同じ高さであれば互いに同じ量になり，違う高さであれば低い方へ移動する．すべての操作が終わった時に指定された
2
つのロッカーボックスに正しい組み合わせでソウルジェムの中身がすべて入っていれば
まどか
の勝利となる．また，一部のロッカーボックスは穢れており，その中へソウルジェムの中身が入ってしまうと大変なことになってしまうので，そのロッカーボックスはソウルジェムの中身の移動のために使うことはできない．
最小で何度の操作を行えば
まどか
は
2
人を救いだすことができるかを求めよ．
入力形式
入力は以下の形式で与えられる．
H\ W\\
s_{11}\ s_{12}\ … s_{1W}\\
s_{21}\ s_{22}\ … s_{2W}\\
…\\
s_{H1}\ s_{H2}\ … s_{HW}\\
H
はロッカーの段数，
W
はロッカーの列数である．
s_{ij}
は上から
i
段目の左から
j
列目のロッカーボックスの状態を表す．
杏子
のソウルジェムの中身が入っているときは
'K'
であり，
さやか
のソウルジェムの中身が入っているときは
'S'
，
杏子
のソウルジェムの中身を移すべきロッカーボックスであるときは
'k'
，
さやか
のソウルジェムの中身を移すべきロッカーボックスであるときは
's'
，穢れたロッカーボックスであるときは
'#'
，それ以外のロッカーボックスであるときは
'.'
である．
出力形式
2
人を救い出すために必要な操作の最小回数を出力せよ．どのように操作しても救い出すことが出来ない場合は
CONTRACT
と出力せよ．
制約
1 ≤ H ≤ 10
1 ≤ W ≤ 10
s_{ij}
は
'#'
,
'.'
,
'S'
,
'K'
,
's'
,
'k'
のいずれかである．
s_{ij}\ =\
'S'
であるような
i, j
がちょうど 1 つだけ存在する．
s_{ij}\ =\
'K'
であるような
i, j
がちょうど 1 つだけ存在する．
s_{ij}\ =\
's'
であるような
i, j
がちょうど 1 つだけ存在する．
s_{ij}\ =\
'k'
であるような
i, j
がちょうど 1 つだけ存在する．
入出力例
入力例 1
4 4
.S..
K...
....
..sk
出力例1
9
入力例 2
5 5
.S.K.
..#..
.###.
..#..
.k.s.
出力例 2
CONTRACT
入力例 3
8 5
S....
####K
##...
#..##
#..##
##k##
#...#
#.s.#
出力例 3
19
入力例 4
8 5
S....
####K
##...
##.##
##.##
##k##
#...#
#.s.#
出力例 4
CONTRACT
入力例 5
10 10
..........
##......##
#K......S#
..........
..........
.#..##..#.
..##..##..
..........
..........
....s.k...
出力例 5
22
入力例 6
3 3
S.s
K..
..k
出力例 6
CONTRACT
Problem Setter: Flat35

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using uint = unsigned int;
using ull = unsigned long long;
#define rep(i,n) for(int i=0;i<int(n);i++)
#define rep1(i,n) for(int i=1;i<=int(n);i++)
#define per(i,n) for(int i=int(n)-1;i>=0;i--)
#define per1(i,n) for(int i=int(n);i>0;i--)
#define all(c) c.begin(),c.end()
#define si(x) int(x.size())
#define pb push_back
#define eb emplace_back
#define fs first
#define sc second
template<class T> using V = vector<T>;
template<class T> using VV = vector<vector<T>>;
template<class T,class U> bool chmax(T& x, U y){
	if(x<y){ x=y; return true; }
	return false;
}
template<class T,class U> bool chmin(T& x, U y){
	if(y<x){ x=y; return true; }
	return false;
}
template<class T> void mkuni(V<T>& v){sort(all(v));v.erase(unique(all(v)),v.end());}
template<class T> int lwb(const V<T>& v, const T& a){return lower_bound(all(v),a) - v.begin();}
template<class T>
V<T> Vec(size_t a) {
    return V<T>(a);
}
template<class T, class... Ts>
auto Vec(size_t a, Ts... ts) {
  return V<decltype(Vec<T>(ts...))>(a, Vec<T>(ts...));
}
template<class S,class T> ostream& operator<<(ostream& o,const pair<S,T> &p){
	return o<<"("<<p.fs<<","<<p.sc<<")";
}
template<class T> ostream& operator<<(ostream& o,const vector<T> &vc){
	o<<"{";
	for(const T& v:vc) o<<v<<",";
	o<<"}";
	return o;
}
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n-1); }

#ifdef LOCAL
#define show(x) cerr << "LINE" << __LINE__ << " : " << #x << " = " << (x) << endl
void dmpr(ostream& os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
	os<<t<<" ~ ";
	dmpr(os,args...);
}
#define shows(...) cerr << "LINE" << __LINE__ << " : ";dmpr(cerr,##__VA_ARGS__)
#define dump(x) cerr << "LINE" << __LINE__ << " : " << #x << " = {";  \
	for(auto v: x) cerr << v << ","; cerr << "}" << endl;
#else
#define show(x) void(0)
#define dump(x) void(0)
#define shows(...) void(0)
#endif

template<class D> D divFloor(D a, D b){
	return a / b - (((a ^ b) < 0 && a % b != 0) ? 1 : 0);
}
template<class D> D divCeil(D a, D b) {
	return a / b + (((a ^ b) > 0 && a % b != 0) ? 1 : 0);
}

int dp[11][11][11][2][2];
// h, aw, bw, (S(a) \cap b != empty?), (S(b) \cap a != empty?), 
// aw == W : a doesn't exist in this raw

bool can[10][10][10];
bool in(int i,int x,int y){
	if(x>y) swap(x,y);
	return x<=i && i<=y;
}

const int inf = 1e9;
int solve(){
	int H,W; cin >> H >> W;
	V<string> s(H); rep(i,H) cin >> s[i];
	int ax,ay,bx,by,Ax,Ay,Bx,By;	// a -> A
	rep(i,H) rep(j,W){
		if(s[i][j] == 'S') ax=i,ay=j;
		if(s[i][j] == 's') Ax=i,Ay=j;
		if(s[i][j] == 'K') bx=i,by=j;
		if(s[i][j] == 'k') Bx=i,By=j;
	}
	if(ax >= Ax || bx >= Bx) return -1;

	rep(i,H){
		rep(x,W) rep(y,W){
			can[i][x][y] = true;
			for(int j=min(x,y);j<=max(x,y);j++) if(s[i][j] == '#') can[i][x][y] = false;
		}
	}

	rep(i,H+1) rep(a,W+1) rep(b,W+1) rep(x,2) rep(y,2) dp[i][a][b][x][y] = inf;
	if(ax > bx){
		swap(ax,bx);swap(ay,by);swap(Ax,Bx);swap(Ay,By);
	}
	if(ax < bx){
		dp[ax][ay][W][0][0] = 0;
	}else{
		dp[ax][ay][by][0][0] = 0;
	}
	#define UPDATE \
		/*shows(h+1,naw,nbw,nsa,nsb,dp[h][aw][bw][sa][sb] + cost);*/ \
		chmin(dp[h+1][naw][nbw][nsa][nsb], dp[h][aw][bw][sa][sb] + cost);

	for(int h=ax;h<H;h++) rep(aw,W+1) rep(bw,W+1) rep(sa,2) rep(sb,2) if(dp[h][aw][bw][sa][sb] != inf){
		bool aend = (h == Ax);
		bool bend = (h == Bx);
		if(aw != W && bw != W){
			rep(Aw,W) rep(Bw,W) if(can[h][aw][Aw] && can[h][bw][Bw]){
				if(aend && !(aw == Aw && aw == Ay)) continue;
				if(bend && !(bw == Bw && bw == By)) continue;

				int cost = abs(aw-Aw) + (aend?0:1) + abs(bw-Bw) + (bend?0:1);		// red + blue
				V<int> edge(W-1);
				for(int w=min(aw,Aw);w<max(aw,Aw);w++) edge[w] |= 1;
				for(int w=min(bw,Bw);w<max(bw,Bw);w++) edge[w] |= 2;
				int lime = 0; rep(w,W-1) if(edge[w] == 3) lime++;
				if(!aend && !bend && Aw == Bw) lime++;
				cost -= lime;		//	- lime
				V<int> deg(W);
				rep(w,W){
					if(w != 0 && edge[w-1]) deg[w]++;	// left
					if(w != W-1 && edge[w]) deg[w]++;	// right
					if((w == aw && h != ax) or (w == bw && h != bx)) deg[w]++;	// up
					if((w == Aw && !aend) or (w == Bw && !bend)) deg[w]++;	// down
					if((w == Aw && aend) or (w == Bw && bend)) deg[w]++;	// terminal +1 cost
				}
				int green = 0; rep(w,W) green += max(deg[w]-2,0);
				cost += green;

				int naw = (aend ? W : Aw), nbw = (bend ? W : Bw);
				int nsa = sa | !in(aw,bw,Bw);
				int nsb = sb | !in(bw,aw,Aw);
				if(h == ax && h == bx && nsa == 0 && nsb == 0){
					// first raw dead
					continue;
				}
				UPDATE
			}
		}else if(aw != W){
			rep(Aw,W) if(can[h][aw][Aw]){
				if(aend && !(aw == Aw && aw == Ay)) continue;

				int cost = abs(aw-Aw) + (aend?0:1);		// red

				int naw = (aend ? W : Aw);
				int nbw = (h+1 == bx ? by : W);
				int nsa = 1;
				int nsb = sb;
				UPDATE
			}
		}else if(bw != W){
			rep(Bw,W) if(can[h][bw][Bw]){
				if(bend && !(bw == Bw && bw == By)) continue;

				int cost = abs(bw-Bw) + (bend?0:1);		// red

				int nbw = (bend ? W : Bw);
				int naw = (h+1 == ax ? ay : W);
				int nsb = 1;
				int nsa = sa;
				UPDATE
			}
		}else{
			int naw = (h+1 == ax ? ay : W);
			int nbw = (h+1 == bx ? by : W);
			int nsa = sa, nsb = sb; int cost = 0;
			UPDATE
		}
	}
	int res = dp[H][W][W][1][1];
	if(res == inf) return -1;
	return res;
}

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);		//DON'T USE scanf/printf/puts !!
	cout << fixed << setprecision(20);

	int ans = solve();
	if(ans == -1) cout << "CONTRACT" << endl;
	else cout << ans << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 3464
final_rank: 3

code_snippet: #include<iostream>
#include<vector>
#include<queue>
using namespace std;
int H,W;
int M = 10000;
int s,S,k,K;
vector<int> dist;




void bfs_s2(vector<char> g,int dis,bool sfound){
  queue<int> que;
  for(int i=0;i<H*W;i++){
    dist[i] = 10000;
  }
  que.push(S);
  dist[S] = dis;
  while(!que.empty()){
    int p = que.front();
    //cout << "p:" << p << endl;
    que.pop();
    //cout << "next_p:" << que.front() << endl;
    if(p==s-W){
      int d = dist[p]+1;
      if(p%W!=0 and g[s-1]=='a')d++;
      if(p%W!=W-1 and g[s+1]=='a')d++;
      if(p/W<H and g[s+W]=='a')d++;
      if(d<M){
        M=d;
      }
      continue;
    }
    vector<int> next;
    if(p%W!=0)next.push_back(p-1);
    if(p%W!=W-1)next.push_back(p+1);
    if(p/W<s/W-1)next.push_back(p+W);
    for(int i=0;i<next.size();i++){
      int d = dist[p]+1;
      switch(g[next[i]]){
        case('.'):
        if(dist[next[i]] > d){
          dist[next[i]] = d;
          que.push(next[i]);
        }
        break;
        case('a'):
        d++;
        case('K'):
        d++;
        //cout << sfound <<endl;
        if(sfound==1){
          if(d<M)M=d;
          return;
        }
        for(int j=0;j<H*W;j++){
          if(g[j]=='a' and dist[j]>d){
            dist[j] = d;
            que.push(j);
          }
          if(g[j]=='K' and dist[j]>d and g[next[i]]!='K'){
            dist[j] = d-1;
            que.push(j);
          }
          if(g[j]=='K' and dist[j]>d and g[next[i]]=='K'){
            dist[j] = d;
            que.push(j);
          }
        }
        break;
      }
    }
  }
}

void dfs_s2(int p,vector<char> g,int dis,bool out){
  if(p/W >= s/W or M<=dis)return;
  if(g[p]=='a' or g[p]=='S'){
    g[p] = 'b';
    if(out==1)M = dis;
    if(out==0){
      if(p%W!=0)dfs_s2(p-1,g,dis,0);
      if(p%W!=W-1)dfs_s2(p+1,g,dis,0);
      if(p/W<s/W-1)dfs_s2(p+W,g,dis,0);
    }
  }
  if(g[p]=='.'){
    g[p] = 'b';
    if(p%W!=0)dfs_s2(p-1,g,dis+1,1);
    if(p%W!=W-1)dfs_s2(p+1,g,dis+1,1);
    if(p/W<s/W-1)dfs_s2(p+W,g,dis+1,1);
  }
}
/*
void bfs_k1(vector<char> g){
  int d=0;
  queue<int> Q;
  Q.push(K);
  Q.push(-1);
  while(!Q.empty()){
    int p=Q.front();
    Q.pop();
    if(p==-1)d++;
    vector<int> next;
    if(p%W!=0)next.push_back(p-1);
    if(p%W!=W-1)next.push_back(p+1);
    if(p/W<k/W-1)next.push_back(p+W);
    for(int i=0;i<next.size();i++){
      if(g[next[i]]=='.')Q.push(next[i]);
      if(next[i]==k-W){
        limdis=d+8;
        break;
      }
    }
  }
}
*/

void dfs_k1(int p,vector<char> g,int dis,bool sfound,bool Sfound){
  //if(dis>limdis)return;
  if(p!=K)g[p]='a';
  if(g[p+W]=='k'){
    dis++;
    for(int i=0;i<H*W;i++){
      if(g[i]=='l')g[i]='.';
    }
    if(Sfound==0){
      bfs_s2(g,dis,sfound);
      //cout << sfound <<Sfound <<endl;
    }
    else if(sfound==1)dfs_s2(S,g,dis+4,0);
    return;
  }
  dis++;
  if(p/W<k/W-1){
    switch(g[p+W]){
      case('S'):
      dfs_k1(p+W,g,dis,sfound,1);
      break;
      case('s'):
      sfound = 1;
      case('.'):
      dfs_k1(p+W,g,dis,sfound,Sfound);
      break;
    }
  }
  vector<int> next;
  if(p%W!=0)next.push_back(p-1);
  if(p%W!=W-1)next.push_back(p+1);
  int P=p+W;
  while(P<H*W){
    if(g[P]=='.')g[P]='l';
    else break;
    P += W;
  }
  for(int i=0;i<next.size();i++){
    switch(g[next[i]]){
      case('S'):
      dfs_k1(next[i],g,dis,sfound,1);
      break;
      case('s'):
      sfound = 1;
      case('.'):
      dfs_k1(next[i],g,dis,sfound,Sfound);
      break;
    }
  }
}




int main(){
  cin >> H >> W;
  vector<char> g;
  g.resize(H*W);
  dist.resize(H*W);
  for(int i=0;i<H*W;i++){
    cin >> g[i];
    if(g[i]=='k')k=i;
    if(g[i]=='K')K=i;
    if(g[i]=='s')s=i;
    if(g[i]=='S')S=i;
  }
  dfs_k1(K,g,0,0,0);

  g[k]='s';
  g[s]='k';
  g[S]='K';
  g[K]='S';
  int koukan;
  koukan = s;
  s=k;
  k=koukan;
  koukan=S;
  S=K;
  K=koukan;

  //cout << "---------------------------"<<endl;
  dfs_k1(K,g,0,0,0);


  if(M==10000)cout << "CONTRACT"<<endl;
  else cout << M <<endl;
}
accuracy: 1
time_ms: 850
memory_kb: 3172
final_rank: 4

code_snippet: #include<iostream>
#include<vector>
#include<queue>
using namespace std;
int H,W;
int M = 10000;
int s,S,k,K;
vector<int> dist;




void bfs_s2(vector<char> g,int dis,bool sfound){
  queue<int> que;
  for(int i=0;i<H*W;i++){
    dist[i] = 10000;
  }
  que.push(S);
  dist[S] = dis;
  while(!que.empty()){
    int p = que.front();
    //cout << "p:" << p << endl;
    que.pop();
    //cout << "next_p:" << que.front() << endl;
    if(p==s-W){
      int d = dist[p]+1;
      if(p%W!=0 and g[s-1]=='a')d++;
      if(p%W!=W-1 and g[s+1]=='a')d++;
      if(p/W<H and g[s+W]=='a')d++;
      if(d<M){
        M=d;
      }
      continue;
    }
    vector<int> next;
    if(p%W!=0)next.push_back(p-1);
    if(p%W!=W-1)next.push_back(p+1);
    if(p/W<s/W-1)next.push_back(p+W);
    for(int i=0;i<next.size();i++){
      int d = dist[p]+1;
      switch(g[next[i]]){
        case('.'):
        if(dist[next[i]] > d){
          dist[next[i]] = d;
          que.push(next[i]);
        }
        break;
        case('a'):
        d++;
        case('K'):
        d++;
        //cout << sfound <<endl;
        if(sfound==1){
          if(d<M)M=d;
          return;
        }
        for(int j=0;j<H*W;j++){
          if(g[j]=='a' and dist[j]>d){
            dist[j] = d;
            que.push(j);
          }
          if(g[j]=='K' and dist[j]>d){
            dist[j] = d-1;
            que.push(j);
          }
        }
        break;
      }
    }
  }
}

void dfs_s2(int p,vector<char> g,int dis,bool out){
  if(p/W >= s/W or M<=dis)return;
  if(g[p]=='a' or g[p]=='S'){
    g[p] = 'b';
    if(out==1)M = dis;
    if(out==0){
      if(p%W!=0)dfs_s2(p-1,g,dis,0);
      if(p%W!=W-1)dfs_s2(p+1,g,dis,0);
      if(p/W<s/W-1)dfs_s2(p+W,g,dis,0);
    }
  }
  if(g[p]=='.'){
    g[p] = 'b';
    if(p%W!=0)dfs_s2(p-1,g,dis+1,1);
    if(p%W!=W-1)dfs_s2(p+1,g,dis+1,1);
    if(p/W<s/W-1)dfs_s2(p+W,g,dis+1,1);
  }
}
/*
void bfs_k1(vector<char> g){
  int d=0;
  queue<int> Q;
  Q.push(K);
  Q.push(-1);
  while(!Q.empty()){
    int p=Q.front();
    Q.pop();
    if(p==-1)d++;
    vector<int> next;
    if(p%W!=0)next.push_back(p-1);
    if(p%W!=W-1)next.push_back(p+1);
    if(p/W<k/W-1)next.push_back(p+W);
    for(int i=0;i<next.size();i++){
      if(g[next[i]]=='.')Q.push(next[i]);
      if(next[i]==k-W){
        limdis=d+8;
        break;
      }
    }
  }
}
*/

void dfs_k1(int p,vector<char> g,int dis,bool sfound,bool Sfound){
  //if(dis>limdis)return;
  if(p!=K)g[p]='a';
  if(g[p+W]=='k'){
    dis++;
    for(int i=0;i<H*W;i++){
      if(g[i]=='l')g[i]='.';
    }
    if(Sfound==0){
      bfs_s2(g,dis,sfound);
      //cout << sfound <<Sfound <<endl;
    }
    else if(sfound==1)dfs_s2(S,g,dis+4,0);
    return;
  }
  dis++;
  if(p/W<k/W-1){
    switch(g[p+W]){
      case('S'):
      dfs_k1(p+W,g,dis,sfound,1);
      break;
      case('s'):
      sfound = 1;
      case('.'):
      dfs_k1(p+W,g,dis,sfound,Sfound);
      break;
    }
  }
  vector<int> next;
  if(p%W!=0)next.push_back(p-1);
  if(p%W!=W-1)next.push_back(p+1);
  int P=p+W;
  while(P<H*W){
    if(g[P]=='.')g[P]='l';
    else break;
    P += W;
  }
  for(int i=0;i<next.size();i++){
    switch(g[next[i]]){
      case('S'):
      dfs_k1(next[i],g,dis,sfound,1);
      break;
      case('s'):
      sfound = 1;
      case('.'):
      dfs_k1(next[i],g,dis,sfound,Sfound);
      break;
    }
  }
}




int main(){
  cin >> H >> W;
  vector<char> g;
  g.resize(H*W);
  dist.resize(H*W);
  for(int i=0;i<H*W;i++){
    cin >> g[i];
    if(g[i]=='k')k=i;
    if(g[i]=='K')K=i;
    if(g[i]=='s')s=i;
    if(g[i]=='S')S=i;
  }
  dfs_k1(K,g,0,0,0);

  g[k]='s';
  g[s]='k';
  g[S]='K';
  g[K]='S';
  int koukan;
  koukan = s;
  s=k;
  k=koukan;
  koukan=S;
  S=K;
  K=koukan;

  //cout << "---------------------------"<<endl;
  dfs_k1(K,g,0,0,0);


  if(M==10000)cout << "CONTRACT"<<endl;
  else cout << M <<endl;
}
accuracy: 0.8269230769230769
time_ms: 860
memory_kb: 3176
final_rank: 5

code_snippet: #include<iostream>
#include<vector>
#include<queue>
using namespace std;
int H,W;
int M = 10000;
int s,S,k,K;
vector<int> dist;




void bfs_s2(vector<char> g,int dis,bool sfound){
  queue<int> que;
  for(int i=0;i<H*W;i++){
    dist[i] = 10000;
  }
  que.push(S);
  dist[S] = dis;
  while(!que.empty()){
    int p = que.front();
    //cout << "p:" << p << endl;
    que.pop();
    //cout << "next_p:" << que.front() << endl;
    if(p==s-W){
      int d = dist[p]+1;
      if(p%W!=0 and g[s-1]=='a')d++;
      if(p%W!=W-1 and g[s+1]=='a')d++;
      if(p/W<H and g[s+W]=='a')d++;
      if(d<M){
        M=d;
      }
      continue;
    }
    vector<int> next;
    if(p%W!=0)next.push_back(p-1);
    if(p%W!=W-1)next.push_back(p+1);
    if(p/W<s/W-1)next.push_back(p+W);
    for(int i=0;i<next.size();i++){
      int d = dist[p]+1;
      switch(g[next[i]]){
        case('.'):
        if(dist[next[i]] > d){
          dist[next[i]] = d;
          que.push(next[i]);
        }
        break;
        case('a'):
        d++;
        case('K'):
        d++;
        //cout << sfound <<endl;
        if(sfound==1){
          if(d<M)M=d;
          return;
        }
        for(int j=0;j<H*W;j++){
          if(g[j]=='a' and dist[j]>d){
            dist[j] = d;
            que.push(j);
          }
          if(g[j]=='K' and dist[j]>d){
            dist[j] = d;
            que.push(j);
          }
        }
        break;
      }
    }
  }
}

void dfs_s2(int p,vector<char> g,int dis,bool out){
  if(p/W >= s/W or M<=dis)return;
  if(g[p]=='a' or g[p]=='S'){
    g[p] = 'b';
    if(out==1)M = dis;
    if(out==0){
      if(p%W!=0)dfs_s2(p-1,g,dis,0);
      if(p%W!=W-1)dfs_s2(p+1,g,dis,0);
      if(p/W<s/W-1)dfs_s2(p+W,g,dis,0);
    }
  }
  if(g[p]=='.'){
    g[p] = 'b';
    if(p%W!=0)dfs_s2(p-1,g,dis+1,1);
    if(p%W!=W-1)dfs_s2(p+1,g,dis+1,1);
    if(p/W<s/W-1)dfs_s2(p+W,g,dis+1,1);
  }
}
/*
void bfs_k1(vector<char> g){
  int d=0;
  queue<int> Q;
  Q.push(K);
  Q.push(-1);
  while(!Q.empty()){
    int p=Q.front();
    Q.pop();
    if(p==-1)d++;
    vector<int> next;
    if(p%W!=0)next.push_back(p-1);
    if(p%W!=W-1)next.push_back(p+1);
    if(p/W<k/W-1)next.push_back(p+W);
    for(int i=0;i<next.size();i++){
      if(g[next[i]]=='.')Q.push(next[i]);
      if(next[i]==k-W){
        limdis=d+8;
        break;
      }
    }
  }
}
*/

void dfs_k1(int p,vector<char> g,int dis,bool sfound,bool Sfound){
  //if(dis>limdis)return;
  if(p!=K)g[p]='a';
  if(g[p+W]=='k'){
    dis++;
    for(int i=0;i<H*W;i++){
      if(g[i]=='l')g[i]='.';
    }
    if(Sfound==0){
      bfs_s2(g,dis,sfound);
      //cout << sfound <<Sfound <<endl;
    }
    else if(sfound==1)dfs_s2(S,g,dis+4,0);
    return;
  }
  dis++;
  if(p/W<k/W-1){
    switch(g[p+W]){
      case('S'):
      dfs_k1(p+W,g,dis,sfound,1);
      break;
      case('s'):
      sfound = 1;
      case('.'):
      dfs_k1(p+W,g,dis,sfound,Sfound);
      break;
    }
  }
  vector<int> next;
  if(p%W!=0)next.push_back(p-1);
  if(p%W!=W-1)next.push_back(p+1);
  int P=p+W;
  while(P<H*W){
    if(g[P]=='.')g[P]='l';
    else break;
    P += W;
  }
  for(int i=0;i<next.size();i++){
    switch(g[next[i]]){
      case('S'):
      dfs_k1(next[i],g,dis,sfound,1);
      break;
      case('s'):
      sfound = 1;
      case('.'):
      dfs_k1(next[i],g,dis,sfound,Sfound);
      break;
    }
  }
}




int main(){
  cin >> H >> W;
  vector<char> g;
  g.resize(H*W);
  dist.resize(H*W);
  for(int i=0;i<H*W;i++){
    cin >> g[i];
    if(g[i]=='k')k=i;
    if(g[i]=='K')K=i;
    if(g[i]=='s')s=i;
    if(g[i]=='S')S=i;
  }
  dfs_k1(K,g,0,0,0);

  g[k]='s';
  g[s]='k';
  g[S]='K';
  g[K]='S';
  int koukan;
  koukan = s;
  s=k;
  k=koukan;
  koukan=S;
  S=K;
  K=koukan;

  //cout << "---------------------------"<<endl;
  dfs_k1(K,g,0,0,0);


  if(M==10000)cout << "CONTRACT"<<endl;
  else cout << M <<endl;
}
accuracy: 0.5576923076923077
time_ms: 860
memory_kb: 3164
final_rank: 9

code_snippet: #include<iostream>
#include<vector>
#include<queue>
using namespace std;
int H,W;
int M = 10000;
int s,S,k,K;
queue<int> que;
vector<int> dist;




void bfs_s2(vector<char> g,int dis,bool sfound){
  for(int i=0;i<H*W;i++){
    dist[i] = 10000;
  }
  que.push(S);
  dist[S] = dis;
  while(!que.empty()){
    int p = que.front();
    que.pop();
    if(g[p+W]=='s'){
      if(dist[p]+1<M){
        M=dist[p]+1;
      }
      continue;
    }
    vector<int> next;
    if(p%W!=0)next.push_back(p-1);
    if(p%W!=W-1)next.push_back(p+1);
    if(p/W<s/W-1)next.push_back(p+W);
    for(int i=0;i<next.size();i++){
      int d = dist[p]+1;
      switch(g[next[i]]){
        case('.'):
        if(dist[next[i]] > d){
          dist[next[i]] = d;
          que.push(next[i]);
        }
        break;
        case('a'):
        d++;
        case('K'):
        d++;
        if(sfound==1){
          if(d<M)M=d;
          return;
        }
        for(int j=0;j<H*W;j++){
          if(g[j]=='a' and dist[j]>d){
            dist[j] = d;
            que.push(j);
          }
          if(g[j]=='K' and dist[j]>d){
            dist[j] = d;
            que.push(j);
          }
        }
        break;
      }
    }
  }
  /*
  for(int i=0;i<H;i++){
    for(int j=0;j<W;j++){
      cout << dist[i*W+j] << " ";
    }
    cout << endl;
  }
  */
}

void dfs_s2(int p,vector<char> g,int dis,bool out){
  if(p/W >= s/W or M<=dis)return;
  if(g[p]=='a' or g[p]=='S'){
    g[p] = 'b';
    if(out==1)M = dis;
    if(out==0){
      if(p%W!=0)dfs_s2(p-1,g,dis,0);
      if(p%W!=W-1)dfs_s2(p+1,g,dis,0);
      if(p/W<s/W-1)dfs_s2(p+W,g,dis,0);
    }
  }
  if(g[p]=='.'){
    g[p] = 'b';
    if(p%W!=0)dfs_s2(p-1,g,dis+1,1);
    if(p%W!=W-1)dfs_s2(p+1,g,dis+1,1);
    if(p/W<s/W-1)dfs_s2(p+W,g,dis+1,1);
  }
}



void dfs_k1(int p,vector<char> g,int dis,bool sfound,bool Sfound){
  if(p!=K)g[p]='a';
  if(g[p+W]=='k'){
    dis++;
    if(Sfound==0)bfs_s2(g,dis,sfound);
    else if(sfound==1)dfs_s2(S,g,dis+4,0);
    return;
  }
  vector<int> next;
  if(p%W!=0)next.push_back(p-1);
  if(p%W!=W-1)next.push_back(p+1);
  if(p/W<k/W-1)next.push_back(p+W);
  dis++;
  for(int i=0;i<next.size();i++){
    switch(g[next[i]]){
      case('S'):
      dfs_k1(next[i],g,dis,sfound,1);
      break;
      case('s'):
      sfound = 1;
      case('.'):
      dfs_k1(next[i],g,dis,sfound,Sfound);
      break;
    }
  }
}



int main(){
  cin >> H >> W;
  vector<char> g;
  g.resize(H*W);
  dist.resize(H*W);
  for(int i=0;i<H*W;i++){
    cin >> g[i];
    if(g[i]=='k')k=i;
    if(g[i]=='K')K=i;
    if(g[i]=='s')s=i;
    if(g[i]=='S')S=i;
  }

  dfs_k1(K,g,0,0,0);

  g[k]='s';
  g[s]='k';
  g[S]='K';
  g[K]='S';
  int koukan;
  koukan = s;
  s=k;
  k=koukan;
  koukan=S;
  S=K;
  K=koukan;


  dfs_k1(K,g,0,0,0);


  if(M==10000)cout << "CONTRACT"<<endl;
  else cout << M <<endl;
}
accuracy: 0.4423076923076923
time_ms: 90
memory_kb: 3172
final_rank: 10

code_snippet: #include<iostream>
#include<vector>
#include<queue>
using namespace std;
int H,W;
int M = 10000;
int s,S,k,K;
queue<int> que;
vector<int> dist;




void bfs_s2(vector<char> g,int dis,bool sfound){
  for(int i=0;i<H*W;i++){
    dist[i] = 10000;
  }
  que.push(S);
  dist[S] = dis;
  while(!que.empty()){
    int p = que.front();
    que.pop();
    if(g[p+W]=='s'){
      if(dist[p]+1<M){
        M=dist[p]+1;
      }
      continue;
    }
    vector<int> next;
    if(p%W!=0)next.push_back(p-1);
    if(p%W!=W-1)next.push_back(p+1);
    if(p/W<k/W-1)next.push_back(p+W);
    for(int i=0;i<next.size();i++){
      int d = dist[p]+1;
      switch(g[next[i]]){
        case('.'):
        if(dist[next[i]] > d){
          dist[next[i]] = d;
          que.push(next[i]);
        }
        break;
        case('a'):
        d++;
        case('K'):
        d++;
        if(sfound==1){
          if(d<M)M=d;
          return;
        }
        for(int j=0;j<H*W;j++){
          if(g[j]=='a' and dist[j]>d){
            dist[j] = d;
            que.push(j);
          }
          if(g[j]=='K' and dist[j]>d){
            dist[j] = d;
            que.push(j);
          }
        }
        break;
      }
    }
  }
}

void dfs_s2(int p,vector<char> g,int dis,bool out){
  if(p/W >= s/W or M<=dis)return;
  if(g[p]=='a' or g[p]=='S'){
    g[p] = 'b';
    if(out==1)M = dis;
    if(out==0){
      if(p%W!=0)dfs_s2(p-1,g,dis,0);
      if(p%W!=W-1)dfs_s2(p+1,g,dis,0);
      if(p/W<s/W-1)dfs_s2(p+W,g,dis,0);
    }
  }
  if(g[p]=='.'){
    g[p] = 'b';
    if(p%W!=0)dfs_s2(p-1,g,dis+1,1);
    if(p%W!=W-1)dfs_s2(p+1,g,dis+1,1);
    if(p/W<s/W-1)dfs_s2(p+W,g,dis+1,1);
  }
}



void dfs_k1(int p,vector<char> g,int dis,bool sfound,bool Sfound){
  if(p!=K)g[p]='a';
  if(g[p+W]=='k'){
    dis++;
    if(Sfound==0)bfs_s2(g,dis,sfound);
    else if(sfound==1)dfs_s2(S,g,dis+4,0);
    return;
  }
  vector<int> next;
  if(p%W!=0)next.push_back(p-1);
  if(p%W!=W-1)next.push_back(p+1);
  if(p/W<k/W-1)next.push_back(p+W);
  dis++;
  for(int i=0;i<next.size();i++){
    switch(g[next[i]]){
      case('S'):
      dfs_k1(next[i],g,dis,sfound,1);
      break;
      case('s'):
      sfound = 1;
      case('.'):
      dfs_k1(next[i],g,dis,sfound,Sfound);
      break;
    }
  }
}



int main(){
  cin >> H >> W;
  vector<char> g;
  g.resize(H*W);
  dist.resize(H*W);
  for(int i=0;i<H*W;i++){
    cin >> g[i];
    if(g[i]=='k')k=i;
    if(g[i]=='K')K=i;
    if(g[i]=='s')s=i;
    if(g[i]=='S')S=i;
  }

  dfs_k1(K,g,0,0,0);

  g[k]='s';
  g[s]='k';
  g[S]='K';
  g[K]='S';
  int koukan;
  koukan = s;
  s=k;
  k=koukan;
  koukan=S;
  S=K;
  K=koukan;


  dfs_k1(K,g,0,0,0);


  if(M==10000)cout << "CONTRACT"<<endl;
  else cout << M <<endl;
}
accuracy: 0.38461538461538464
time_ms: 90
memory_kb: 3172
final_rank: 11

code_snippet: #include<iostream>
#include<vector>
#include<queue>
using namespace std;
int H,W;
int M = 10000;
int s,S,k,K;
queue<int> que;
vector<int> dist;




void bfs_s2(vector<char> g,int dis,bool sfound){
  for(int i=0;i<H*W;i++){
    dist[i] = 10000;
  }
  que.push(S);
  dist[S] = dis;
  while(!que.empty()){
    int p = que.front();
    que.pop();
    if(g[p+W]=='s'){
      if(dist[p]+1<M){
        M=dist[p]+1;
      }
      continue;
    }
    vector<int> next;
    if(p%W!=0)next.push_back(p-1);
    if(p%W!=W-1)next.push_back(p+1);
    if(p/W<k/W-1)next.push_back(p+W);
    for(int i=0;i<next.size();i++){
      int d = dist[p]+1;
      switch(g[next[i]]){
        case('.'):
        if(dist[next[i]] > d){
          dist[next[i]] = d;
          que.push(next[i]);
        }
        break;
        case('a'):
        d++;
        case('K'):
        d++;
        if(sfound==1){
          if(d<M)M=d;
          return;
        }
        for(int j=0;j<H*W;j++){
          if(g[j]=='a' and dist[j]>d){
            dist[j] = d;
            que.push(j);
          }
          if(g[j]=='K' and dist[j]>d){
            dist[j] = d;
            que.push(j);
          }
        }
        break;
      }
    }
  }
}

void dfs_s2(int p,vector<char> g,int dis,bool out){
  if(p/W >= s/W or M<=dis)return;
  if(g[p]=='a' or g[p]=='S'){
    g[p] = 'b';
    if(out==1)M = dis;
    if(out==0){
      if(p%W!=0)dfs_s2(p-1,g,dis,0);
      if(p%W!=W-1)dfs_s2(p+1,g,dis,0);
      if(p/W<s/W-1)dfs_s2(p+W,g,dis,0);
    }
  }
  if(g[p]=='.'){
    g[p] = 'b';
    if(p%W!=0)dfs_s2(p-1,g,dis+1,1);
    if(p%W!=W-1)dfs_s2(p+1,g,dis+1,1);
    if(p/W<s/W-1)dfs_s2(p+W,g,dis+1,1);
  }
}



void dfs_k1(int p,vector<char> g,int dis,bool sfound,bool Sfound){
  if(p!=K)g[p]='a';
  if(g[p+W]=='k'){
    dis++;
    if(Sfound==0)bfs_s2(g,dis,sfound);
    else if(sfound==1){
      dfs_s2(S,g,dis+4,0);
    }
    return;
  }
  vector<int> next;
  if(p%W!=0)next.push_back(p-1);
  if(p%W!=W-1)next.push_back(p+1);
  if(p/W<k/W-1)next.push_back(p+W);
  dis++;
  for(int i=0;i<next.size();i++){
    switch(g[next[i]]){
      case('S'):
      Sfound = 1;
      dfs_k1(next[i],g,dis,sfound,Sfound);
      break;
      case('s'):
      sfound = 1;
      case('.'):
      dfs_k1(next[i],g,dis,sfound,Sfound);
      break;
    }
  }
}



int main(){
  cin >> H >> W;
  vector<char> g;
  g.resize(H*W);
  dist.resize(H*W);
  for(int i=0;i<H*W;i++){
    cin >> g[i];
    if(g[i]=='k')k=i;
    if(g[i]=='K')K=i;
    if(g[i]=='s')s=i;
    if(g[i]=='S')S=i;
  }

  dfs_k1(K,g,0,0,0);

  g[k]='s';
  g[s]='k';
  g[S]='K';
  g[K]='S';
  int koukan;
  koukan = s;
  s=k;
  k=koukan;
  koukan=S;
  S=K;
  K=koukan;


  dfs_k1(K,g,0,0,0);


  if(M==10000)cout << "CONTRACT"<<endl;
  else cout << M <<endl;
}
accuracy: 0.3076923076923077
time_ms: 70
memory_kb: 3172
final_rank: 12

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
char str[12][12];
int dp[12][12][12][12][4];
int H,W;
int sr,sc,kr,kc,SR,SC,KR,KC;
inline int ABS(int a){return max(a,-a);}
inline void upd(int a,int b,int c,int d,int e){
	if(a>=sr){
		if(a>=kr)return;
		if(a+1<KR)dp[a+1][11][11][b][e|2]=min(dp[a+1][11][11][b][e|2],dp[a][b][c][d][e]);
		else if(a+1==KR)dp[a+1][11][KC][b][e|2]=min(dp[a+1][11][KC][b][e|2],dp[a][b][c][d][e]);
		else{
			for(int y=0;y<W;y++){
				bool d2=false;
				for(int z=min(y,c);z<=max(y,c);z++)if(str[a][z]=='#')d2=true;
				if(str[a+1][y]=='#')d2=true;
				if(a+1==kr&&kc!=y)d2=true;
				if(d2)continue;
				int x=b;
				int ks=0;
				int vt=0;
				for(int z=min(y,c);z<max(y,c);z++){
					bool iL=(min(b,x)<=z)&&(z<=max(b,x));
					bool iR=(min(b,x)<=z+1)&&(z+1<=max(b,x));
					if(!iL&&!iR)ks++;
					else if(!(iL&&iR)){
						if(!vt&&a==SR&&(z==SC||z+1==SC)){vt=1;ks++;}
					//	else if(!vt&&a==sr&&(z==sc||z+1==sc)){vt=1;ks++;}
						else ks+=2;
					}
				}
				if(d!=11&&a>KR&&a<=sr&&min(b,d)<=c&&c<=max(b,d)&&min(b,x)<=c&&c<=max(b,x)){
					if(a-1==SR&&c==SC)ks--;
					else if(a-1==sr&&c==sc)ks--;
					else ks-=2;
				}
				if((SR!=a||y!=SC)&&min(b,x)<=y&&y<=max(b,x))ks+=2;
				else ks++;
				if(d!=11&&a>KR&&a<=sr&&min(b,x)<=c&&c<=max(b,x)&&!(min(b,d)<=c&&c<=max(b,d)))ks++;
				int te=e;
				if(c<min(b,x)||max(b,x)<c)te|=2;
				if(b<min(c,y)||max(c,y)<b)te|=1;
				dp[a+1][11][y][b][te]=min(dp[a+1][11][y][b][te],dp[a][b][c][d][e]+ks);
			}
		}
		return;
	}
	for(int x=0;x<W;x++){
		bool d1=false;
		for(int z=min(x,b);z<=max(x,b);z++)if(str[a][z]=='#')d1=true;
		if(str[a+1][x]=='#')d1=true;
		if(a+1==sr&&sc!=x)d1=true;
		
		if(d1)continue;
		if(a<KR){
			int ks=ABS(x-b)+1;
			if(a+1==KR)dp[a+1][x][KC][b][e|1]=min(dp[a+1][x][KC][b][e|1],dp[a][b][c][d][e]+ks);
			else dp[a+1][x][11][b][e|1]=min(dp[a+1][x][11][b][e|1],dp[a][b][c][d][e]+ks);
			continue;
		}
		if(a>=kr){
			int ks=ABS(x-b)+1;
			if(a==kr&&min(b,x)<=c&&c<=max(b,x))ks++;
			if(d!=11&&a>KR&&min(b,d)<=c&&c<=max(b,d)&&min(b,x)<=c&&c<=max(b,x)){
				if(a-1==SR&&c==SC)ks--;
				else if(a-1==sr&&c==sc)ks--;
				else ks-=2;
			}
			if(d!=11&&a>KR&&min(b,x)<=c&&c<=max(b,x)&&!(min(b,d)<=c&&c<=max(b,d)))ks++;
			int te=e|1;
			if(a==kr&&(c<min(b,x)||max(b,x)<c))te|=2;
			dp[a+1][x][11][b][te]=min(dp[a+1][x][11][b][te],dp[a][b][c][d][e]+ks);
			continue;
		}
		for(int y=0;y<W;y++){
			bool d2=false;
			for(int z=min(y,c);z<=max(y,c);z++)if(str[a][z]=='#')d2=true;
			if(str[a+1][y]=='#')d2=true;
			if(a+1==kr&&kc!=y)d2=true;
			if(a==SR&&a==KR&&min(b,x)<=c&&c<=max(b,x)&&min(c,y)<=b&&b<=max(c,y))continue;
			if(d2)continue;
			int ks=ABS(x-b)+1;
			int vt=0;
			for(int z=min(y,c);z<max(y,c);z++){
				bool iL=(min(b,x)<=z)&&(z<=max(b,x));
				bool iR=(min(b,x)<=z+1)&&(z+1<=max(b,x));
				if(!iL&&!iR)ks++;
				else if(!(iL&&iR)){
					if(!vt&&a==SR&&(z==SC||z+1==SC)){vt=1;ks++;}
			//		else if(!vt&&a==sr&&(z==sc||z+1==sc)){vt=1;ks++;}
					else ks+=2;
				}
			}
			if(d!=11&&a>KR&&min(b,d)<=c&&c<=max(b,d)&&min(b,x)<=c&&c<=max(b,x)){
				if(a-1==SR&&c==SC)ks--;
				else if(a-1==sr&&c==sc)ks--;
				else ks-=2;
			}
			if((SR!=a||y!=SC)&&min(b,x)<=y&&y<=max(b,x))ks+=2;
			else ks++;
			if(d!=11&&a>KR&&min(b,x)<=c&&c<=max(b,x)&&!(min(b,d)<=c&&c<=max(b,d)))ks++;
			int te=e;
			if(c<min(b,x)||max(b,x)<c)te|=2;
			if(b<min(c,y)||max(c,y)<b)te|=1;
		//	if(a==sr)te|=2;
		//	if(a==kr)te|=1;
		//	printf("%d %d %d %d %d -> %d %d %d %d %d: %d\n",a,b,c,d,e,a+1,x,y,b,te,ks);
			dp[a+1][x][y][b][te]=min(dp[a+1][x][y][b][te],dp[a][b][c][d][e]+ks);
		}
	}
}
int main(){
	int a,b;
	scanf("%d%d",&a,&b);
	H=a;W=b;
	for(int i=0;i<a;i++)scanf("%s",str[i]);
	for(int i=0;i<12;i++)for(int j=0;j<12;j++)for(int k=0;k<12;k++)for(int l=0;l<12;l++)
		dp[i][j][k][l][0]=dp[i][j][k][l][1]=dp[i][j][k][l][2]=dp[i][j][k][l][3]=99999999;
	for(int i=0;i<a;i++)for(int j=0;j<b;j++){
		if(str[i][j]=='s'){sr=i;sc=j;}
		if(str[i][j]=='k'){kr=i;kc=j;}
		if(str[i][j]=='S'){SR=i;SC=j;}
		if(str[i][j]=='K'){KR=i;KC=j;}
	}
	if(SR>KR){
		swap(SR,KR);
		swap(SC,KC);
		swap(sr,kr);
		swap(sc,kc);
	}
	if(SR==KR){
		dp[SR][SC][KC][11][0]=0;
	}else if(SR<KR){
		dp[SR][SC][11][11][1]=0;
	}else{
		dp[SR][SC][11][11][2]=0;
	}
	int ret=99999999;
	for(int i=0;i<a;i++){
		for(int j=0;j<12;j++){
			for(int k=0;k<12;k++){
				for(int l=0;l<12;l++){
					for(int m=0;m<4;m++){
						if(dp[i][j][k][l][m]>999999)continue;
						//printf("%d %d %d %d %d: %d\n",i,j,k,l,m,dp[i][j][k][l][m]);
						int t=0;
						if(j==11)t|=2;
						if(k==11)t|=1;
						if(j<W&&k<W&&k!=j)t|=3;
						if(i>=max(sr,kr)&&(m|t)==3)ret=min(ret,dp[i][j][k][l][m]);
						else upd(i,j,k,l,m);
					}
				}
			}
		}
	}
	if(SR>=sr||KR>=kr)ret=999999999;
	if(ret>999999)printf("CONTRACT\n");
	else printf("%d\n",ret);
}
accuracy: 1
time_ms: 40
memory_kb: 1356
final_rank: 1

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
char str[12][12];
int dp[12][12][12][12][4];
int H,W;
int sr,sc,kr,kc,SR,SC,KR,KC;
inline int ABS(int a){return max(a,-a);}
inline void upd(int a,int b,int c,int d,int e){
	if(a>=sr){
		if(a>=kr)return;
		if(a+1<KR)dp[a+1][11][11][b][e|2]=min(dp[a+1][11][11][b][e|2],dp[a][b][c][d][e]);
		else if(a+1==KR)dp[a+1][11][KC][b][e|2]=min(dp[a+1][11][KC][b][e|2],dp[a][b][c][d][e]);
		else{
			for(int y=0;y<W;y++){
				bool d2=false;
				for(int z=min(y,c);z<=max(y,c);z++)if(str[a][z]=='#')d2=true;
				if(str[a+1][y]=='#')d2=true;
				if(a+1==kr&&kc!=y)d2=true;
				if(d2)continue;
				int x=b;
				int ks=0;
				int vt=0;
				for(int z=min(y,c);z<max(y,c);z++){
					bool iL=(min(b,x)<=z)&&(z<=max(b,x));
					bool iR=(min(b,x)<=z+1)&&(z+1<=max(b,x));
					if(!iL&&!iR)ks++;
					else if(!(iL&&iR)){
						if(!vt&&a==SR&&(z==SC||z+1==SC)){vt=1;ks++;}
						else if(!vt&&a==sr&&(z==sc||z+1==sc)){vt=1;ks++;}
						else ks+=2;
					}
				}
				if(d!=11&&a>KR&&min(b,d)<=c&&c<=max(b,d)&&min(b,x)<=c&&c<=max(b,x)){
					if(a-1==SR&&c==SC)ks--;
					else if(a-1==sr&&c==sc)ks--;
					else ks-=2;
				}
				if((SR!=a||y!=SC)&&min(b,x)<=y&&y<=max(b,x))ks+=2;
				else ks++;
				if(d!=11&&a>KR&&a<=sr&&min(b,x)<=c&&c<=max(b,x)&&!(min(b,d)<=c&&c<=max(b,d)))ks++;
				int te=e;
				if(c<min(b,x)||max(b,x)<c)te|=2;
				if(b<min(c,y)||max(c,y)<b)te|=1;
				dp[a+1][11][y][b][te]=min(dp[a+1][11][y][b][te],dp[a][b][c][d][e]+ks);
			}
		}
	}
	for(int x=0;x<W;x++){
		bool d1=false;
		for(int z=min(x,b);z<=max(x,b);z++)if(str[a][z]=='#')d1=true;
		if(str[a+1][x]=='#')d1=true;
		if(a+1==sr&&sc!=x)d1=true;
		
		if(d1)continue;
		if(a<KR){
			int ks=ABS(x-b)+1;
			if(a+1==KR)dp[a+1][x][KC][b][e|1]=min(dp[a+1][x][KC][b][e|1],dp[a][b][c][d][e]+ks);
			else dp[a+1][x][11][b][e|1]=min(dp[a+1][x][11][b][e|1],dp[a][b][c][d][e]+ks);
			continue;
		}
		if(a>=kr){
			int ks=ABS(x-b)+1;
			if(a==kr&&min(b,x)<=c&&c<=max(b,x))ks++;
			if(d!=11&&a>KR&&min(b,d)<=c&&c<=max(b,d)&&min(b,x)<=c&&c<=max(b,x)){
				if(a-1==SR&&c==SC)ks--;
				else if(a-1==sr&&c==sc)ks--;
				else ks-=2;
			}
			if(d!=11&&a>KR&&min(b,x)<=c&&c<=max(b,x)&&!(min(b,d)<=c&&c<=max(b,d)))ks++;
			int te=e|1;
			if(a==kr&&(c<min(b,x)||max(b,x)<c))te|=2;
			dp[a+1][x][11][b][te]=min(dp[a+1][x][11][b][te],dp[a][b][c][d][e]+ks);
			continue;
		}
		for(int y=0;y<W;y++){
			bool d2=false;
			for(int z=min(y,c);z<=max(y,c);z++)if(str[a][z]=='#')d2=true;
			if(str[a+1][y]=='#')d2=true;
			if(a+1==kr&&kc!=y)d2=true;
			if(a==SR&&a==KR&&min(b,x)<=c&&c<=max(b,x)&&min(c,y)<=b&&b<=max(c,y))continue;
			if(d2)continue;
			int ks=ABS(x-b)+1;
			int vt=0;
			for(int z=min(y,c);z<max(y,c);z++){
				bool iL=(min(b,x)<=z)&&(z<=max(b,x));
				bool iR=(min(b,x)<=z+1)&&(z+1<=max(b,x));
				if(!iL&&!iR)ks++;
				else if(!(iL&&iR)){
					if(!vt&&a==SR&&(z==SC||z+1==SC)){vt=1;ks++;}
					else if(!vt&&a==sr&&(z==sc||z+1==sc)){vt=1;ks++;}
					else ks+=2;
				}
			}
			if(d!=11&&a>KR&&min(b,d)<=c&&c<=max(b,d)&&min(b,x)<=c&&c<=max(b,x)){
				if(a-1==SR&&c==SC)ks--;
				else if(a-1==sr&&c==sc)ks--;
				else ks-=2;
			}
			if((SR!=a||y!=SC)&&min(b,x)<=y&&y<=max(b,x))ks+=2;
			else ks++;
			if(d!=11&&a>KR&&min(b,x)<=c&&c<=max(b,x)&&!(min(b,d)<=c&&c<=max(b,d)))ks++;
			int te=e;
			if(c<min(b,x)||max(b,x)<c)te|=2;
			if(b<min(c,y)||max(c,y)<b)te|=1;
		//	if(a==sr)te|=2;
		//	if(a==kr)te|=1;
		//	printf("%d %d %d %d %d -> %d %d %d %d %d: %d\n",a,b,c,d,e,a+1,x,y,b,te,ks);
			dp[a+1][x][y][b][te]=min(dp[a+1][x][y][b][te],dp[a][b][c][d][e]+ks);
		}
	}
}
int main(){
	int a,b;
	scanf("%d%d",&a,&b);
	H=a;W=b;
	for(int i=0;i<a;i++)scanf("%s",str[i]);
	for(int i=0;i<12;i++)for(int j=0;j<12;j++)for(int k=0;k<12;k++)for(int l=0;l<12;l++)
		dp[i][j][k][l][0]=dp[i][j][k][l][1]=dp[i][j][k][l][2]=dp[i][j][k][l][3]=99999999;
	for(int i=0;i<a;i++)for(int j=0;j<b;j++){
		if(str[i][j]=='s'){sr=i;sc=j;}
		if(str[i][j]=='k'){kr=i;kc=j;}
		if(str[i][j]=='S'){SR=i;SC=j;}
		if(str[i][j]=='K'){KR=i;KC=j;}
	}
	if(SR>KR){
		swap(SR,KR);
		swap(SC,KC);
		swap(sr,kr);
		swap(sc,kc);
	}
	if(SR==KR){
		dp[SR][SC][KC][11][0]=0;
	}else if(SR<KR){
		dp[SR][SC][11][11][1]=0;
	}else{
		dp[SR][SC][11][11][2]=0;
	}
	int ret=99999999;
	for(int i=0;i<a;i++){
		for(int j=0;j<12;j++){
			for(int k=0;k<12;k++){
				for(int l=0;l<12;l++){
					for(int m=0;m<4;m++){
						if(dp[i][j][k][l][m]>999999)continue;
					//	printf("%d %d %d %d %d: %d\n",i,j,k,l,m,dp[i][j][k][l][m]);
						int t=0;
						if(j==11)t|=2;
						if(k==11)t|=1;
						if(j<W&&k<W&&k!=j)t|=3;
						if(i>=max(sr,kr)&&(m|t)==3)ret=min(ret,dp[i][j][k][l][m]);
						else upd(i,j,k,l,m);
					}
				}
			}
		}
	}
	if(SR>=sr||KR>=kr)ret=999999999;
	if(ret>999999)printf("CONTRACT\n");
	else printf("%d\n",ret);
}
accuracy: 0.5961538461538461
time_ms: 40
memory_kb: 1352
final_rank: 6

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
char str[12][12];
int dp[12][12][12][12][4];
int H,W;
int sr,sc,kr,kc,SR,SC,KR,KC;
inline int ABS(int a){return max(a,-a);}
inline void upd(int a,int b,int c,int d,int e){
	if(a>=sr){
		if(a>=kr)return;
		if(a+1<KR)dp[a+1][11][11][b][e|2]=min(dp[a+1][11][11][b][e|2],dp[a][b][c][d][e]);
		else if(a+1==KR)dp[a+1][11][KC][b][e|2]=min(dp[a+1][11][KC][b][e|2],dp[a][b][c][d][e]);
		else{
			for(int y=0;y<W;y++){
				bool d2=false;
				for(int z=min(y,c);z<=max(y,c);z++)if(str[a][z]=='#')d2=true;
				if(str[a+1][y]=='#')d2=true;
				if(a+1==kr&&kc!=y)d2=true;
				if(d2)continue;
				int x=b;
				int ks=0;
				int vt=0;
				for(int z=min(y,c);z<max(y,c);z++){
					bool iL=(min(b,x)<=z)&&(z<=max(b,x));
					bool iR=(min(b,x)<=z+1)&&(z+1<=max(b,x));
					if(!iL&&!iR)ks++;
					else if(!(iL&&iR)){
						if(!vt&&a==SR&&(z==SC||z+1==SC)){vt=1;ks++;}
						else if(!vt&&a==sr&&(z==sc||z+1==sc)){vt=1;ks++;}
						else ks+=2;
					}
				}
				if(d!=11&&a>KR&&min(b,d)<=c&&c<=max(b,d)&&min(b,x)<=c&&c<=max(b,x)){
					if(a-1==SR&&c==SC)ks--;
					else ks-=2;
				}
				if((SR!=a||y!=SC)&&min(b,x)<=y&&y<=max(b,x))ks+=2;
				else ks++;
				if(d!=11&&a>KR&&a<=sr&&min(b,x)<=c&&c<=max(b,x)&&!(min(b,d)<=c&&c<=max(b,d)))ks++;
				int te=e;
				if(c<min(b,x)||max(b,x)<c)te|=2;
				if(b<min(c,y)||max(c,y)<b)te|=1;
				dp[a+1][11][y][b][te]=min(dp[a+1][11][y][b][te],dp[a][b][c][d][e]+ks);
			}
		}
	}
	for(int x=0;x<W;x++){
		bool d1=false;
		for(int z=min(x,b);z<=max(x,b);z++)if(str[a][z]=='#')d1=true;
		if(str[a+1][x]=='#')d1=true;
		if(a+1==sr&&sc!=x)d1=true;
		
		if(d1)continue;
		if(a<KR){
			int ks=ABS(x-b)+1;
			if(a+1==KR)dp[a+1][x][KC][b][e|1]=min(dp[a+1][x][KC][b][e|1],dp[a][b][c][d][e]+ks);
			else dp[a+1][x][11][b][e|1]=min(dp[a+1][x][11][b][e|1],dp[a][b][c][d][e]+ks);
			continue;
		}
		if(a>=kr){
			int ks=ABS(x-b)+1;
			if(a==kr&&min(b,x)<=c&&c<=max(b,x))ks++;
			if(d!=11&&a>KR&&min(b,d)<=c&&c<=max(b,d)&&min(b,x)<=c&&c<=max(b,x)){
				if(a-1==SR&&c==SC)ks--;
				else ks-=2;
			}
			if(d!=11&&a>KR&&min(b,x)<=c&&c<=max(b,x)&&!(min(b,d)<=c&&c<=max(b,d)))ks++;
			int te=e|1;
			if(a==kr&&(c<min(b,x)||max(b,x)<c))te|=2;
			dp[a+1][x][11][b][te]=min(dp[a+1][x][11][b][te],dp[a][b][c][d][e]+ks);
			continue;
		}
		for(int y=0;y<W;y++){
			bool d2=false;
			for(int z=min(y,c);z<=max(y,c);z++)if(str[a][z]=='#')d2=true;
			if(str[a+1][y]=='#')d2=true;
			if(a+1==kr&&kc!=y)d2=true;
			if(a==SR&&a==KR&&min(b,x)<=c&&c<=max(b,x)&&min(c,y)<=b&&b<=max(c,y))continue;
			if(d2)continue;
			int ks=ABS(x-b)+1;
			int vt=0;
			for(int z=min(y,c);z<max(y,c);z++){
				bool iL=(min(b,x)<=z)&&(z<=max(b,x));
				bool iR=(min(b,x)<=z+1)&&(z+1<=max(b,x));
				if(!iL&&!iR)ks++;
				else if(!(iL&&iR)){
					if(!vt&&a==SR&&(z==SC||z+1==SC)){vt=1;ks++;}
					else if(!vt&&a==sr&&(z==sc||z+1==sc)){vt=1;ks++;}
					else ks+=2;
				}
			}
			if(d!=11&&a>KR&&min(b,d)<=c&&c<=max(b,d)&&min(b,x)<=c&&c<=max(b,x)){
				if(a-1==SR&&c==SC)ks--;
				else ks-=2;
			}
			if((SR!=a||y!=SC)&&min(b,x)<=y&&y<=max(b,x))ks+=2;
			else ks++;
			if(d!=11&&a>KR&&min(b,x)<=c&&c<=max(b,x)&&!(min(b,d)<=c&&c<=max(b,d)))ks++;
			int te=e;
			if(c<min(b,x)||max(b,x)<c)te|=2;
			if(b<min(c,y)||max(c,y)<b)te|=1;
		//	if(a==sr)te|=2;
		//	if(a==kr)te|=1;
		//	printf("%d %d %d %d %d -> %d %d %d %d %d: %d\n",a,b,c,d,e,a+1,x,y,b,te,ks);
			dp[a+1][x][y][b][te]=min(dp[a+1][x][y][b][te],dp[a][b][c][d][e]+ks);
		}
	}
}
int main(){
	int a,b;
	scanf("%d%d",&a,&b);
	H=a;W=b;
	for(int i=0;i<a;i++)scanf("%s",str[i]);
	for(int i=0;i<12;i++)for(int j=0;j<12;j++)for(int k=0;k<12;k++)for(int l=0;l<12;l++)
		dp[i][j][k][l][0]=dp[i][j][k][l][1]=dp[i][j][k][l][2]=dp[i][j][k][l][3]=99999999;
	for(int i=0;i<a;i++)for(int j=0;j<b;j++){
		if(str[i][j]=='s'){sr=i;sc=j;}
		if(str[i][j]=='k'){kr=i;kc=j;}
		if(str[i][j]=='S'){SR=i;SC=j;}
		if(str[i][j]=='K'){KR=i;KC=j;}
	}
	if(SR>KR){
		swap(SR,KR);
		swap(SC,KC);
		swap(sr,kr);
		swap(sc,kc);
	}
	if(SR==KR){
		dp[SR][SC][KC][11][0]=0;
	}else if(SR<KR){
		dp[SR][SC][11][11][1]=0;
	}else{
		dp[SR][SC][11][11][2]=0;
	}
	int ret=99999999;
	for(int i=0;i<a;i++){
		for(int j=0;j<12;j++){
			for(int k=0;k<12;k++){
				for(int l=0;l<12;l++){
					for(int m=0;m<4;m++){
						if(dp[i][j][k][l][m]>999999)continue;
					//	printf("%d %d %d %d %d: %d\n",i,j,k,l,m,dp[i][j][k][l][m]);
						int t=0;
						if(j==11)t|=2;
						if(k==11)t|=1;
						if(j<W&&k<W&&k!=j)t|=3;
						if(i>=max(sr,kr)&&(m|t)==3)ret=min(ret,dp[i][j][k][l][m]);
						else upd(i,j,k,l,m);
					}
				}
			}
		}
	}
	if(SR>=sr||KR>=kr)ret=999999999;
	if(ret>999999)printf("CONTRACT\n");
	else printf("%d\n",ret);
}
accuracy: 0.5961538461538461
time_ms: 40
memory_kb: 1356
final_rank: 7

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
char str[12][12];
int dp[12][12][12][12][4];
int H,W;
int sr,sc,kr,kc,SR,SC,KR,KC;
inline int ABS(int a){return max(a,-a);}
inline void upd(int a,int b,int c,int d,int e){
	if(a>=sr){
		if(a>=kr)return;
		if(a+1<KR)dp[a+1][11][11][b][e|2]=min(dp[a+1][11][11][b][e|2],dp[a][b][c][d][e]);
		else if(a+1==KR)dp[a+1][11][KC][b][e|2]=min(dp[a+1][11][KC][b][e|2],dp[a][b][c][d][e]);
		else{
			for(int y=0;y<W;y++){
				bool d2=false;
				for(int z=min(y,c);z<=max(y,c);z++)if(str[a][z]=='#')d2=true;
				if(str[a+1][y]=='#')d2=true;
				if(a+1==kr&&kc!=y)d2=true;
				if(d2)continue;
				int x=b;
				int ks=0;
				int vt=0;
				for(int z=min(y,c);z<max(y,c);z++){
					bool iL=(min(b,x)<=z)&&(z<=max(b,x));
					bool iR=(min(b,x)<=z+1)&&(z+1<=max(b,x));
					if(!iL&&!iR)ks++;
					else if(!(iL&&iR)){
						if(!vt&&a==SR&&(z==SC||z+1==SC)){vt=1;ks++;}
						else if(!vt&&a==sr&&(z==sc||z+1==sc)){vt=1;ks++;}
						else ks+=2;
					}
				}
				if(d!=11&&a>KR&&a<=sr&&min(b,d)<=c&&c<=max(b,d)&&min(b,x)<=c&&c<=max(b,x))ks-=2;
				if(min(b,x)<=y&&y<=max(b,x))ks+=2;
				else ks++;
				if(d!=11&&a>KR&&a<=sr&&min(b,x)<=c&&c<=max(b,x)&&!(min(b,d)<=c&&c<=max(b,d)))ks++;
				int te=e;
				if(c<min(b,x)||max(b,x)<c)te|=2;
				if(b<min(c,y)||max(c,y)<b)te|=1;
				dp[a+1][11][y][b][te]=min(dp[a+1][11][y][b][te],dp[a][b][c][d][e]+ks);
			}
		}
	}
	for(int x=0;x<W;x++){
		bool d1=false;
		for(int z=min(x,b);z<=max(x,b);z++)if(str[a][z]=='#')d1=true;
		if(str[a+1][x]=='#')d1=true;
		if(a+1==sr&&sc!=x)d1=true;
		
		if(d1)continue;
		if(a<KR){
			int ks=ABS(x-b)+1;
			if(a+1==KR)dp[a+1][x][KC][b][e|1]=min(dp[a+1][x][KC][b][e|1],dp[a][b][c][d][e]+ks);
			else dp[a+1][x][11][b][e|1]=min(dp[a+1][x][11][b][e|1],dp[a][b][c][d][e]+ks);
			continue;
		}
		if(a>=kr){
			int ks=ABS(x-b)+1;
			if(a==kr&&min(b,x)<=c&&c<=max(b,x))ks++;
			if(d!=11&&a>KR&&a<=kr&&min(b,d)<=c&&c<=max(b,d)&&min(b,x)<=c&&c<=max(b,x))ks-=2;
			if(d!=11&&a>KR&&min(b,x)<=c&&c<=max(b,x)&&!(min(b,d)<=c&&c<=max(b,d)))ks++;
			int te=e|1;
			if(a==kr&&(c<min(b,x)||max(b,x)<c))te|=2;
			dp[a+1][x][11][b][te]=min(dp[a+1][x][11][b][te],dp[a][b][c][d][e]+ks);
			continue;
		}
		for(int y=0;y<W;y++){
			bool d2=false;
			for(int z=min(y,c);z<=max(y,c);z++)if(str[a][z]=='#')d2=true;
			if(str[a+1][y]=='#')d2=true;
			if(a+1==kr&&kc!=y)d2=true;
			if(a==SR&&a==KR&&min(b,x)<=c&&c<=max(b,x)&&min(c,y)<=b&&b<=max(c,y))continue;
			if(d2)continue;
			int ks=ABS(x-b)+1;
			int vt=0;
			for(int z=min(y,c);z<max(y,c);z++){
				bool iL=(min(b,x)<=z)&&(z<=max(b,x));
				bool iR=(min(b,x)<=z+1)&&(z+1<=max(b,x));
				if(!iL&&!iR)ks++;
				else if(!(iL&&iR)){
					if(!vt&&a==SR&&(z==SC||z+1==SC)){vt=1;ks++;}
					else if(!vt&&a==sr&&(z==sc||z+1==sc)){vt=1;ks++;}
					else ks+=2;
				}
			}
			if(d!=11&&a>KR&&min(b,d)<=c&&c<=max(b,d)&&min(b,x)<=c&&c<=max(b,x))ks-=2;
			if(min(b,x)<=y&&y<=max(b,x))ks+=2;
			else ks++;
			if(d!=11&&a>KR&&min(b,x)<=c&&c<=max(b,x)&&!(min(b,d)<=c&&c<=max(b,d)))ks++;
			int te=e;
			if(c<min(b,x)||max(b,x)<c)te|=2;
			if(b<min(c,y)||max(c,y)<b)te|=1;
		//	if(a==sr)te|=2;
		//	if(a==kr)te|=1;
			dp[a+1][x][y][b][te]=min(dp[a+1][x][y][b][te],dp[a][b][c][d][e]+ks);
		}
	}
}
int main(){
	int a,b;
	scanf("%d%d",&a,&b);
	H=a;W=b;
	for(int i=0;i<a;i++)scanf("%s",str[i]);
	for(int i=0;i<12;i++)for(int j=0;j<12;j++)for(int k=0;k<12;k++)for(int l=0;l<12;l++)
		dp[i][j][k][l][0]=dp[i][j][k][l][1]=dp[i][j][k][l][2]=dp[i][j][k][l][3]=99999999;
	for(int i=0;i<a;i++)for(int j=0;j<b;j++){
		if(str[i][j]=='s'){sr=i;sc=j;}
		if(str[i][j]=='k'){kr=i;kc=j;}
		if(str[i][j]=='S'){SR=i;SC=j;}
		if(str[i][j]=='K'){KR=i;KC=j;}
	}
	if(SR>KR){
		swap(SR,KR);
		swap(SC,KC);
		swap(sr,kr);
		swap(sc,kc);
	}
	if(SR==KR){
		dp[SR][SC][KC][11][0]=0;
	}else if(SR<KR){
		dp[SR][SC][11][11][1]=0;
	}else{
		dp[SR][SC][11][11][2]=0;
	}
	int ret=99999999;
	for(int i=0;i<a;i++){
		for(int j=0;j<12;j++){
			for(int k=0;k<12;k++){
				for(int l=0;l<12;l++){
					for(int m=0;m<4;m++){
						if(dp[i][j][k][l][m]>999999)continue;
			//			printf("%d %d %d %d %d: %d\n",i,j,k,l,m,dp[i][j][k][l][m]);
						int t=0;
						if(j==11)t|=2;
						if(k==11)t|=1;
						if(j<W&&k<W&&k!=j)t|=3;
						if(i>=max(sr,kr)&&(m|t)==3)ret=min(ret,dp[i][j][k][l][m]);
						else upd(i,j,k,l,m);
					}
				}
			}
		}
	}
	if(SR>=sr||KR>=kr)ret=999999999;
	if(ret>999999)printf("CONTRACT\n");
	else printf("%d\n",ret);
}
accuracy: 0.5576923076923077
time_ms: 40
memory_kb: 1356
final_rank: 8

code_snippet: #include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <assert.h>
#include <vector>
#include <queue>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

struct Point {
  int state; // NG, OK
  int x;
  int y;
  int cost;
  Point() {;}
  Point(int state, int x, int y, int cost) : state(state), x(x), y(y), cost(cost) {;}
  bool operator<(const Point &rhs) const {
    return cost > rhs.cost;
  }
};

int h, w;
int rsx, rsy, rex, rey;
int bsx, bsy, bex, bey;
char field[20][20];

void PrintField() {
  REP(y, h) {
    REP(x, w) {
      printf("%c", field[y][x]);
    }
    puts("");
  }
}

bool visit[2][20][20];
int dist[2][20][20];
int calc() {
  const int dx[3] = { 1, 0, -1 };
  const int dy[3] = { 0, 1, 0, };
  priority_queue<Point> que;
  int initialState = 0;
  if (field[bsy][bsx] != 'K') { initialState = 1; }
  que.push(Point(initialState, bsx, bsy, 0));
  MEMSET(visit, 0);
  MEMSET(dist, 0x0f);
  while (!que.empty()) {
    Point p = que.top();
    que.pop();
    if (visit[p.state][p.y][p.x]) { continue; }
    visit[p.state][p.y][p.x] = true;
    if (p.state == 1 && p.x == bex && p.y == bey) {
      if (field[p.y][p.x] == 'K') { p.cost++; }
      return p.cost;
    }
    if (p.y == bey) { continue; }
    REP(dir, 3) {
      int nx = p.x + dx[dir];
      int ny = p.y + dy[dir];
      if (nx < 0 || nx >= w || ny < 0 || ny >= h) { continue; }
      if (nx == rsx && ny == rsy) { continue; }
      if (field[ny][nx] == '#') { continue; }
      int nstate = p.state;
      if (dir == 1 && field[ny][nx] != 'K') {
        nstate = 1;
      }
      int ncost = p.cost;
      if (field[p.y][p.x] == 'K' && field[ny][nx] == 'K') {;}
      else if (field[p.y][p.x] == 'K' || field[ny][nx] == 'K') { ncost += 2; }
      else if (field[p.y][p.x] == '.' && field[ny][nx] == '.') { ncost++; }

      if (visit[nstate][ny][nx] == '#') { continue; }
      if (dist[nstate][ny][nx] <= ncost) { continue; }
      dist[nstate][ny][nx] = ncost;
      que.push(Point(nstate, nx, ny, ncost));
    }
  }
  return 1 << 30;
}

int Init(int x, int y, int dir, int movey) {
  int ret = 1 << 30;
  if (x < 0 || x >= w || y < 0 || y >= h) { return 1 << 30; }
  if (field[y][x] != '.') { return 1 << 30; }
  if (movey != 1 && dir != -1) {
    for (int ny = y; ny >= 0; ny--) {
      if ((x == bsx && ny == bsy) ||
          (x == bex && ny == bey) ||
          field[ny][x] == '#') { break; }
      if (field[ny][x] == 'K') { return 1 << 30; }
    }
  }
  field[y][x] = 'K';
  if (x == rex && y == rey) {
    ret = calc();
  } else if (y == rey) {;}
  else {
    const int dx[2] = { 1, -1 };
    REP(i, 2) {
      int nx = x + dx[i];
      ret = min(ret, Init(nx, y, i, 0) + 1);
    }
    ret = min(ret, Init(x, y + 1, dir, 1) + 1);
  }
  field[y][x] = '.';
  return ret;
}

int main() {
  while (scanf("%d %d", &h, &w) > 0) {
    REP(y, h) {
      int v = scanf("%s", field[y]);
      assert(v == 1);
    }
    REP(y, h) REP(x, w) {
      if (field[y][x] == 'K') { rsx = x; rsy = y; field[y][x] = '.'; }
      if (field[y][x] == 'S') { bsx = x; bsy = y; field[y][x] = '.'; }
      if (field[y][x] == 'k') { rex = x; rey = y; field[y][x] = '.'; }
      if (field[y][x] == 's') { bex = x; bey = y; field[y][x] = '.'; }
    }
    int ans = 1 << 30;
    if (rsy >= rey || bsy >= bey) {}
    else {
      ans = min(ans, Init(rsx, rsy, -1, 1));
      swap(rsx, bsx);
      swap(rsy, bsy);
      swap(rex, bex);
      swap(rey, bey);
      ans = min(ans, Init(rsx, rsy, -1, 1));
    }
    if (ans >= (1 << 30)) puts("CONTRACT");
    else printf("%d\n", ans);
  }
}
accuracy: 1
time_ms: 550
memory_kb: 0
final_rank: 2