Problem:
Problem D:
Dr. Nakamura's Lab.
Dr.中村は偉大な発明者である, 今日も常人には発想出来ない新たな発明に取り掛かっている. 今発明しているのは新たな防犯システムとコンテナである.
防犯システムの方は上に乗った者を識別して招かれざる客だった場合, 電流を流して気絶させるパネルである. このパネルは踏まないように上を通過しても無駄で, 空中のものに対し放電する. しかし, まだ完成には程遠く, 電流は強すぎて調節が不可能で, 一度放電すると充電しない限り使えない. また, 人と物体の区別ができず, そもそも人自体区別できない等欠点をあげればキリがない.
コンテナの方は謎の力によって常時地面から浮いており, 運ぶのに便利に作ってある. しかし, これも完成には遠く, 一度押すと何かにぶつかるまで止まらない.
Dr.中村は一日の作業を終え, 帰宅しようとしたが未完成のパネルを設置したままだということに気づいた. これを取り外すのは防犯上非常に困難に作ってある上に, これを通らなければ帰れないような位置に設置してしまったのでDr.中村は途方に暮れた. しかし, 素晴らしい頭脳を持つDr.中村は解決案をすぐに思いついた. パネルは一度放電させれば通れるようになるため, コンテナを通過させればパネルの上を通れるようになる, そう考えた. 実際, パネルの上にコンテナを通過させると, コンテナは電流によって消滅してしまう一方でパネルは放電し, 通れるようになる.
しかし, 研究室の中は入り組んでおり, うまくコンテナを動かさないとパネルを通過させられない. Dr.中村は助手であるあなたにメールで助けを求めた. あなたの仕事は研究室の情報が与えられた時にDr.中村が出口までたどり着くためのプログラムを作成することである.
研究室は二次元グリッドで与えられ, Dr.中村は一度の移動で上下左右に隣接するセルに移動することが出来る.ただし, 障害物, コンテナ, 放電していないパネルのセルには移動できない.
Dr.中村は上下左右に隣接するセルにあるコンテナを押すことができ, コンテナはDr.中村がいる方向と逆の方向に別のコンテナか障害物にぶつかる, あるいは放電されていないパネルの上を通過するまで動く. また, 何かにぶつかり止まった場合, ぶつかる直前のセルで静止する.
出口はコンテナもDr.中村も侵入可能である. コンテナは出口を通っても消滅せず、そのまま通過する.
壁にぶつかって出口をふさぐことはある. この場合は出口に進入できない.
あなたのプログラムが要求されていることは, Dr.中村は最少何回の移動で研究室を脱出できるかを出力することのみである. なぜなら, Dr.中村は素晴らしい頭脳の持ち主なのでそれさえわかれば自分で脱出するからである.
Input
入力は複数のデータセットからなり, 一行目に研究室の縦の長さ H と横の長さ W が与えられる.
2行目以降では研究室の状態が H × W 個の文字で表わされる. 各文字が表すものは以下のとおりである:
‘
#
’障害物を表す.
‘
@
’Dr.中村の初期位置を表す.
‘
w
’パネルを表す.
‘
c
’コンテナを表す.
‘
.
’何も置かれていない空白のセルを表す.
‘
E
’脱出口を表す.
縦と横の長さがともに 0 のとき入力の終了を表す. これについて処理をする必要はない.
以下のことを仮定してよい.
3 ≤ H, W ≤ 10
研究室の周囲は障害物で囲まれている.
パネルとコンテナの数はそれぞれ 3 を越えない.
研究室にはただ１つの出口がある.
Output
各データセットについて最少の移動回数を１行に出力せよ. なお、Dr.中村が脱出できない場合、”
-1
”と出力せよ.
Sample Input
5 5
#####
##@##
#wc.#
#Ew.#
#####
5 5
#####
##@.#
#wc.#
#E#.#
#####
3 6
######
#@.wE#
######
0 0
Output for the Sample Input
3
5
-1

Submitted solutions:

