#include <cstdio>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

const int INF = INT_MAX / 4;
int dy[] = {0, 1, -1, 0};
int dx[] = {1, 0, 0, -1};

class Data
{
public:
    int y, x;                  // プレイヤーの位置
    vector<pair<int, int> > c; // コンテナの位置
    bitset<3> w;               // パネルの状態

    Data()
    {
        c.assign(3, make_pair(0,0));
    }
    long long toLL()
    {
        long long ret = (y << 4) + x;
        sort(c.begin(), c.end());
        for(int i=0; i<3; ++i){
            ret <<= 4;
            ret += c[i].first;
            ret <<= 4;
            ret += c[i].second;
        }
        ret <<= 4;
        ret += w.to_ulong();
        return ret;
    }
};

vector<string> s;

int solve(Data d0)
{
    deque<Data> q;
    set<long long> memo;
    q.push_back(d0);
    memo.insert(d0.toLL());

    int ret = 0;
    while(!q.empty()){
        int m = q.size();
        while(--m >= 0){
            Data d = q.front();
            q.pop_front();
            if(s[d.y][d.x] == 'E')
                return ret;

            for(int i=0; i<4; ++i){
                int y2 = d.y + dy[i];
                int x2 = d.x + dx[i];
                if(s[y2][x2] == '#') // プレイヤーの隣が壁
                    continue;

                Data d2 = d;
                if(isdigit(s[y2][x2])){ // プレイヤーの隣がパネル
                    if(!d2.w[s[y2][x2]-'0']) // パネルが放電していないならば移動不可
                        continue;
                    d2.y = y2;
                    d2.x = x2;
                    if(memo.find(d2.toLL()) == memo.end()){
                        q.push_back(d2);
                        memo.insert(d2.toLL());
                    }
                }else if(find(d2.c.begin(), d2.c.end(), make_pair(y2, x2)) != d2.c.end()){ // プレイヤーの隣がコンテナ
                    int k = find(d2.c.begin(), d2.c.end(), make_pair(y2, x2)) - d2.c.begin();
                    // 何かに衝突するまでコンテナを移動させる
                    for(;;){
                        if(s[y2+dy[i]][x2+dx[i]] == '#')
                            break;
                        if(find(d2.c.begin(), d2.c.end(), make_pair(y2+dy[i], x2+dx[i])) != d2.c.end())
                            break;
                        if(isdigit(s[y2+dy[i]][x2+dx[i]]) && !d2.w[s[y2+dy[i]][x2+dx[i]]-'0']){ // パネルが放電する場合
                            d2.w[s[y2+dy[i]][x2+dx[i]]-'0'] = true;
                            y2 = x2 = 0;
                            break;
                        }
                        y2 += dy[i];
                        x2 += dx[i];
                    }
                    d2.c[k] = make_pair(y2, x2);
                    if(memo.find(d2.toLL()) == memo.end()){
                        q.push_front(d2);
                        ++ m;
                        memo.insert(d2.toLL());
                    }
                }else{
                    d2.y = y2;
                    d2.x = x2;
                    if(memo.find(d2.toLL()) == memo.end()){
                        q.push_back(d2);
                        memo.insert(d2.toLL());
                    }
                }
            }
        }
        ++ ret;
    }

    return -1;
}

int main()
{
    for(;;){
        int h, w;
        cin >> h >> w;
        if(h == 0)
            return 0;

        Data d;
        int p = 0;
        int q = 0;
        s.assign(h, string(w, ' '));
        for(int i=0; i<h; ++i){
            for(int j=0; j<w; ++j){
                cin >> s[i][j];
                if(s[i][j] == '@'){
                    d.y = i;
                    d.x = j;
                    s[i][j] = '.';
                }else if(s[i][j] == 'c'){
                    d.c[p] = make_pair(i, j);
                    s[i][j] = '.';
                    ++ p;
                }else if(s[i][j] == 'w'){
                    s[i][j] = q + '0';
                    ++ q;
                }
            }
        }

        cout << solve(d) << endl;
    }
}

Measured memory_bytes: 2556