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

Measured memory_bytes: 6376