code_snippet: #include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define REP(i, a, n) for (int i = (a); i < (n); i++)
#define rep(i, n) REP(i, 0, n)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define foreach(it, x) for (typeof((x).begin()) it = (x).begin(); it != (x).end(); it++)
const int dx[] = {0, 1, 0, -1};
const int dy[] = {-1, 0, 1, 0};
int W, H, sx, sy, gx, gy;
int bfscost[10][10];
char csize, wsize, wx[3], wy[3], cx[3], cy[3];
char field[16][16];
char DP[9][9][9][9][9][9][9][9];
struct state {
  char x, y, cx[3], cy[3], Sc;
  state(char _x, char _y, char _cx[], char _cy[], char _Sc) {
    x = _x, y = _y, Sc = _Sc;
    cx[0] = _cx[0], cx[1] = _cx[1], cx[2] = _cx[2];
    cy[0] = _cy[0], cy[1] = _cy[1], cy[2] = _cy[2];
  }
  bool operator<(const state &a) const {
    if (x != a.x) return x < a.x;
    if (y != a.y) return y < a.y;
    if (cx[0] != a.cx[0]) return cx[0] < a.cx[0];
    if (cx[1] != a.cx[1]) return cx[1] < a.cx[1];
    if (cx[2] != a.cx[2]) return cx[2] < a.cx[2];
    if (cy[0] != a.cy[0]) return cy[0] < a.cy[0];
    if (cy[1] != a.cy[1]) return cy[1] < a.cy[1];
    if (cy[2] != a.cy[2]) return cy[2] < a.cy[2];
    return Sc < a.Sc;
  }
  bool operator==(const state &a) const {
    return (x == a.x && y == a.y &&
            (cx[0] == a.cx[0] && cx[1] == a.cx[1] && cx[2] == a.cx[2]) &&
            (cy[0] == a.cy[0] && cy[1] == a.cy[1] && cy[2] == a.cy[2]) &&
            Sc == a.Sc);
  }
};
bool isdel(char tx, char ty, char ncx[], char ncy[]) {
  if (field[ty][tx] != 'w') return true;
  rep(i, csize) if (ncx[i] == tx && ncy[i] == ty) return true;
  return false;
}
bool iscontena(char tx, char ty, char ncx[], char ncy[], char Sc) {
  rep(i, csize) if (ncx[i] == tx && ncy[i] == ty && !(Sc & (1 << i))) return true;
  return false;
}
void BFS(char nx, char ny, char ncx[], char ncy[], char Sc) {
  memset(bfscost, -1, sizeof(bfscost));
  bfscost[ny][nx] = 0;
  queue<pair<int, int>> q;
  q.push(make_pair(nx, ny));
  while (!q.empty()) {
    int x = q.front().first, y = q.front().second;
    int cost = bfscost[y][x];
    q.pop();
    rep(k, 4) {
      int tx = x + dx[k];
      int ty = y + dy[k];
      if (field[ty][tx] == '#' || bfscost[ty][tx] != -1 || iscontena(tx, ty, ncx, ncy, Sc))
        continue;
      if (field[ty][tx] == 'w' && !isdel(tx, ty, ncx, ncy)) continue;
      bfscost[ty][tx] = cost + 1;
      q.push(make_pair(tx, ty));
    }
  }
}
void input() {
  rep(i, H) {
    scanf("%s", field[i]);
    rep(j, W) {
      if (field[i][j] == '@') sx = j, sy = i;
      if (field[i][j] == 'E') gx = j, gy = i;
      if (field[i][j] == 'w') wx[wsize] = j, wy[wsize] = i, wsize++;
      if (field[i][j] == 'c') cx[csize] = j, cy[csize] = i, csize++;
    }
  }
}
int main() {
  while (scanf("%d%d", &H, &W), H | W) {
    csize = wsize = 0;
    memset(DP, -1, sizeof(DP));
    rep(i, 3) cx[i] = cy[i] = 0;
    input();
    int res = INT_MAX;
    priority_queue<pair<int, state>, vector<pair<int, state>>, greater<pair<int, state>>> q;
    q.push(make_pair(0, state(sx, sy, cx, cy, 0)));
    DP[cx[0]][cy[0]][cx[1]][cy[1]][cx[2]][cy[2]][sx][sy] = 0;
    while (!q.empty()) {
      int cost = q.top().first;
      char nx = q.top().second.x, ny = q.top().second.y;
      char tSc = q.top().second.Sc;
      char ncx[3], ncy[3];
      rep(i, csize) ncx[i] = q.top().second.cx[i], ncy[i] = q.top().second.cy[i];
      q.pop();
      if (res <= cost) break;
      BFS(nx, ny, ncx, ncy, tSc);
      if (bfscost[gy][gx] != -1) res = min(res, cost + bfscost[gy][gx]);
      rep(i, csize) if (!(tSc & (1 << i))) {
        rep(j, 4) {
          int tx = ncx[i] + dx[j];
          int ty = ncy[i] + dy[j];
          if (bfscost[ty][tx] == -1) continue;
          int ttSc = tSc;
          int dir = (j + 2) % 4;
          int tcx = ncx[i], tcy = ncy[i];
          for (;;) {
            int ay = tcy + dy[dir];
            int ax = tcx + dx[dir];
            if (field[ay][ax] == '#' || iscontena(ax, ay, ncx, ncy, tSc)) break;
            tcx += dx[dir];
            tcy += dy[dir];
            if (field[ay][ax] == 'w' && !isdel(ax, ay, ncx, ncy)) {
              ttSc |= 1 << i;
              break;
            }
          }
          if (tcx == ncx[i] && tcy == ncy[i]) continue;
          char ttcx[3], ttcy[3];
          rep(k, csize) ttcx[k] = ncx[k], ttcy[k] = ncy[k];
          ttcx[i] = tcx, ttcy[i] = tcy;
          char *dpp = &DP[ttcx[0]][ttcy[0]][ttcx[1]][ttcy[1]][ttcx[2]][ttcy[2]][tx][ty];
          if (*dpp == -1 || *dpp > cost + bfscost[ty][tx]) {
            *dpp = cost + bfscost[ty][tx];
            q.push(make_pair(cost + bfscost[ty][tx], state(tx, ty, ttcx, ttcy, ttSc)));
          }
        }
      }
    }
    printf("%d\n", (res == INT_MAX ? -1 : res));
  }
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 45588
final_rank: 18

code_snippet: #include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define REP(i, a, n) for (i = a; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define foreach(it, x)                                                         \
  for (typeof(x.begin()) it = x.begin(); it != x.end(); it++)
const int dx[] = {0, 1, 0, -1};
const int dy[] = {-1, 0, 1, 0};
int W, H, sx, sy, gx, gy;
int bfscost[10][10];
char csize, wsize, wx[3], wy[3], cx[3], cy[3];
char field[16][16];
char DP[9][9][9][9][9][9][9][9];
struct state {
  char x, y, cx[3], cy[3], Sc;
  state(char _x, char _y, char _cx[], char _cy[], char _Sc) {
    x = _x, y = _y, Sc = _Sc;
    cx[0] = _cx[0], cx[1] = _cx[1], cx[2] = _cx[2];
    cy[0] = _cy[0], cy[1] = _cy[1], cy[2] = _cy[2];
  }
  bool operator<(const state &a) const {
    if (x != a.x)
      return x < a.x;
    if (y != a.y)
      return y < a.y;
    if (cx[0] != a.cx[0])
      return cx[0] < a.cx[0];
    if (cx[1] != a.cx[1])
      return cx[1] < a.cx[1];
    if (cx[2] != a.cx[2])
      return cx[2] < a.cx[2];
    if (cy[0] != a.cy[0])
      return cy[0] < a.cy[0];
    if (cy[1] != a.cy[1])
      return cy[1] < a.cy[1];
    if (cy[2] != a.cy[2])
      return cy[2] < a.cy[2];
    return Sc < a.Sc;
  }
  bool operator==(const state &a) const {
    return (x == a.x && y == a.y &&
            (cx[0] == a.cx[0] && cx[1] == a.cx[1] && cx[2] == a.cx[2]) &&
            (cy[0] == a.cy[0] && cy[1] == a.cy[1] && cy[2] == a.cy[2]) &&
            Sc == a.Sc);
  }
};
bool isdel(char tx, char ty, char ncx[], char ncy[]) {
  int i;
  if (field[ty][tx] != 'w')
    return true;
  rep(i, csize) if (ncx[i] == tx && ncy[i] == ty) return true;
  return false;
}
bool iscontena(char tx, char ty, char ncx[], char ncy[], char Sc) {
  int i;
  rep(i,
      csize) if (ncx[i] == tx && ncy[i] == ty && !(Sc & (1 << i))) return true;
  return false;
}
void BFS(char nx, char ny, char ncx[], char ncy[], char Sc) {
  int i, j, k;
  memset(bfscost, -1, sizeof(bfscost));
  bfscost[ny][nx] = 0;
  queue<pair<int, int>> q;
  q.push(make_pair(nx, ny));
  while (!q.empty()) {
    int x = q.front().first, y = q.front().second;
    int cost = bfscost[y][x];
    q.pop();
    rep(k, 4) {
      int tx = x + dx[k];
      int ty = y + dy[k];
      if (field[ty][tx] == '#' || bfscost[ty][tx] != -1 ||
          iscontena(tx, ty, ncx, ncy, Sc))
        continue;
      if (field[ty][tx] == 'w' && !isdel(tx, ty, ncx, ncy))
        continue;
      bfscost[ty][tx] = cost + 1;
      q.push(make_pair(tx, ty));
    }
  }
}
void input() {
  int i, j;
  rep(i, H) {
    scanf("%s", field[i]);
    rep(j, W) {
      if (field[i][j] == '@')
        sx = j, sy = i;
      if (field[i][j] == 'E')
        gx = j, gy = i;
      if (field[i][j] == 'w') {
        wx[wsize] = j, wy[wsize] = i;
        wsize++;
      }
      if (field[i][j] == 'c') {
        cx[csize] = j, cy[csize] = i;
        csize++;
      }
    }
  }
}
int main() {
  int i, j, k;
  while (scanf("%d%d", &H, &W), H | W) {
    csize = wsize = 0;
    memset(DP, -1, sizeof(DP));
    rep(i, 3) cx[i] = cy[i] = 0;
    input();
    int res = INT_MAX;
    priority_queue<pair<int, state>, vector<pair<int, state>>,
                   greater<pair<int, state>>>
        q;
    q.push(make_pair(0, state(sx, sy, cx, cy, 0)));
    DP[cx[0]][cy[0]][cx[1]][cy[1]][cx[2]][cy[2]][sx][sy] = 0;
    while (!q.empty()) {
      int cost = q.top().first;
      char nx = q.top().second.x, ny = q.top().second.y;
      char tSc = q.top().second.Sc;
      char ncx[3], ncy[3];
      rep(i, 3) ncx[i] = ncy[i] = 0;
      rep(i, csize) ncx[i] = q.top().second.cx[i],
                    ncy[i] = q.top().second.cy[i];
      q.pop();
      if (res <= cost)
        break;
      BFS(nx, ny, ncx, ncy, tSc);
      if (bfscost[gy][gx] != -1)
        res = min(res, cost + bfscost[gy][gx]);
      rep(i, csize) if (!(tSc & (1 << i))) {
        rep(j, 4) {
          int tx = ncx[i] + dx[j];
          int ty = ncy[i] + dy[j];
          if (bfscost[ty][tx] == -1)
            continue;
          int ttSc = tSc;
          int dir = (j + 2) % 4;
          int tcx = ncx[i], tcy = ncy[i];
          for (;;) {
            int ay = tcy + dy[dir];
            int ax = tcx + dx[dir];
            if (field[ay][ax] == '#' || iscontena(ax, ay, ncx, ncy, tSc))
              break;
            tcx += dx[dir];
            tcy += dy[dir];
            if (field[ay][ax] == 'w' && !isdel(ax, ay, ncx, ncy)) {
              ttSc |= 1 << i;
              break;
            }
          }
          if (tcx == ncx[i] && tcy == ncy[i])
            continue;
          char ttcx[3], ttcy[3];
          rep(k, 3) ttcx[i] = ttcy[i] = 0;
          rep(k, csize) ttcx[k] = ncx[k], ttcy[k] = ncy[k];
          ttcx[i] = tcx, ttcy[i] = tcy;
          char *dpp =
              &DP[ttcx[0]][ttcy[0]][ttcx[1]][ttcy[1]][ttcx[2]][ttcy[2]][tx][ty];
          if (*dpp == -1 || *dpp > cost + bfscost[ty][tx]) {
            *dpp = cost + bfscost[ty][tx];
            q.push(make_pair(cost + bfscost[ty][tx],
                             state(tx, ty, ttcx, ttcy, ttSc)));
          }
        }
      }
    }
    printf("%d\n", res == INT_MAX ? -1 : res);
  }
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 45668
final_rank: 19

code_snippet: #include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define REP(i, a, n) for (i = a; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define foreach(it, x)                                                         \
  for (typeof(x.begin()) it = x.begin(); it != x.end(); it++)
const int dx[] = {0, 1, 0, -1};
const int dy[] = {-1, 0, 1, 0};
int W, H, sx, sy, gx, gy;
int bfscost[10][10];
char csize, wsize, wx[3], wy[3], cx[3], cy[3];
char field[16][16];
struct state {
  char x, y, cx[3], cy[3], Sc;
  state(char _x, char _y, char _cx[], char _cy[], char _Sc) {
    x = _x, y = _y, Sc = _Sc;
    cx[0] = _cx[0], cx[1] = _cx[1], cx[2] = _cx[2];
    cy[0] = _cy[0], cy[1] = _cy[1], cy[2] = _cy[2];
  }
  bool operator<(const state &a) const {
    if (x != a.x)
      return x < a.x;
    if (y != a.y)
      return y < a.y;
    if (cx[0] != a.cx[0])
      return cx[0] < a.cx[0];
    if (cx[1] != a.cx[1])
      return cx[1] < a.cx[1];
    if (cx[2] != a.cx[2])
      return cx[2] < a.cx[2];
    if (cy[0] != a.cy[0])
      return cy[0] < a.cy[0];
    if (cy[1] != a.cy[1])
      return cy[1] < a.cy[1];
    if (cy[2] != a.cy[2])
      return cy[2] < a.cy[2];
    return Sc < a.Sc;
  }
  bool operator==(const state &a) const {
    return (x == a.x && y == a.y &&
            (cx[0] == a.cx[0] && cx[1] == a.cx[1] && cx[2] == a.cx[2]) &&
            (cy[0] == a.cy[0] && cy[1] == a.cy[1] && cy[2] == a.cy[2]) &&
            Sc == a.Sc);
  }
};
bool isdel(char tx, char ty, char ncx[], char ncy[]) {
  int i;
  if (field[ty][tx] != 'w')
    return true;
  rep(i, csize) if (ncx[i] == tx && ncy[i] == ty) return true;
  return false;
}
bool iscontena(char tx, char ty, char ncx[], char ncy[], char Sc) {
  int i;
  rep(i,
      csize) if (ncx[i] == tx && ncy[i] == ty && !(Sc & (1 << i))) return true;
  return false;
}
void BFS(char nx, char ny, char ncx[], char ncy[], char Sc) {
  int i, j, k;
  memset(bfscost, -1, sizeof(bfscost));
  bfscost[ny][nx] = 0;
  queue<pair<int, int>> q;
  q.push(make_pair(nx, ny));
  while (!q.empty()) {
    int x = q.front().first, y = q.front().second;
    int cost = bfscost[y][x];
    q.pop();
    rep(k, 4) {
      int tx = x + dx[k];
      int ty = y + dy[k];
      if (field[ty][tx] == '#' || bfscost[ty][tx] != -1 ||
          iscontena(tx, ty, ncx, ncy, Sc))
        continue;
      if (field[ty][tx] == 'w' && !isdel(tx, ty, ncx, ncy))
        continue;
      bfscost[ty][tx] = cost + 1;
      q.push(make_pair(tx, ty));
    }
  }
}
void input() {
  int i, j;
  rep(i, H) {
    scanf("%s", field[i]);
    rep(j, W) {
      if (field[i][j] == '@')
        sx = j, sy = i;
      if (field[i][j] == 'E')
        gx = j, gy = i;
      if (field[i][j] == 'w') {
        wx[wsize] = j, wy[wsize] = i;
        wsize++;
      }
      if (field[i][j] == 'c') {
        cx[csize] = j, cy[csize] = i;
        csize++;
      }
    }
  }
}
int main() {
  int i, j, k;
  map<state, int> dp;
  while (scanf("%d%d", &H, &W), H | W) {
    dp.clear();
    csize = wsize = 0;
    rep(i, 3) cx[i] = cy[i] = 0;
    input();
    int res = INT_MAX;
    priority_queue<pair<int, state>, vector<pair<int, state>>,
                   greater<pair<int, state>>>
        q;
    q.push(make_pair(0, state(sx, sy, cx, cy, 0)));
    while (!q.empty()) {
      int cost = q.top().first;
      char nx = q.top().second.x, ny = q.top().second.y;
      char tSc = q.top().second.Sc;
      char ncx[3], ncy[3];
      rep(i, 3) ncx[i] = ncy[i] = 0;
      rep(i, csize) ncx[i] = q.top().second.cx[i],
                    ncy[i] = q.top().second.cy[i];
      q.pop();
      if (res <= cost)
        break;
      BFS(nx, ny, ncx, ncy, tSc);
      if (bfscost[gy][gx] != -1)
        res = min(res, cost + bfscost[gy][gx]);
      rep(i, csize) if (!(tSc & (1 << i))) {
        rep(j, 4) {
          int tx = ncx[i] + dx[j];
          int ty = ncy[i] + dy[j];
          if (bfscost[ty][tx] == -1)
            continue;
          int ttSc = tSc;
          int dir = (j + 2) % 4;
          int tcx = ncx[i], tcy = ncy[i];
          for (;;) {
            int ay = tcy + dy[dir];
            int ax = tcx + dx[dir];
            if (field[ay][ax] == '#' || iscontena(ax, ay, ncx, ncy, tSc))
              break;
            tcx += dx[dir];
            tcy += dy[dir];
            if (field[ay][ax] == 'w' && !isdel(ax, ay, ncx, ncy)) {
              ttSc |= 1 << i;
              break;
            }
          }
          if (tcx == ncx[i] && tcy == ncy[i])
            continue;
          char ttcx[3], ttcy[3];
          rep(k, 3) ttcx[i] = ttcy[i] = 0;
          rep(k, csize) ttcx[k] = ncx[k], ttcy[k] = ncy[k];
          ttcx[i] = tcx, ttcy[i] = tcy;
          if (dp.count(state(tx, ty, ttcx, ttcy, ttSc)) == 0 ||
              dp[state(tx, ty, ttcx, ttcy, ttSc)] > cost + bfscost[ty][tx]) {
            dp[state(tx, ty, ttcx, ttcy, ttSc)] = cost + bfscost[ty][tx];
            q.push(make_pair(cost + bfscost[ty][tx],
                             state(tx, ty, ttcx, ttcy, ttSc)));
          }
        }
      }
    }
    printf("%d\n", res == INT_MAX ? -1 : res);
  }
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3600
final_rank: 1

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


struct Info{
	char table[10][11];
	int current_row,current_col,sum_cost;
};

int H,W,goal_row,goal_col;
int diff_row[4] = {-1,0,0,1},diff_col[4] = {0,-1,1,0};
map<ll,bool>MAP;

ll makeCode(char table[10][11]){

	ll ret,nakamura_pos,panel[3] = {0,0,0},container[3] = {0,0,0},p_index = 0,c_index = 0;

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			switch(table[row][col]){
			case '@':
				nakamura_pos = 10*row+col;
				break;
			case 'w':
				panel[p_index++] = 10*row+col;
				break;
			case 'c':
				container[c_index++] = 10*row+col;
				break;
			default:
				//Do nothing
				break;
			}
		}
	}

	ret = nakamura_pos*1000000000000;
	ret += panel[0]*10000000000+panel[1]*100000000+panel[2]*1000000;
	ret += container[0]*10000+container[1]*100+container[2];

	return ret;
}

void copyInfo(Info& to,Info from){

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++)to.table[row][col] = from.table[row][col];
	}
	to.sum_cost = from.sum_cost;
}

