#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
#include <cfloat>
#include <ctime>
#include <cassert>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <numeric>
#include <list>


using namespace std;

#ifdef _MSC_VER
#define __typeof__ decltype
template <class T> int __builtin_popcount(T n) { return n ? 1 + __builtin_popcount(n & (n - 1)) : 0; }
#endif

#define foreach(it, c) for (__typeof__((c).begin()) it=(c).begin(); it != (c).end(); ++it)
#define all(c) (c).begin(), (c).end()
#define rall(c) (c).rbegin(), (c).rend()
#define CLEAR(arr, val) memset(arr, val, sizeof(arr))

#define rep(i, n) for (int i = 0; i < n; ++i)

template <class T> void max_swap(T& a, const T& b) { a = max(a, b); }
template <class T> void min_swap(T& a, const T& b) { a = min(a, b); }

typedef long long ll;
typedef pair<int, int> pint;

const double EPS = 1e-8;
const double PI = acos(-1.0);
const int dx[] = { 0, 1, 0, -1 };
const int dy[] = { 1, 0, -1, 0 };


#ifdef _MSC_VER
#include <unordered_map>
#else
#include <tr1/unordered_map>
using namespace tr1;
#endif

int pos_enc(int x, int y)
{
	return (x & 0xf) | ((y & 0xf) << 4);
}
void pos_dec(ll enc, int& x, int& y)
{
	x = enc & 0xf;
	y = (enc >> 4) & 0xf;
}
ll encode(int x, int y, int* con_x, int* con_y, int pane)
{
	ll res = pos_enc(x, y);
	for (int i = 0; i < 3; ++i)
		res = (res << 8) | 0xff & pos_enc(con_x[i], con_y[i]);
	res = (res << 3) | 0x7 & pane;
	return res;
}
void decode(ll enc, int& x, int& y, int* con_x, int* con_y, int& pane)
{
	pane = enc & 0x7; enc >>= 3;
	for (int i = 2; i >= 0; --i)
	{
		pos_dec(enc & 0xff, con_x[i], con_y[i]);
		enc >>= 8;
	}
	pos_dec(enc, x, y);
}
int main()
{
	ios::sync_with_stdio(false);

	int h, w;
	while (cin >> h >> w, h)
	{
		char s[16][16];
		for (int i = 0; i < h; ++i)
			cin >> s[i];

		int sx, sy, gx, gy;
		int cx[3], cy[3];
		CLEAR(cx, 0);
		CLEAR(cy, 0);
		for (int y = 0, c = 0, p = 0; y < h; ++y)
		{
			for (int x = 0; x < w; ++x)
			{
				if (s[y][x] == '@')
				{
					sx = x, sy = y;
					s[y][x] = '.';
				}
				else if (s[y][x] == 'E')
				{
					gx = x, gy = y;
					s[y][x] = '.';
				}
				else if (s[y][x] == 'w')
					s[y][x] = '0' + p++;
				else if (s[y][x] == 'c')
				{
					cx[c] = x;
					cy[c] = y;
					++c;
					s[y][x] = '.';
				}
			}
		}

		ll enc = encode(sx, sy, cx, cy, 0x7);

		typedef pair<int, ll> P;
		priority_queue<P, vector<P>, greater<P> > q;
		unordered_map<ll, int> dis;
		dis[enc] = 0;
		q.push(P(0, enc));
		int res = -1;
		while (!q.empty())
		{
			P t = q.top(); q.pop();
			if (t.first > dis[t.second])
				continue;

			int cc = t.first;
			int nc = cc + 1;
			int x, y, cx[3], cy[3], pane;
			decode(t.second, x, y, cx, cy, pane);
			if (x == gx && y == gy)
			{
				res = cc;
				break;
			}

			for (int i = 0; i < 4; ++i)
			{
				int tx = x + dx[i], ty = y + dy[i];

				bool cont = false;
				for (int j = 0; j < 3; ++j)
				{
					if (tx == cx[j] && ty == cy[j])
					{
						cont = true;
						int wx = tx, wy = ty;
						int ccx[3], ccy[3];
						copy(cx, cx + 3, ccx);
						copy(cy, cy + 3, ccy);

						ll e;
						for (e = -1; e == -1; )
						{
							wx += dx[i], wy += dy[i];

							bool other_cont = false;
							for (int k = 0; k < 3; ++k)
								if (k != j && wx == cx[k] && wy == cy[k])
									other_cont = true;
							if (s[wy][wx] == '#' || other_cont)
							{
								wx -= dx[i], wy -= dy[i];
								ccx[j] = wx, ccy[j] = wy;
								e = encode(x, y, ccx, ccy, pane);
							}
							else if (isdigit(s[wy][wx]) && (pane >> (s[wy][wx] - '0') & 1))
							{
								ccx[j] = 0, ccy[j] = 0;
								e = encode(x, y, ccx, ccy, pane ^ (1 << (s[wy][wx] - '0')));
							}
						}
						if (!dis.count(e) || cc < dis[e])
						{
							dis[e] = cc;
							q.push(P(cc, e));
							break;
						}
					}
				}
				if (cont)
					continue;

				if (s[ty][tx] == '.'
					|| (isdigit(s[ty][tx]) && !(pane >> (s[ty][tx] - '0') & 1)))
				{
					ll e = encode(tx, ty, cx, cy, pane);
					if (!dis.count(e) || nc < dis[e])
					{
						dis[e] = nc;
						q.push(P(nc, e));
					}
				}
			}
		}

		cout << res << endl;
	}
}

Measured memory_bytes: 0