#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;
}

Measured memory_bytes: 53376