void func(){

	MAP.clear();

	Info first;
	first.sum_cost = 0;

	for(int row = 0; row < H; row++){
		scanf("%s",first.table[row]);
		for(int col = 0; col < W; col++){
			if(first.table[row][col] == '@'){
				first.current_row = row;
				first.current_col = col;
			}else if(first.table[row][col] == 'E'){
				goal_row = row;
				goal_col = col;
			}
		}
	}

	ll tmp_code = makeCode(first.table);
	MAP[tmp_code] = true;

	queue<Info> Q;
	Q.push(first);

	int adj_row,adj_col,next_row,next_col;

	while(!Q.empty()){

		if(Q.front().current_row == goal_row && Q.front().current_col == goal_col){
			printf("%d\n",Q.front().sum_cost);
			return;
		}else{

			for(int i = 0; i < 4; i++){
				adj_row = Q.front().current_row+diff_row[i];
				adj_col = Q.front().current_col+diff_col[i];

				if(Q.front().table[adj_row][adj_col] == '#' || Q.front().table[adj_row][adj_col] == 'w')continue;

				if(Q.front().table[adj_row][adj_col] == 'c'){

					next_row = -1;

					switch(i){
					case 0:
						for(int row = adj_row; row >= 0; row--){
							switch(Q.front().table[row-1][adj_col]){
							case '.':
							case 'E':
								//Do nothing
								break;
							case '#':
								next_row = row;
								next_col = adj_col;
								break;
							case 'w':
								next_row = row-1;
								next_col = adj_col;
								break;
							case 'c':
								next_row = row;
								next_col = adj_col;
								break;
							}
							if(next_row != -1)break;
						}
						break;
					case 1:
						for(int col = adj_col; col >= 0; col--){
							switch(Q.front().table[adj_row][col-1]){
							case '.':
							case 'E':
								//Do nothing
								break;
							case '#':
								next_row = adj_row;
								next_col = col;
								break;
							case 'w':
								next_row = adj_row;
								next_col = col-1;
								break;
							case 'c':
								next_row = adj_row;
								next_col = col;
								break;
							}
							if(next_row != -1)break;
						}

						break;
					case 2:
						for(int col = adj_col; col <= W-1; col++){
							switch(Q.front().table[adj_row][col+1]){
							case '.':
							case 'E':
								//Do nothing
								break;
							case '#':
								next_row = adj_row;
								next_col = col;
								break;
							case 'w':
								next_row = adj_row;
								next_col = col+1;
								break;
							case 'c':
								next_row = adj_row;
								next_col = col;
								break;
							}
							if(next_row != -1)break;
						}

						break;
					case 3:
						for(int row = adj_row; row <= H-1; row++){
							switch(Q.front().table[row+1][adj_col]){
							case '.':
							case 'E':
								//Do nothing
								break;
							case '#':
								next_row = row;
								next_col = adj_col;
								break;
							case 'w':
								next_row = row+1;
								next_col = adj_col;
								break;
							case 'c':
								next_row = row;
								next_col = adj_col;
								break;
							}
							if(next_row != -1)break;
						}
						break;
					}

					if(adj_row == next_row && adj_col == next_col)continue;

					Info next_info;
					copyInfo(next_info,Q.front());

					next_info.table[adj_row][adj_col] = '.';

					switch(next_info.table[next_row][next_col]){
					case '.':
					case 'E':
						next_info.table[next_row][next_col] = 'c';
						break;
					case 'w':
						next_info.table[next_row][next_col] = '.';
						break;
					}

					tmp_code = makeCode(next_info.table);

					auto at = MAP.find(tmp_code);

					if(at != MAP.end())continue;

					next_info.current_row = Q.front().current_row;
					next_info.current_col = Q.front().current_col;

					Q.push(next_info);

				}else{ //'E'or'.'

					Info next_info;
					copyInfo(next_info,Q.front());
					next_info.table[adj_row][adj_col] = '@';
					next_info.table[Q.front().current_row][Q.front().current_col] = '.';

					tmp_code = makeCode(next_info.table);

					auto at = MAP.find(tmp_code);
					if(at != MAP.end())continue;

					MAP[tmp_code] = true;
					next_info.sum_cost++;
					next_info.current_row = adj_row;
					next_info.current_col = adj_col;

					Q.push(next_info);
				}
			}
			Q.pop();
		}
	}
	printf("-1\n");
}

int main(){

	while(true){
		scanf("%d %d",&H,&W);
		if(H == 0 && W == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 6376
final_rank: 3

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


struct Info{
	char table[10][11];
	int current_row,current_col,sum_cost;
};

int H,W,goal_row,goal_col;
int diff_row[4] = {-1,0,0,1},diff_col[4] = {0,-1,1,0};
map<ll,bool>MAP;

ll makeCode(char table[10][11]){

	ll ret,nakamura_pos,panel[3] = {0,0,0},container[3] = {0,0,0},p_index = 0,c_index = 0;

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			switch(table[row][col]){
			case '@':
				nakamura_pos = 10*row+col;
				break;
			case 'w':
				panel[p_index++] = 10*row+col;
				break;
			case 'c':
				container[c_index++] = 10*row+col;
				break;
			default:
				//Do nothing
				break;
			}
		}
	}

	ret = nakamura_pos*1000000000000;
	ret += panel[0]*10000000000+panel[1]*100000000+panel[2]*1000000;
	ret += container[0]*10000+container[1]*100+container[2];

	return ret;
}

void copyInfo(Info& to,Info from){

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++)to.table[row][col] = from.table[row][col];
	}
	to.sum_cost = from.sum_cost;
}

void func(){

	MAP.clear();

	Info first;
	first.sum_cost = 0;

	for(int row = 0; row < H; row++){
		scanf("%s",first.table[row]);
		for(int col = 0; col < W; col++){
			if(first.table[row][col] == '@'){
				first.current_row = row;
				first.current_col = col;
			}else if(first.table[row][col] == 'E'){
				goal_row = row;
				goal_col = col;
			}
		}
	}

	ll tmp_code = makeCode(first.table);
	MAP[tmp_code] = true;

	queue<Info> Q;
	Q.push(first);

	int adj_row,adj_col,next_row,next_col;

	while(!Q.empty()){

		if(Q.front().current_row == goal_row && Q.front().current_col == goal_col){
			printf("%d\n",Q.front().sum_cost);
			return;
		}else{

			for(int i = 0; i < 4; i++){
				adj_row = Q.front().current_row+diff_row[i];
				adj_col = Q.front().current_col+diff_col[i];

				if(Q.front().table[adj_row][adj_col] == '#' || Q.front().table[adj_row][adj_col] == 'w')continue; //?£???????????????????SKIP

				if(Q.front().table[adj_row][adj_col] == 'c'){ //?????????????????´???

					next_row = -1;

					switch(i){
					case 0: //???????????????????????????????????????
						for(int row = adj_row; row >= 0; row--){
							switch(Q.front().table[row-1][adj_col]){
							case '.':
							case 'E':
								//Do nothing
								break;
							case '#':
								next_row = row;
								next_col = adj_col;
								break;
							case 'w':
								next_row = row-1;
								next_col = adj_col;
								break;
							case 'c':
								next_row = row;
								next_col = adj_col;
								break;
							}
							if(next_row != -1)break;
						}
						break;
					case 1: //???????????????????????????????????????

						for(int col = adj_col; col >= 0; col--){
							switch(Q.front().table[adj_row][col-1]){
							case '.':
							case 'E':
								//Do nothing
								break;
							case '#':
								next_row = adj_row;
								next_col = col;
								break;
							case 'w':
								next_row = adj_row;
								next_col = col-1;
								break;
							case 'c':
								next_row = adj_row;
								next_col = col;
								break;
							}
							if(next_row != -1)break;
						}

						break;
					case 2: //???????????????????????????????????????

						for(int col = adj_col; col <= W-1; col++){
							switch(Q.front().table[adj_row][col+1]){
							case '.':
							case 'E':
								//Do nothing
								break;
							case '#':
								next_row = adj_row;
								next_col = col;
								break;
							case 'w':
								next_row = adj_row;
								next_col = col+1;
								break;
							case 'c':
								next_row = adj_row;
								next_col = col;
								break;
							}
							if(next_row != -1)break;
						}

						break;
					case 3: //???????????????????????????????????????
						for(int row = adj_row; row <= H-1; row++){
							switch(Q.front().table[row+1][adj_col]){ //1????????????????????????
							case '.':
							case 'E':
								//Do nothing
								break;
							case '#':
								next_row = row;
								next_col = adj_col;
								break;
							case 'w':
								next_row = row+1;
								next_col = adj_col;
								break;
							case 'c':
								next_row = row;
								next_col = adj_col;
								break;
							}
							if(next_row != -1)break;
						}
						break;
					}

					if(adj_row == next_row && adj_col == next_col)continue; //????????????????§???????????????´??????????§?????????¨??????????????????????????????

					Info next_info;
					copyInfo(next_info,Q.front());

					next_info.table[adj_row][adj_col] = '.'; //???????????????????¶?????????????

					switch(next_info.table[next_row][next_col]){
					case '.':
					case 'E':
						next_info.table[next_row][next_col] = 'c';
						break;
					case 'w':
						next_info.table[next_row][next_col] = '.';
						break;
					}

					tmp_code = makeCode(next_info.table);

					auto at = MAP.find(tmp_code);

					if(at != MAP.end())continue;

					next_info.current_row = Q.front().current_row;
					next_info.current_col = Q.front().current_col;

					Q.push(next_info);

				}else{ //'E'or'.'

					Info next_info;
					copyInfo(next_info,Q.front());
					next_info.table[adj_row][adj_col] = '@';
					next_info.table[Q.front().current_row][Q.front().current_col] = '.';

					tmp_code = makeCode(next_info.table);

					auto at = MAP.find(tmp_code);
					if(at != MAP.end())continue;

					MAP[tmp_code] = true;
					next_info.sum_cost++;
					next_info.current_row = adj_row;
					next_info.current_col = adj_col;

					Q.push(next_info);
				}
			}
			Q.pop();
		}
	}
	printf("-1\n");
}

int main(){

	while(true){
		scanf("%d %d",&H,&W);
		if(H == 0 && W == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 6504
final_rank: 4

code_snippet: #include "bits/stdc++.h"
#include <unordered_map>
using namespace std;

const int dx[4] = { -1,0,1,0 };
const int dy[4] = { 0,1,0,-1 };
struct status {
	vector<vector<int>>field;
	int drx;
	int dry;
	vector<int>p_ons;
	vector<pair<int, int>>ps;
	vector<pair<int, int>>cs;
};
status mk_sta(const vector<vector<int>>&field,int drx,int dry,const vector<pair<int,int>>&ps) {
	vector<int>p_ons(ps.size());
	for (int i = 0; i < ps.size(); ++i) {
		p_ons[i]=field[ps[i].second][ps[i].first] >= 200;
	}
	vector<pair<int, int>>cs;
	for (int y = 0; y < field.size(); ++y) {
		for (int x = 0; x < field[y].size(); ++x) {
			if (field[y][x] == 100)cs.push_back(make_pair(x, y));
		}
	}
	return status{ field,drx,dry,p_ons,ps,cs };
}
class HashVI {  // ???????????\??¢??°???????????§??????
public:
	size_t operator()(const status &x) const {
		size_t t = 0;
		t *= 10;
		t += x.drx;
		t *= 10;
		t += x.dry;
		for (int i = 0; i < x.p_ons.size(); ++i) {
			t *= 2;
			t += x.p_ons[i];
		}
		for (int i = 0; i < x.cs.size(); ++i) {
			t *= 10;
			t += x.cs[i].first;
			t *= 10;
			t += x.cs[i].second;
		}
		return t;
	}
};
class Equal {
public:
	bool operator()(const status&l, const status&r)const  {
		return l.cs == r.cs&&l.p_ons == r.p_ons&&l.drx == r.drx&&l.dry == r.dry;
	}
};
unordered_map<status, int, HashVI,Equal>mp;
vector<vector<int>>mov(vector<vector<int>>field, int fromx, int fromy, int way) {
	field[fromy][fromx] = 1;
	while (1) {
		int nextx = fromx + dx[way];
		int nexty = fromy + dy[way];
		
		 if (field[nexty][nextx] >= 200) {
			field[nexty][nextx] = 1;
			fromx = nextx;
			fromy = nexty;
			return field;
		 }
		 else if (field[nexty][nextx]!=1) {
			 field[fromy][fromx] = 100;
			 return field;
		 }
		 else {
			 fromx = nextx;
			 fromy = nexty;
		}
	}
	assert(false);
}
struct aa {
	status sta;
	int time;
};
class Compare {
public :
	bool operator()(const aa&l, const aa&r) {
		return l.time > r.time;
	}
};
int gx, gy;
int solve(const status&sta) {
	queue<aa>que;
	que.push(aa{ sta,0 });
	while (!que.empty()) {
		auto atop = que.front();
		que.pop();
		status sta=atop.sta;
		int turn = atop.time;
		if (mp.find(sta) == mp.end()) {
			mp[sta] = turn;
			vector<vector<int>>field = sta.field;
			int ans = 1e8;
			const int nowx = sta.drx;
			const int nowy = sta.dry;
			for (int way = 0; way < 4; ++way) {
				const int nextx = nowx + dx[way];
				const int nexty = nowy + dy[way];
				vector<int>panel_ons(sta.p_ons);
				vector<pair<int, int>>panels(sta.ps);
				vector<pair<int, int>>cons(sta.cs);
				if (field[nexty][nextx] == 0) {
				}
				else if (field[nexty][nextx] == 100) {
					auto next_field = mov(field, nextx, nexty, way);
					if (next_field[nexty][nextx] == 1) {
						que.push(aa{ mk_sta(next_field,nowx,nowy,sta.ps),turn });

					}
				}
				else if (field[nexty][nextx] == 1) {
					if (nexty == gy&&nextx == gx) {
						return turn + 1;
					}
					else {

						que.push(aa{ mk_sta(field,nextx,nexty,sta.ps),turn + 1 });
					}
				}
			}
		}
	}
	
	return -1;
}

int main() {
	while (1) {
		mp.clear();
		int H, W; cin >> H >> W;
		if (!H)break;
		vector<vector<int>>field(H, vector<int>(W));
		int sx, sy;
		vector<pair<int, int>>cs;
		vector<pair<int, int>>ps;
		for (int i = 0; i < H; ++i) {
			string st; cin >> st;
			for (int j = 0; j < W; ++j) {
				if (st[j] == '#') {
					field[i][j] = 0;
				}
				else if (st[j] == '@') {
					field[i][j] = 1;
					sx = j; sy = i;
				}
				else if (st[j] == 'w') {
					field[i][j] = 200+ps.size();
					ps.emplace_back(j, i);
				}
				else if (st[j] == 'c') {
					field[i][j] = 100;
					cs.emplace_back(j, i);
				}
				else if (st[j] == 'E') {
					field[i][j]=1;
					gx = j;
					gy = i;
				}
				else {
					field[i][j] = 1;
				}
			}
		}
		int ans = solve(mk_sta(field, sx, sy, ps));
		if (ans > 1e7)ans = -1;
		cout << ans << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 850
memory_kb: 53376
final_rank: 20

code_snippet: #include <bits/stdc++.h>
 
using namespace std;
 
#define MAX_H 15
#define MAX_W 15
 
int p,c;
 
class State{
public:
    int x,y,px[3],py[3],cx[3],cy[3];
    bool operator < (const State &s)const{
	if(x != s.x){
	    return x < s.x;
	}else if(y != s.y){
	    return y < s.y;
	}else{
	    for(int i = 0 ; i < p ; i++){
		if(px[i] != s.px[i]){
		    return px[i] < s.px[i];
		}else if(py[i] != s.py[i]){
		    return py[i] < s.py[i];
		}
	    }
	    for(int i = 0 ; i < c ; i++){
		if(cx[i] != s.cx[i]){
		    return cx[i] < s.cx[i];
		}else if(cy[i] != s.cy[i]){
		    return cy[i] < s.cy[i];
		}
	    }
	    return false;
	}
    }
};
 
int H,W,gx,gy;
set<State> visited;
char field[MAX_H][MAX_W];
State start;
const int dx[] = {-1,0,1,0};
const int dy[] = {0,-1,0,1};
 
void init(){
    p = c = 0;
    visited.clear();
}
 
bool input(){
    cin >> H >> W;
    if(H == 0 && W == 0){
	return false;
    }
    init();
    for(int i = 0 ; i < H ; i++){
	for(int j = 0 ; j < W ; j++){
	    cin >> field[i][j];
	    if(field[i][j] == '@'){
		start.x = j; start.y = i;
	    }else if(field[i][j] == 'E'){
		gx = j; gy = i;
	    }else if(field[i][j] == 'w'){
		start.px[p] = j; start.py[p] = i;
		p++;
	    }else if(field[i][j] == 'c'){
		field[i][j] = '.';
		start.cx[c] = j; start.cy[c] = i;
		c++;
	    }
	}
    }
    return true;
}
 
inline bool valid(const State &s){
    if(field[s.y][s.x] == '#'){
	return false;
    }
    for(int i = 0 ; i < p ; i++){
	if(s.x == s.px[i] && s.y == s.py[i]){
	    return false;
	}
    }
    for(int i = 0 ; i < c ; i++){
	if(s.x == s.cx[i] && s.y == s.cy[i]){
	    return false;
	}
    }
    return true;
}
 
inline bool pushCont(State &s,int dir){
    int idx = -1;
    int nx = s.x + dx[dir], ny = s.y + dy[dir];
    for(int i = 0 ; i < c ; i++){
	if(s.cx[i] == nx && s.cy[i] == ny){
	    idx = i;
	    break;
	}
    }
    if(idx == -1){ return false; }
    while(true){
	nx += dx[dir], ny += dy[dir];
	if(field[ny][nx] == '#'){
	    s.cx[idx] = nx-dx[dir];
	    s.cy[idx] = ny-dy[dir];
	    return true;
	}
	for(int i = 0 ; i < c ; i++){
	    if(i == idx) continue;
	    if(s.cx[i] == nx && s.cy[i] == ny){
		s.cx[idx] = nx-dx[dir];
		s.cy[idx] = ny-dy[dir];
		return true;
	    }
	}
	for(int i = 0 ; i < p ; i++){
	    if(s.px[i] == nx && s.py[i] == ny){
		s.px[i] = s.py[i] = -1;
		s.cx[idx] = s.cy[idx] = -1;
		return true;
	    }
	}
    }
    return false;
}
 
int solve(){
    deque<State> Q;
    deque<int> move;
    Q.push_front(start);
    move.push_front(0);
    visited.insert(start);
 
    while(!Q.empty()){
	State s = Q.front(); Q.pop_front();
	int m = move.front(); move.pop_front();
	if(s.x == gx && s.y == gy){
	    return m;
	}
	for(int i = 0 ; i < 4 ; i++){
	    State tmp = s;
	    s.x += dx[i], s.y += dy[i];
	    if(valid(s)){
		if(!visited.count(s)){
		    visited.insert(s);
		    Q.push_back(s);
		    move.push_back(m+1);
		}
	    }
	    s.x -= dx[i], s.y -= dy[i];
	    if(pushCont(s,i)){
		if(!visited.count(s)){
		    visited.insert(s);
		    Q.push_front(s);
		    move.push_front(m);
		}
	    }
	    s = tmp;
	}
    }
    return -1;
}
 
int main(){
    while(input()){
	cout << solve() << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 9924
final_rank: 7

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define MAX_H 15
#define MAX_W 15

int p,c;

class State{
public:
  int x,y,px[3],py[3],cx[3],cy[3];
  bool operator < (const State &s)const{
    if(x != s.x){
      return x < s.x;
    }else if(y != s.y){
      return y < s.y;
    }else{
      for(int i = 0 ; i < p ; i++){
        if(px[i] != s.px[i]){
          return px[i] < s.px[i];
        }else if(py[i] != s.py[i]){
          return py[i] < s.py[i];
        }
      }
      for(int i = 0 ; i < c ; i++){
        if(cx[i] != s.cx[i]){
          return cx[i] < s.cx[i];
        }else if(cy[i] != s.cy[i]){
          return cy[i] < s.cy[i];
        }
      }
      return false;
    }
  }
};

int H,W,gx,gy;
set<State> visited;
char field[MAX_H][MAX_W];
State start;
const int dx[] = {-1,0,1,0};
const int dy[] = {0,-1,0,1};

void init(){
  p = c = 0;
  visited.clear();
}

bool input(){
  cin >> H >> W;
  if(H == 0 && W == 0){
    return false;
  }
  init();
  for(int i = 0 ; i < H ; i++){
    for(int j = 0 ; j < W ; j++){
      cin >> field[i][j];
      if(field[i][j] == '@'){
        start.x = j; start.y = i;
      }else if(field[i][j] == 'E'){
        gx = j; gy = i;
      }else if(field[i][j] == 'w'){
        start.px[p] = j; start.py[p] = i;
        p++;
      }else if(field[i][j] == 'c'){
        field[i][j] = '.';
        start.cx[c] = j; start.cy[c] = i;
        c++;
      }
    }
  }
  return true;
}

inline bool valid(const State &s){
  if(field[s.y][s.x] == '#'){
    return false;
  }
  for(int i = 0 ; i < p ; i++){
    if(s.x == s.px[i] && s.y == s.py[i]){
      return false;
    }
  }
  for(int i = 0 ; i < c ; i++){
    if(s.x == s.cx[i] && s.y == s.cy[i]){
      return false;
    }
  }
  return true;
}

inline bool pushCont(State &s,int dir){
  int idx = -1;
  int nx = s.x + dx[dir], ny = s.y + dy[dir];
  for(int i = 0 ; i < c ; i++){
    if(s.cx[i] == nx && s.cy[i] == ny){
      idx = i;
      break;
    }
  }
  if(idx == -1){ return false; }
  while(true){
    nx += dx[dir], ny += dy[dir];
    if(field[ny][nx] == '#'){
      s.cx[idx] = nx-dx[dir];
      s.cy[idx] = ny-dy[dir];
      return true;
    }
    for(int i = 0 ; i < c ; i++){
      if(i == idx) continue;
      if(s.cx[i] == nx && s.cy[i] == ny){
        s.cx[idx] = nx-dx[dir];
        s.cy[idx] = ny-dy[dir];
        return true;
      }
    }
    for(int i = 0 ; i < p ; i++){
      if(s.px[i] == nx && s.py[i] == ny){
        s.px[i] = s.py[i] = -1;
        s.cx[idx] = s.cy[idx] = -1;
        return true;
      }
    }
  }
  return false;
}

int solve(){
  deque<State> Q;
  deque<int> move;
  Q.push_front(start);
  move.push_front(0);
  visited.insert(start);

  while(!Q.empty()){
    State s = Q.front(); Q.pop_front();
    int m = move.front(); move.pop_front();
    if(s.x == gx && s.y == gy){
      return m;
    }
    for(int i = 0 ; i < 4 ; i++){
      State tmp = s;
      s.x += dx[i], s.y += dy[i];
      if(valid(s)){
        if(!visited.count(s)){
          visited.insert(s);
          Q.push_back(s);
          move.push_back(m+1);
        }
      }
      s.x -= dx[i], s.y -= dy[i];
      if(pushCont(s,i)){
        if(!visited.count(s)){
          visited.insert(s);
          Q.push_front(s);
          move.push_front(m);
        }
      }
      s = tmp;
    }
  }
  return -1;
}

int main(){
  while(input()){
    cout << solve() << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 170
memory_kb: 8044
final_rank: 5

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define MAX_H 15
#define MAX_W 15

class State{
public:
  int x,y,px[3],py[3],cx[3],cy[3];
  State(){
    x = y = -1;
    for(int i = 0 ; i < 3 ; i++){
      px[i] = py[i] = cx[i] = cy[i] = -1;
    }
  }
  bool operator < (const State &s)const{
    if(x != s.x){
      return x < s.x;
    }else if(y != s.y){
      return y < s.y;
    }else{
      for(int i = 0 ; i < 3 ; i++){
        if(px[i] != s.px[i]){
          return px[i] < s.px[i];
        }else if(py[i] != s.py[i]){
          return py[i] < s.py[i];
        }
      }
      for(int i = 0 ; i < 3 ; i++){
        if(cx[i] != s.cx[i]){
          return cx[i] < s.cx[i];
        }else if(cy[i] != s.cy[i]){
          return cy[i] < s.cy[i];
        }
      }
      return false;
    }
  }
};

int H,W,gx,gy,p,c;
set<State> visited;
char field[MAX_H][MAX_W];
State start;
const int dx[] = {-1,0,1,0};
const int dy[] = {0,-1,0,1};

void init(){
  p = c = 0;
  visited.clear();
}

bool input(){
  cin >> H >> W;
  if(H == 0 && W == 0){
    return false;
  }
  init();
  for(int i = 0 ; i < H ; i++){
    for(int j = 0 ; j < W ; j++){
      cin >> field[i][j];
      if(field[i][j] == '@'){
        start.x = j; start.y = i;
      }else if(field[i][j] == 'E'){
        gx = j; gy = i;
      }else if(field[i][j] == 'w'){
        start.px[p] = j; start.py[p] = i;
        p++;
      }else if(field[i][j] == 'c'){
        field[i][j] = '.';
        start.cx[c] = j; start.cy[c] = i;
        c++;
      }
    }
  }
  return true;
}

bool valid(const State &s){
  if(field[s.y][s.x] == '#'){
    return false;
  }
  for(int i = 0 ; i < p ; i++){
    if(s.x == s.px[i] && s.y == s.py[i]){
      return false;
    }
  }
  for(int i = 0 ; i < c ; i++){
    if(s.x == s.cx[i] && s.y == s.cy[i]){
      return false;
    }
  }
  return true;
}

bool pushCont(State &s,int dir){
  int idx = -1;
  int nx = s.x + dx[dir], ny = s.y + dy[dir];
  for(int i = 0 ; i < c ; i++){
    if(s.cx[i] == nx && s.cy[i] == ny){
      idx = i;
      break;
    }
  }
  if(idx == -1){ return false; }
  while(true){
    nx += dx[dir], ny += dy[dir];
    if(field[ny][nx] == '#'){
      s.cx[idx] = nx-dx[dir];
      s.cy[idx] = ny-dy[dir];
      return true;
    }
    for(int i = 0 ; i < c ; i++){
      if(i == idx) continue;
      if(s.cx[i] == nx && s.cy[i] == ny){
        s.cx[idx] = nx-dx[dir];
        s.cy[idx] = ny-dy[dir];
        return true;
      }
    }
    for(int i = 0 ; i < p ; i++){
      if(s.px[i] == nx && s.py[i] == ny){
        s.px[i] = s.py[i] = -1;
        s.cx[idx] = s.cy[idx] = -1;
        return true;
      }
    }
  }
  return false;
}

int solve(){
  deque<State> Q;
  deque<int> move;
  Q.push_front(start);
  move.push_front(0);
  visited.insert(start);

  while(!Q.empty()){
    State s = Q.front(); Q.pop_front();
    int m = move.front(); move.pop_front();
    if(s.x == gx && s.y == gy){
      return m;
    }
    for(int i = 0 ; i < 4 ; i++){
      State tmp = s;
      s.x += dx[i], s.y += dy[i];
      if(valid(s)){
        if(!visited.count(s)){
          visited.insert(s);
          Q.push_back(s);
          move.push_back(m+1);
        }
      }
      s = tmp;
      if(pushCont(s,i)){
        if(!visited.count(s)){
          visited.insert(s);
          Q.push_front(s);
          move.push_front(m);
        }
      }
      s = tmp;
    }
  }
  return -1;
}

int main(){
  while(input()){
    cout << solve() << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 170
memory_kb: 8044
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define dump(...) cout<<"# "<<#__VA_ARGS__<<'='<<(__VA_ARGS__)<<endl
#define repi(i,a,b) for(int i=int(a);i<int(b);i++)
#define peri(i,a,b) for(int i=int(b);i-->int(a);)
#define rep(i,n) repi(i,0,n)
#define per(i,n) peri(i,0,n)
#define all(c) begin(c),end(c)
#define mp make_pair
#define mt make_tuple

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;

template<typename T1,typename T2>
ostream& operator<<(ostream& os,const pair<T1,T2>& p){
	return os<<'('<<p.first<<','<<p.second<<')';
}

template<typename Tuple>
void print_tuple(ostream&,const Tuple&){}
template<typename Car,typename... Cdr,typename Tuple>
void print_tuple(ostream& os,const Tuple& t){
	print_tuple<Cdr...>(os,t);
	os<<(sizeof...(Cdr)?",":"")<<get<sizeof...(Cdr)>(t);
}
template<typename... Args>
ostream& operator<<(ostream& os,const tuple<Args...>& t){
	print_tuple<Args...>(os<<'(',t);
	return os<<')';
}

template<typename Ch,typename Tr,typename C>
basic_ostream<Ch,Tr>& operator<<(basic_ostream<Ch,Tr>& os,const C& c){
	os<<'[';
	for(auto i=begin(c);i!=end(c);++i)
		os<<(i==begin(c)?"":" ")<<*i;
	return os<<']';
}

constexpr int INF=1e9;
constexpr int MOD=1e9+7;
constexpr double EPS=1e-9;

enum:char{
	WALL='#',ME='@',PANEL='w',CONTAINER='c',EMPTY='.',ESCAPE='E'
};
constexpr int di[]={-1,1,0,0},dj[]={0,0,-1,1};

string encode(const vs& grid,int i,int j)
{
	int h=grid.size(),w=grid[0].size();
	string res;
	repi(k,1,h-1) res+=grid[k].substr(1,w-2);
	res[(i-1)*(w-2)+j-1]=ME;
	return res;
}

int main()
{
	for(int h,w;cin>>h>>w && h|w;){
		int gi=-1,gj=-1;
		deque<tuple<vs,int,int,int>> dq;
		{
			vs grid(h);
			rep(i,h) cin>>grid[i];
			rep(i,h) rep(j,w) if(grid[i][j]==ESCAPE){
				gi=i,gj=j;
				grid[i][j]=EMPTY;
			}
			rep(i,h) rep(j,w) if(grid[i][j]==ME){
				grid[i][j]=EMPTY;
				dq.emplace_back(grid,i,j,0);
			}
		}
		
		int res=-1;
		set<string> vis;
		while(dq.size()){
			vs cur; int ci,cj,ct; tie(cur,ci,cj,ct)=move(dq.front()); dq.pop_front();
			if(!vis.insert(encode(cur,ci,cj)).second) continue;
			
			if(ci==gi && cj==gj){
				res=ct;
				break;
			}
			
			rep(k,4){
				int ni=ci+di[k],nj=cj+dj[k];
				if(cur[ni][nj]==WALL || cur[ni][nj]==PANEL) continue;
				if(cur[ni][nj]==CONTAINER){
					int i=ni+di[k],j=nj+dj[k];
					for(;;i+=di[k],j+=dj[k]){
						if(cur[i][j]==EMPTY) continue;
						if(cur[i][j]==PANEL) break;
						if(cur[i][j]==WALL || cur[i][j]==CONTAINER){
							i-=di[k],j-=dj[k];
							break;
						}
					}
					if(i==ni && j==nj) continue;
					vs next=cur;
					next[ni][nj]=EMPTY;
					next[i][j]=next[i][j]==PANEL?EMPTY:CONTAINER;
					dq.emplace_front(move(next),ci,cj,ct);
				}
				else
					dq.emplace_back(cur,ni,nj,ct+1);
			}
		}
		cout<<res<<endl;
	}
}
accuracy: 1
time_ms: 480
memory_kb: 9936
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define dump(...) cout<<"# "<<#__VA_ARGS__<<'='<<(__VA_ARGS__)<<endl
#define repi(i,a,b) for(int i=int(a);i<int(b);i++)
#define peri(i,a,b) for(int i=int(b);i-->int(a);)
#define rep(i,n) repi(i,0,n)
#define per(i,n) peri(i,0,n)
#define all(c) begin(c),end(c)
#define mp make_pair
#define mt make_tuple

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;

template<typename T1,typename T2>
ostream& operator<<(ostream& os,const pair<T1,T2>& p){
	return os<<'('<<p.first<<','<<p.second<<')';
}

template<typename Tuple>
void print_tuple(ostream&,const Tuple&){}
template<typename Car,typename... Cdr,typename Tuple>
void print_tuple(ostream& os,const Tuple& t){
	print_tuple<Cdr...>(os,t);
	os<<(sizeof...(Cdr)?",":"")<<get<sizeof...(Cdr)>(t);
}
template<typename... Args>
ostream& operator<<(ostream& os,const tuple<Args...>& t){
	print_tuple<Args...>(os<<'(',t);
	return os<<')';
}

template<typename Ch,typename Tr,typename C>
basic_ostream<Ch,Tr>& operator<<(basic_ostream<Ch,Tr>& os,const C& c){
	os<<'[';
	for(auto i=begin(c);i!=end(c);++i)
		os<<(i==begin(c)?"":" ")<<*i;
	return os<<']';
}

constexpr int INF=1e9;
constexpr int MOD=1e9+7;
constexpr double EPS=1e-9;

enum:char{
	WALL='#',ME='@',PANEL='w',CONTAINER='c',EMPTY='.',ESCAPE='E'
};
constexpr int di[]={-1,1,0,0},dj[]={0,0,-1,1};

string encode(const vs& grid,int i,int j)
{
	int h=grid.size(),w=grid[0].size();
	string res;
	repi(k,1,h-1) res+=grid[k].substr(1,w-2);
	res[(i-1)*(w-2)+j-1]=ME;
	return res;
}

int main()
{
	for(int h,w;cin>>h>>w && h|w;){
		int gi=-1,gj=-1;
		deque<tuple<vs,int,int,int>> dq;
		{
			vs grid(h);
			rep(i,h) cin>>grid[i];
			rep(i,h) rep(j,w) if(grid[i][j]==ESCAPE){
				gi=i,gj=j;
				grid[i][j]=EMPTY;
			}
			rep(i,h) rep(j,w) if(grid[i][j]==ME){
				grid[i][j]=EMPTY;
				dq.emplace_back(grid,i,j,0);
			}
		}
		
		int res=-1;
		set<string> vis;
		while(dq.size()){
			vs cur; int ci,cj,ct; tie(cur,ci,cj,ct)=dq.front(); dq.pop_front();
			if(!vis.insert(encode(cur,ci,cj)).second) continue;
			
			if(ci==gi && cj==gj){
				res=ct;
				break;
			}
			
			rep(k,4){
				int ni=ci+di[k],nj=cj+dj[k];
				if(cur[ni][nj]==WALL || cur[ni][nj]==PANEL) continue;
				if(cur[ni][nj]==CONTAINER){
					int i=ni+di[k],j=nj+dj[k];
					for(;;i+=di[k],j+=dj[k]){
						if(cur[i][j]==EMPTY) continue;
						if(cur[i][j]==PANEL) break;
						if(cur[i][j]==WALL || cur[i][j]==CONTAINER){
							i-=di[k],j-=dj[k];
							break;
						}
					}
					if(i==ni && j==nj) continue;
					vs next=cur;
					next[ni][nj]=EMPTY;
					next[i][j]=next[i][j]==PANEL?EMPTY:CONTAINER;
					dq.emplace_front(move(next),ci,cj,ct);
				}
				else
					dq.emplace_back(cur,ni,nj,ct+1);
			}
		}
		cout<<res<<endl;
	}
}
accuracy: 1
time_ms: 520
memory_kb: 10076
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define dump(...) cout<<"# "<<#__VA_ARGS__<<'='<<(__VA_ARGS__)<<endl
#define repi(i,a,b) for(int i=int(a);i<int(b);i++)
#define peri(i,a,b) for(int i=int(b);i-->int(a);)
#define rep(i,n) repi(i,0,n)
#define per(i,n) peri(i,0,n)
#define all(c) begin(c),end(c)
#define mp make_pair
#define mt make_tuple

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;

template<typename T1,typename T2>
ostream& operator<<(ostream& os,const pair<T1,T2>& p){
	return os<<'('<<p.first<<','<<p.second<<')';
}

template<typename Tuple>
void print_tuple(ostream&,const Tuple&){}
template<typename Car,typename... Cdr,typename Tuple>
void print_tuple(ostream& os,const Tuple& t){
	print_tuple<Cdr...>(os,t);
	os<<(sizeof...(Cdr)?",":"")<<get<sizeof...(Cdr)>(t);
}
template<typename... Args>
ostream& operator<<(ostream& os,const tuple<Args...>& t){
	print_tuple<Args...>(os<<'(',t);
	return os<<')';
}

template<typename Ch,typename Tr,typename C>
basic_ostream<Ch,Tr>& operator<<(basic_ostream<Ch,Tr>& os,const C& c){
	os<<'[';
	for(auto i=begin(c);i!=end(c);++i)
		os<<(i==begin(c)?"":" ")<<*i;
	return os<<']';
}

constexpr int INF=1e9;
constexpr int MOD=1e9+7;
constexpr double EPS=1e-9;

enum:char{
	WALL='#',ME='@',PANEL='w',CONTAINER='c',EMPTY='.',ESCAPE='E'
};
constexpr int di[]={-1,1,0,0},dj[]={0,0,-1,1};

string encode(const vs& grid,int i,int j)
{
	int h=grid.size(),w=grid[0].size();
	string res;
	repi(k,1,h-1) res+=grid[k].substr(1,w-2);
	res[(i-1)*(w-2)+j-1]=ME;
	return res;
}

int main()
{
	for(int h,w;cin>>h>>w && h|w;){
		int gi=-1,gj=-1;
		deque<tuple<vs,int,int,int>> dq;
		{
			vs grid(h);
			rep(i,h) cin>>grid[i];
			rep(i,h) rep(j,w) if(grid[i][j]==ESCAPE){
				gi=i,gj=j;
				grid[i][j]=EMPTY;
			}
			rep(i,h) rep(j,w) if(grid[i][j]==ME){
				grid[i][j]=EMPTY;
				dq.emplace_back(grid,i,j,0);
			}
		}
		
		int res=-1;
		set<string> vis;
		while(dq.size()){
			vs cur; int ci,cj,ct; tie(cur,ci,cj,ct)=dq.front(); dq.pop_front();
			if(!vis.insert(encode(cur,ci,cj)).second) continue;
			
			if(ci==gi && cj==gj){
				res=ct;
				break;
			}
			
			rep(k,4){
				int ni=ci+di[k],nj=cj+dj[k];
				if(cur[ni][nj]==WALL || cur[ni][nj]==PANEL) continue;
				if(cur[ni][nj]==CONTAINER){
					int i=ni+di[k],j=nj+dj[k];
					for(;;i+=di[k],j+=dj[k]){
						if(cur[i][j]==EMPTY) continue;
						if(cur[i][j]==PANEL) break;
						if(cur[i][j]==WALL || cur[i][j]==CONTAINER){
							i-=di[k],j-=dj[k];
							break;
						}
					}
					if(i==ni && j==nj) continue;
					vs next=cur;
					next[ni][nj]=EMPTY;
					next[i][j]=next[i][j]==PANEL?EMPTY:CONTAINER;
					dq.emplace_front(next,ci,cj,ct);
				}
				else
					dq.emplace_back(cur,ni,nj,ct+1);
			}
		}
		cout<<res<<endl;
	}
}
accuracy: 1
time_ms: 520
memory_kb: 9972
final_rank: 16

code_snippet: #include<stdio.h>
#include<algorithm>
#include<queue>
#include<set>
#include<deque>
using namespace std;
char str[20][20];
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
int main(){
	int a,b;
	while(scanf("%d%d",&a,&b),a){
		for(int i=0;i<a;i++)scanf("%s",str[i]);
		int sr,sc;
		int gr,gc;
		set<int>v;
		int m=0;
		int st=0;
		for(int i=0;i<a;i++){
			for(int j=0;j<b;j++){
				if(str[i][j]=='@'){sr=i;sc=j;}
				if(str[i][j]=='E'){gr=i;gc=j;}
				if(str[i][j]=='c'){
					st*=100;
					st+=i*10+j;
					m++;
				}
			}
		}
		st*=100;
		st+=sr*10+sc;
		deque<pair<int,int> >Q;
		bool yet=true;
		Q.push_back(make_pair(0,st));
		while(Q.size()){
			int cost=Q.front().first;
			int at=Q.front().second;
			Q.pop_front();
			if(v.count(at))continue;
			
		//	printf("%d %d\n",cost,at);
			v.insert(at);
			if(at%100==gr*10+gc){
				yet=false;
				printf("%d\n",cost);
				break;
			}
			int row=at%100/10;
			int col=at%10;
			int tmp=at;
			tmp/=100;
			int br[5];
			int bc[5];
			for(int i=0;i<m;i++){
				br[i]=tmp%100/10;
				bc[i]=tmp%10;
				tmp/=100;
			}
			for(int i=0;i<4;i++){
				if(0<=row+dx[i]&&row+dx[i]<a&&0<=col+dy[i]&&col+dy[i]<b&&str[row+dx[i]][col+dy[i]]!='#'){
					bool W=false;
					bool C=false;
					for(int j=0;j<m;j++)if(row+dx[i]==br[j]&&col+dy[i]==bc[j])C=true;
					if(str[row+dx[i]][col+dy[i]]=='w')W=true;
					if(C&&!W){
						int nr=row+dx[i];
						int nc=col+dy[i];
						while(str[nr+dx[i]][nc+dy[i]]!='#'){
							nr+=dx[i];nc+=dy[i];
							bool nk=false;
							bool nw=false;
							for(int j=0;j<m;j++)if(nr==br[j]&&nc==bc[j])nk=true;
							
							if(str[nr][nc]=='w')nw=true;
							if(nw&&!nk)break;
							if(nk&&!nw){
								nr-=dx[i];nc-=dy[i];break;
							}
						}
						int to=at;
						for(int j=0;j<m;j++)if(row+dx[i]==br[j]&&col+dy[i]==bc[j]){
							int ad=1;
							for(int k=0;k<j*2+2;k++)ad*=10;
							to-=to%(ad*100)-to%ad;
							to+=ad*(nr*10+nc);
						}
						if(v.count(to))continue;
						Q.push_front(make_pair(cost,to));
					}
					if(W&&!C)continue;
					if(C&&!W)continue;
					int to=at-at%100+(row+dx[i])*10+col+dy[i];
					if(v.count(to))continue;
					Q.push_back(make_pair(cost+1,to));
				}
			}
		}
		if(yet)printf("-1\n");
	}
}
accuracy: 1
time_ms: 100
memory_kb: 4280
final_rank: 2

code_snippet: #include<iostream>
#include <cstring>
#include <map>
#include <queue>
using namespace std;

int dx[] = {-1,0,1,0};
int dy[] = {0,1,0,-1};

char lab[10][10];
struct NODE{
	int x,y;
	int px[3],py[3];
	int dead;
	int cdead;
	NODE(){
		x = y = 0;
		px[0] = px[1] = px[2] = 0;
		py[0] = py[1] = py[2] = 0;
		dead = 0;
		cdead = 0;
	}
};
bool operator < (const NODE &a,const NODE &b){
	if( a.x != b.x ) return a.x < b.x;
	if( a.y != b.y ) return a.y < b.y;
	if( a.px[0] != b.px[0] ) return a.px[0] < b.px[0];
	if( a.px[1] != b.px[1] ) return a.px[1] < b.px[1];
	if( a.px[2] != b.px[2] ) return a.px[2] < b.px[2];
	if( a.py[0] != b.py[0] ) return a.py[0] < b.py[0];
	if( a.py[1] != b.py[1] ) return a.py[1] < b.py[1];
	if( a.py[2] != b.py[2] ) return a.py[2] < b.py[2];
	if( a.dead != b.dead ) return a.dead < b.dead;
	if( a.cdead != b.cdead ) return a.cdead < b.cdead;
	return false;
}

int main(){
	int H,W;
	while( cin >> H >> W && H ){
		int wx[3],wy[3];
		map<NODE,int> done;
		NODE fst; int cc = 0 , ww = 0;
		for(int i = 0 ; i < H ; i++){
			for(int j = 0 ; j < W ; j++){
				cin >> lab[i][j];
				if( lab[i][j] == '@' ) fst.x = j , fst.y = i;
				if( lab[i][j] == 'c' ){
					fst.px[cc] = j;
					fst.py[cc++] = i;
				}
				if( lab[i][j] == 'w' ){
					wx[ww] = j;
					wy[ww++] = i;
				}
			}
		}
		deque< pair<int,NODE> > Q;
		done[fst] = 0;
		Q.push_front(make_pair(0,fst));
		
		while( Q.size() ){
			NODE q = Q.front().second;
			int cost = Q.front().first;
			Q.pop_front();
			if( done[q] != cost ) continue;
			if( lab[q.y][q.x] == 'E' ){
				cout << cost << endl;
				goto exit;
			}
			for(int d = 0 ; d < 4 ; d++){
				int tx = q.x + dx[d];
				int ty = q.y + dy[d];
				if( lab[ty][tx] == '#' ) continue;
				int fail = 0;
				for(int i = 0 ; i < ww ; i++){
					if( !(q.dead >> i & 1) && tx == wx[i] && ty == wy[i] ) fail = 1;
				}
				if(fail) continue;
				
				NODE next = q;
				for(int i = 0 ; i < cc ; i++){
					if( !(q.cdead >> i & 1) && tx == q.px[i] && ty == q.py[i] ){
						int mx = tx;
						int my = ty;
						while( lab[my+dy[d]][mx+dx[d]] != '#' ){
							int br = 0;
							for(int j = 0 ; j < cc ; j++){
								if( !(q.cdead >> j & 1) && mx+dx[d] == q.px[j] && my+dy[d] == q.py[j] )
									br = 1;
							}
							if(br) break;
							mx += dx[d];
							my += dy[d];
							for(int j = 0 ; j < ww ; j++){
								if( !(q.dead >> j & 1) && mx == wx[j] && my == wy[j] ){
									br = 1;
									next.cdead |= (1<<i);
									next.dead |= (1<<j);
									mx = 0;
									my = 0;
									break;
								}
							}
							if(br) break;
						}
						next.px[i] = mx;
						next.py[i] = my;
						tx = q.x;
						ty = q.y;
					}
				}
				int diff = q.y != ty || q.x != tx;
				next.x = tx , next.y = ty;
				if( !done.count(next) || done[next] > cost+diff ){
					if( diff ) Q.push_back(make_pair(diff+cost,next));
					else       Q.push_front(make_pair(diff+cost,next));
					
					done[next] = cost+diff;
				}
			}
		}
		cout << -1 << endl;
		exit:;
		
	}
}
accuracy: 1
time_ms: 250
memory_kb: 7880
final_rank: 8

code_snippet: #include<iostream>
#include <cstring>
#include <map>
#include <queue>
using namespace std;

int dx[] = {-1,0,1,0};
int dy[] = {0,1,0,-1};

char lab[10][10];
struct NODE{
	int x,y;
	int px[3],py[3];
	int dead;
	int cdead;
	NODE(){
		x = y = 0;
		px[0] = px[1] = px[2] = 0;
		py[0] = py[1] = py[2] = 0;
		dead = 0;
		cdead = 0;
	}
};
bool operator < (const NODE &a,const NODE &b){
	if( a.x != b.x ) return a.x < b.x;
	if( a.y != b.y ) return a.y < b.y;
	if( a.px[0] != b.px[0] ) return a.px[0] < b.px[0];
	if( a.px[1] != b.px[1] ) return a.px[1] < b.px[1];
	if( a.px[2] != b.px[2] ) return a.px[2] < b.px[2];
	if( a.py[0] != b.py[0] ) return a.py[0] < b.py[0];
	if( a.py[1] != b.py[1] ) return a.py[1] < b.py[1];
	if( a.py[2] != b.py[2] ) return a.py[2] < b.py[2];
	if( a.dead != b.dead ) return a.dead < b.dead;
	if( a.cdead != b.cdead ) return a.cdead < b.cdead;
	return false;
}

int main(){
	int H,W;
	while( cin >> H >> W && H ){
		int wx[3],wy[3];
		map<NODE,int> done;
		NODE fst; int cc = 0 , ww = 0;
		for(int i = 0 ; i < H ; i++){
			for(int j = 0 ; j < W ; j++){
				cin >> lab[i][j];
				if( lab[i][j] == '@' ) fst.x = j , fst.y = i;
				if( lab[i][j] == 'c' ){
					fst.px[cc] = j;
					fst.py[cc++] = i;
				}
				if( lab[i][j] == 'w' ){
					wx[ww] = j;
					wy[ww++] = i;
				}
			}
		}
		priority_queue< pair<int,NODE> , vector< pair<int,NODE> > , greater<  pair<int,NODE> >  > Q;
		done[fst] = 0;
		Q.push(make_pair(0,fst));
		
		while( Q.size() ){
			NODE q = Q.top().second;
			int cost = Q.top().first;
			Q.pop();
			if( done[q] != cost ) continue;
			if( lab[q.y][q.x] == 'E' ){
				cout << cost << endl;
				goto exit;
			}
			for(int d = 0 ; d < 4 ; d++){
				int tx = q.x + dx[d];
				int ty = q.y + dy[d];
				if( lab[ty][tx] == '#' ) continue;
				int fail = 0;
				for(int i = 0 ; i < ww ; i++){
					if( !(q.dead >> i & 1) && tx == wx[i] && ty == wy[i] ) fail = 1;
				}
				if(fail) continue;
				
				NODE next = q;
				for(int i = 0 ; i < cc ; i++){
					if( !(q.cdead >> i & 1) && tx == q.px[i] && ty == q.py[i] ){
						int mx = tx;
						int my = ty;
						while( lab[my+dy[d]][mx+dx[d]] != '#' ){
							int br = 0;
							for(int j = 0 ; j < cc ; j++){
								if( !(q.cdead >> j & 1) && mx+dx[d] == q.px[j] && my+dy[d] == q.py[j] )
									br = 1;
							}
							if(br) break;
							mx += dx[d];
							my += dy[d];
							for(int j = 0 ; j < ww ; j++){
								if( !(q.dead >> j & 1) && mx == wx[j] && my == wy[j] ){
									br = 1;
									next.cdead |= (1<<i);
									next.dead |= (1<<j);
									mx = 0;
									my = 0;
									break;
								}
							}
							if(br) break;
						}
						next.px[i] = mx;
						next.py[i] = my;
						tx = q.x;
						ty = q.y;
					}
				}
				int diff = q.y != ty || q.x != tx;
				next.x = tx , next.y = ty;
				if( !done.count(next) || done[next] > cost+diff ){
					Q.push(make_pair(diff+cost,next));
					done[next] = cost+diff;
				}
			}
		}
		cout << -1 << endl;
		exit:;
		
	}
}
accuracy: 1
time_ms: 260
memory_kb: 7912
final_rank: 11

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
using namespace std;
#define fr first
#define sc second
#define rep(i,n) for(int i = 0 ; i < n ; i++ )
typedef pair< int , int > Pt;
typedef long long ll;
const int dx[] = { 0, 1, -1, 0}, dy[] = { 1, 0, 0, -1};
struct P{
  Pt nkmr;
  vector< Pt > pnl,cnt;
};
typedef pair< int , P > IP;
Pt Goal;
int h, w;
char mas[10][10];
int search_cnt(int y,int x,P& n){
  rep(i,n.cnt.size()) if(n.cnt[i] == Pt(y,x)) return i;
  return -1;
}
int search_panel(int y,int x,P& n){
  rep(i,n.pnl.size()) if(n.pnl[i] == Pt(y,x)) return i;
  return -1;
}
bool isused(map<ll,bool>& used,P& p){
  ll ret = (p.nkmr.fr << 4) + p.nkmr.sc;
  for(int i = 0 ; i < p.pnl.size() ; i++ ){
    ret <<= 4;
    ret += p.pnl[i].fr;
    ret <<= 4;
    ret += p.pnl[i].sc;
  }
  for(int i = 0 ; i < p.cnt.size() ; i++ ){
    ret <<= 4;
    ret += p.cnt[i].fr;
    ret <<= 4;
    ret += p.cnt[i].sc;
  }
  if(used[ret]++) return true;
  return false;
}
int bfs(P& St){
  queue<pair< int , P > > que;
  map < ll , bool >  used;
  que.push(IP(0,St));
  while(!que.empty()){
    int _cost = que.front().fr;
    P p = que.front().sc;
    que.pop();
    if(p.nkmr == Goal) return _cost;
    if(isused(used,p)) continue;
    rep(i,4){
      P next = p;
      int ny = p.nkmr.fr + dy[i], nx = p.nkmr.sc + dx[i],contena,panel;
      if(mas[ny][nx] == '#' || search_panel(ny,nx,next) != -1) continue;
      if((contena = search_cnt(ny,nx,next)) != -1){ //コンテナあった
        int ty = ny + dy[i], tx = nx + dx[i];
        if(mas[ty][tx] != '.' || search_cnt(ty,tx,next) != -1) continue;
        while(mas[ty][tx] == '.' &&
              search_cnt(ty,tx,next) == -1 && search_panel(ty,tx,next) == -1){
          ty += dy[i], tx += dx[i];
        }
        if((panel = search_panel(ty,tx,next)) != -1){
          next.cnt[contena] = Pt(-1,-1);
          next.pnl[panel] = Pt(-1,-1);
        }else next.cnt[contena] = Pt(ty - dy[i],tx - dx[i]);
        que.push(IP(_cost,next));
      }else que.push(IP(_cost+1,(P){Pt(ny,nx),p.pnl,p.cnt}));
    }
  }
  return -1;
}
int main(){
  while(cin >> h >> w , h ){
    P p = (P){Pt(),vector<Pt>(),vector<Pt>()};
    int cpa = 0,ccn = 0;
    rep(i,h) rep(j,w){
      cin >> mas[i][j];
      if(mas[i][j] == '@') p.nkmr = Pt(i,j), mas[i][j] = '.';
      else if(mas[i][j] == 'w'){
        p.pnl.push_back(Pt(i,j)), mas[i][j] = '.';
      }else if(mas[i][j] == 'c'){
        p.cnt.push_back(Pt(i,j)), mas[i][j] = '.';
      }else if(mas[i][j] == 'E') Goal = Pt(i,j), mas[i][j] = '.';
    }
    cout << bfs(p) << endl;
  }
}
accuracy: 1
time_ms: 280
memory_kb: 6212
final_rank: 9

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
using namespace std;
#define fr first
#define sc second
#define rep(i,n) for(int i = 0 ; i < n ; i++ )
typedef pair< int , int > Pt;
typedef long long ll;
const int dx[] = { 0, 1, -1, 0}, dy[] = { 1, 0, 0, -1};
struct P{
  Pt nkmr;
  vector< Pt > pnl,cnt;
  bool operator<(const P& right)const{
    return nkmr < right.nkmr;
  }
};
typedef pair< int , P > IP;
Pt Goal;
int h, w;
char mas[10][10];
int search_cnt(int y,int x,P& n){
  rep(i,n.cnt.size()) if(n.cnt[i] == Pt(y,x)) return i;
  return -1;
}
int search_panel(int y,int x,P& n){
  rep(i,n.pnl.size()) if(n.pnl[i] == Pt(y,x)) return i;
  return -1;
}
bool isused(map<ll,bool>& used,P& p){
  ll ret = (p.nkmr.fr << 4) + p.nkmr.sc;
  for(int i = 0 ; i < p.pnl.size() ; i++ ){
    ret <<= 4;
    ret += p.pnl[i].fr;
    ret <<= 4;
    ret += p.pnl[i].sc;
  }
  for(int i = 0 ; i < p.cnt.size() ; i++ ){
    ret <<= 4;
    ret += p.cnt[i].fr;
    ret <<= 4;
    ret += p.cnt[i].sc;
  }
  if(used[ret]++) return true;
  return false;
}
int Dijkstra(P& St){
  //priority_queue<pair<int,P>,vector<pair<int,P> >,greater<pair< int,P> > > que;
  queue<pair< int , P > > que;
  map < ll , bool >  used;
  que.push(IP(0,St));
  while(!que.empty()){
    int _cost = que.front().fr;
    P p = que.front().sc;
    que.pop();
    if(p.nkmr == Goal) return _cost;
    if(isused(used,p)) continue;
    rep(i,4){
      P next = p;
      int ny = p.nkmr.fr + dy[i], nx = p.nkmr.sc + dx[i],contena,panel;
      if(mas[ny][nx] == '#' || search_panel(ny,nx,next) != -1) continue;
      if((contena = search_cnt(ny,nx,next)) != -1){ //コンテナあった
        int ty = ny + dy[i], tx = nx + dx[i];
        if(mas[ty][tx] != '.' || search_cnt(ty,tx,next) != -1) continue;
        while(mas[ty][tx] == '.' &&
              search_cnt(ty,tx,next) == -1 && search_panel(ty,tx,next) == -1){
          ty += dy[i], tx += dx[i];
        }
        if((panel = search_panel(ty,tx,next)) != -1){
          next.cnt[contena] = Pt(-1,-1);
          next.pnl[panel] = Pt(-1,-1);
        }else next.cnt[contena] = Pt(ty - dy[i],tx - dx[i]);
        que.push(IP(_cost,next));
      }else que.push(IP(_cost+1,(P){Pt(ny,nx),p.pnl,p.cnt}));
    }
  }
  return -1;
}
int main(){
  while(cin >> h >> w , h ){
    P p = (P){Pt(),vector<Pt>(),vector<Pt>()};
    int cpa = 0,ccn = 0;
    rep(i,h) rep(j,w){
      cin >> mas[i][j];
      if(mas[i][j] == '@') p.nkmr = Pt(i,j), mas[i][j] = '.';
      else if(mas[i][j] == 'w'){
        p.pnl.push_back(Pt(i,j)), mas[i][j] = '.';
      }else if(mas[i][j] == 'c'){
        p.cnt.push_back(Pt(i,j)), mas[i][j] = '.';
      }else if(mas[i][j] == 'E') Goal = Pt(i,j), mas[i][j] = '.';
    }
    cout << Dijkstra(p) << endl;
  }
}
accuracy: 1
time_ms: 280
memory_kb: 6212
final_rank: 9

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define fr first
#define sc second
#define rep(i,n) for(int i = 0 ; i < n ; i++ )
typedef pair< int , int > Pt;
typedef long long ll;
const int dx[] = { 0, 1, -1, 0}, dy[] = { 1, 0, 0, -1};
struct P{
  Pt nkmr;
  vector< Pt > pnl,cnt;
  bool operator<(const P& right)const{
    return nkmr < right.nkmr;
  }
};
typedef pair< int , P > IP;
Pt Goal;
int h, w;
char mas[10][10];
int search_cnt(int y,int x,P& n){
  rep(i,n.cnt.size()) if(n.cnt[i] == Pt(y,x)) return i;
  return -1;
}
int search_panel(int y,int x,P& n){
  rep(i,n.pnl.size()) if(n.pnl[i] == Pt(y,x)) return i;
  return -1;
}
bool isused(set<ll>& used,P& p){
  ll ret = (p.nkmr.fr << 4) + p.nkmr.sc;
  sort(p.pnl.begin(),p.pnl.end()),sort(p.cnt.begin(),p.cnt.end());
  for(int i = 0 ; i < p.pnl.size() ; i++ ){
    ret <<= 4;
    ret += p.pnl[i].fr;
    ret <<= 4;
    ret += p.pnl[i].sc;
  }
  for(int i = 0 ; i < p.cnt.size() ; i++ ){
    ret <<= 4;
    ret += p.cnt[i].fr;
    ret <<= 4;
    ret += p.cnt[i].sc;
  }
  if(used.find(ret) != used.end()) return true;
  used.insert(ret);
  return false;
}
int Dijkstra(P& St){
  int dbk;
  priority_queue<pair<int,P>,vector<pair<int,P> >,greater<pair< int,P> > > que;
  set < ll >  used;
  que.push(IP(0,St));
  while(!que.empty()){
    int _cost = que.top().fr;
    P p = que.top().sc;
    que.pop();
    if(p.nkmr == Goal) return _cost;
    if(isused(used,p)) continue;
    rep(i,4){
      P next = p;
      int ny = p.nkmr.fr + dy[i], nx = p.nkmr.sc + dx[i],contena,panel;
      if(mas[ny][nx] == '#' || search_panel(ny,nx,next) != -1) continue;
      if((contena = search_cnt(ny,nx,next)) != -1){ //コンテナあった
        int ty = ny + dy[i], tx = nx + dx[i];
        if(mas[ty][tx] != '.' || search_cnt(ty,tx,next) != -1) continue;
        while(mas[ty][tx] == '.' &&
              search_cnt(ty,tx,next) == -1 && search_panel(ty,tx,next) == -1){
          ty += dy[i], tx += dx[i];
        }
        if((panel = search_panel(ty,tx,next)) != -1){
          next.cnt[contena] = Pt(-1,-1);
          next.pnl[panel] = Pt(-1,-1);
        }else next.cnt[contena] = Pt(ty - dy[i],tx - dx[i]);
        que.push(IP(_cost,next));
      }else{
        que.push(IP(_cost+1,(P){Pt(ny,nx),p.pnl,p.cnt}));
      }
    }
  }
  return -1;
}
int main(){
  while(cin >> h >> w , h ){
    P p = (P){Pt(),vector<Pt>(),vector<Pt>()};
    int cpa = 0,ccn = 0;
    rep(i,h) rep(j,w){
      cin >> mas[i][j];
      if(mas[i][j] == '@') p.nkmr = Pt(i,j), mas[i][j] = '.';
      else if(mas[i][j] == 'w'){
        p.pnl.push_back(Pt(i,j)), mas[i][j] = '.';
      }else if(mas[i][j] == 'c'){
        p.cnt.push_back(Pt(i,j)), mas[i][j] = '.';
      }else if(mas[i][j] == 'E') Goal = Pt(i,j), mas[i][j] = '.';
    }
    cout << Dijkstra(p) << endl;
  }
}
accuracy: 1
time_ms: 390
memory_kb: 4000
final_rank: 12

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
using namespace std;
#define fr first
#define sc second
#define rep(i,n) for(int i = 0 ; i < n ; i++ )
typedef pair< int , int > Pt;
typedef long long ll;
const int dx[] = { 0, 1, -1, 0}, dy[] = { 1, 0, 0, -1};
struct P{
  Pt nkmr;
  vector< Pt > pnl,cnt;
  bool operator<(const P& right)const{
    return nkmr < right.nkmr;
  }
};
typedef pair< int , P > IP;
Pt Goal;
int h, w;
char mas[10][10];
int search_cnt(int y,int x,P& n){
  rep(i,n.cnt.size()) if(n.cnt[i] == Pt(y,x)) return i;
  return -1;
}
int search_panel(int y,int x,P& n){
  rep(i,n.pnl.size()) if(n.pnl[i] == Pt(y,x)) return i;
  return -1;
}
bool isused(map<ll,bool>& used,P& p){
  ll ret = (p.nkmr.fr << 4) + p.nkmr.sc;
  sort(p.pnl.begin(),p.pnl.end()),sort(p.cnt.begin(),p.cnt.end());
  for(int i = 0 ; i < p.pnl.size() ; i++ ){
    ret <<= 4;
    ret += p.pnl[i].fr;
    ret <<= 4;
    ret += p.pnl[i].sc;
  }
  for(int i = 0 ; i < p.cnt.size() ; i++ ){
    ret <<= 4;
    ret += p.cnt[i].fr;
    ret <<= 4;
    ret += p.cnt[i].sc;
  }
  if(used[ret]) return true;
  used[ret] = true;
  return false;
}
int Dijkstra(P& St){
  int dbk;
  priority_queue<pair<int,P>,vector<pair<int,P> >,greater<pair< int,P> > > que;
  map < ll , bool > used;
  que.push(IP(0,St));
  while(!que.empty()){
    int _cost = que.top().fr;
    P p = que.top().sc;
    que.pop();
    if(p.nkmr == Goal) return _cost;
    if(isused(used,p)) continue;
    rep(i,4){
      P next = p;
      int ny = p.nkmr.fr + dy[i], nx = p.nkmr.sc + dx[i],contena,panel;
      if(mas[ny][nx] == '#' || search_panel(ny,nx,next) != -1) continue;
      if((contena = search_cnt(ny,nx,next)) != -1){ //コンテナあった
        int ty = ny + dy[i], tx = nx + dx[i];
        if(mas[ty][tx] != '.' || search_cnt(ty,tx,next) != -1) continue;
        while(mas[ty][tx] == '.' &&
              search_cnt(ty,tx,next) == -1 && search_panel(ty,tx,next) == -1){
          ty += dy[i], tx += dx[i];
        }
        if((panel = search_panel(ty,tx,next)) != -1){
          next.cnt[contena] = Pt(-1,-1);
          next.pnl[panel] = Pt(-1,-1);
        }else next.cnt[contena] = Pt(ty - dy[i],tx - dx[i]);
        que.push(IP(_cost,next));
      }else{
        que.push(IP(_cost+1,(P){Pt(ny,nx),p.pnl,p.cnt}));
      }
    }
  }
  return -1;
}
int main(){
  while(cin >> h >> w , h ){
    P p = (P){Pt(),vector<Pt>(),vector<Pt>()};
    int cpa = 0,ccn = 0;
    rep(i,h) rep(j,w){
      cin >> mas[i][j];
      if(mas[i][j] == '@') p.nkmr = Pt(i,j), mas[i][j] = '.';
      else if(mas[i][j] == 'w'){
        p.pnl.push_back(Pt(i,j)), mas[i][j] = '.';
      }else if(mas[i][j] == 'c'){
        p.cnt.push_back(Pt(i,j)), mas[i][j] = '.';
      }else if(mas[i][j] == 'E') Goal = Pt(i,j), mas[i][j] = '.';
    }
    cout << Dijkstra(p) << endl;
  }
}
accuracy: 1
time_ms: 380
memory_kb: 4656
final_rank: 13

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
#include<map>
#include<cassert>
#include<climits>
#include<queue>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<29)
#define MAX 10

using namespace std;

struct P
{
  int x,y;
  P(int x=inf,int y=inf):x(x),y(y){}
  bool operator < (const P& a)const
  {
    if(x != a.x)return x < a.x;
    return y < a.y;
  }
};

struct Pox
{
  string field;
  P cur;
  short cost;
  Pox(string field="$",P cur = P(),short cost=SHRT_MAX):field(field),cur(cur),cost(cost){}
  bool operator < (const Pox& a)const
  {
    return cost > a.cost;
  }
};

map<string,short> mincost;
int H,W;
P st,ed;
vector<P> stone;
string field;
int dx[] = {-1,+0,+1,+0};
int dy[] = {+0,-1,+0,+1};

void compute()
{
  priority_queue<Pox> Q;
  Q.push(Pox(field,st,0));
  mincost.clear();
  mincost[field] = 0;

  while(!Q.empty())
    {
      Pox pox = Q.top(); Q.pop();
      int x = pox.cur.x;
      int y = pox.cur.y;
 
      if(field[y*W+x] == 'E')
	{
	  cout << pox.cost << endl;
	  return;
	}

      rep(i,4)
	{
	  int nx = x + dx[i];
	  int ny = y + dy[i];
	  string nfield = pox.field;
	  if(!(0 <= nx && nx < W && 0 <= ny && ny < H))continue;
	  if(pox.field[W*ny+nx] == 'c')
	    {
	      int sx = nx+dx[i], sy = ny+dy[i];
	      while(0 <= sx && sx < W && 0 <= sy && sy < H)
		{
		  if(pox.field[sy*W+sx] == 'c')break;
		  if(pox.field[sy*W+sx] == '#')break;
		  if(pox.field[sy*W+sx] == 'w')break;
		  sx += dx[i];
		  sy += dy[i];
		}

	      if(0 <= sx && sx < W && 0 <= sy && sy < H)
		{
		  if(pox.field[sy*W+sx] == 'w')
		    {
		      nfield[ny*W+nx] = '.';
		      nfield[sy*W+sx] = '.';
		      Q.push(Pox(nfield,pox.cur,pox.cost));
		      continue;
		    }
		}

	      sx -= dx[i],sy -= dy[i];
	      if(sx == nx && sy == ny)continue;//cannot move the stone

	      nfield[W*ny+nx] = '.';
	      if(ny == ed.y && nx == ed.x)nfield[W*ed.y+ed.x] = 'E';
	      nfield[W*sy+sx] = 'c';
	      Q.push(Pox(nfield,pox.cur,pox.cost));
	    }
	}

      
      rep(i,4)
	{
	  int nx = pox.cur.x + dx[i];
	  int ny = pox.cur.y + dy[i];
	  string nfield = pox.field;

	  if(!(0 <= nx && nx < W && 0 <= ny && ny < H))continue;
	  if(pox.field[W*ny+nx] == '#')continue;
	  if(pox.field[W*ny+nx] == 'w')continue;

	  if(pox.field[W*ny+nx] == 'c')continue;

	  nfield[y*W+x] = '.';

	  assert(nfield[ny*W+nx] == '.' || nfield[ny*W+nx] == 'E');
	  nfield[ny*W+nx] = '@';

	  if(mincost.find(nfield) == mincost.end())
	    {
	      mincost[nfield] = pox.cost + 1;
	      Q.push(Pox(nfield,P(nx,ny),pox.cost+1));
	    }
	  else
	    {
	      if(mincost[nfield] > pox.cost + 1)
		{
		  mincost[nfield] = pox.cost + 1;
		  Q.push(Pox(nfield,P(nx,ny),pox.cost+1));
		}
	    }
	}
      
    }
  cout << -1 << endl;
}

int main()
{
  while(cin >> H >> W,H|W)
    {
      st = P(inf,inf);
      field.clear();
      int dex = 0;
      rep(i,H)
	{
	  string line;
	  cin >> line;
	  field += line;
	  rep(j,W)
	    {
	      if(line[j] == '@')st = P(j,i),line[j] = '.';
	      if(line[j] == 'E')ed = P(j,i);
	      if(line[j] == 'c')stone.push_back(P(j,i));
	    }
	}
      
      assert(!(st.x == inf && st.y == inf));

      compute();

    }
  return 0;
}

/*

テ」ツつウテ」ツδウテ」ツδ?」ツδ甘」ツ?古」ツつエテ」ツδシテ」ツδォテ」ツ?ォテ」ツ?ョテ」ツ?」テ」ツ?淌・ツセツ古・ツ?催・ツコツヲテ」ツ?敕」ツ?ョテ」ツつウテ」ツδウテ」ツδ?」ツδ甘」ツつ津・ツ仰陛」ツ?凝」ツ?療」ツ?淌ゥツ堋崚」ツ?ォテ」ツ?。テ」ツつε」ツつ禿」ツ?ィテ」ツつエテ」ツδシテ」ツδォテ」ツ?古・ツセツゥテ・ツ?ε」ツ?陛」ツつ古」ツつ凝」ツ?凝ッツシツ淌ッツシツ暗・ツョツ淌ィツ」ツ?ヲツャツ。テァツャツャテ」ツ??」ツ?妥」ツ?ゥテッツシツ?
.c.    ...    ... 
.E. => .c. => .Ec 
.#.    .#.    .#.


テ」ツつウテ」ツδウテ」ツδ?」ツδ甘」ツ?ョテ・ツ仰陛」ツ?凝」ツ?凖ヲツ鳴ケテヲツウツ陛」ツ?ョティツァツ」テゥツ?暗」ツδ淌」ツつケ
テ、ツサツ甘」ツ??」ツつ凝・ツ?エテヲツ可?」ツ?ォテゥツ堋」テヲツ篠・テ」ツ?凖」ツつ凝ッツシツ氾」ツ?、テ」ツ?ョテ」ツつサテ」ツδォテ」ツ?ォテ」ツ?づ」ツつ凝」ツつウテ」ツδウテ」ツδ?」ツδ甘」ツ?ッテ、ツサツサテヲツ?湘」ツ?ォテ・ツ仰陛」ツ?凝」ツ?凖、ツコツ凝」ツ?古」ツ?ァテ」ツ?催」ツつ?


.....     ..c..       ..c..
..c..     .....       .....
.c@c. =>  c.@.c  ,    .c@.c テ」ツ?ィテ」ツ?凝、ツサツサテヲツ?湘」ツ?ォテ・ツ仰陛」ツ?凝」ツ?崚」ツつ?
.....     .....       .....
.....     .....       .....

  

10 10
##########
#..#@#...#
#..#c#...#
#........#
#..cEc...#
#...#....#
#........#
#........#
#........#
##########
0 0

Ans : 7

10 10
##########
#........#
#..@.c..c#
#...c....#
#...ww.###
#........#
##.......#
#..####..#
#..wE#...#
##########
0 0

Ans : 31
 */
accuracy: 1
time_ms: 390
memory_kb: 11820
final_rank: 14