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

Solution in JAVA (judge verdict: Memory Limit Exceeded)

import java.util.*;
import static java.lang.Math.*;
import static java.lang.System.out;

// AOJ4thJun
public class Main {
	final Scanner sc=new Scanner(System.in);
	final int[] vx={0,1,0,-1,-1,1,1,-1}, vy={-1,0,1,0,-1,-1,1,1};
	final int INF=1<<26;
	final double EPS=1.0e-08;
	public static void main(String[] args) {
		long s=System.currentTimeMillis();
		new Main().doIt();
		out.println((System.currentTimeMillis()-s)+"msec");
	}
	void doIt(){
		new AOJ1038();
	}
	
	// ICPC WarmUp 2009 - D
	// TLE(11.03sec)
	class AOJ1038{
		AOJ1038(){
			while(sc.hasNext()){
				int H=sc.nextInt(),W=sc.nextInt(),sx=0,sy=0,cc=0,ww=0;
				int[] cx=new int[3],cy=new int[3],wx=new int[3], wy=new int[3];
				Arrays.fill(cx, -1);	Arrays.fill(cy, -1);	Arrays.fill(wx, -1);	Arrays.fill(wy, -1);
				if((W|H)==0)	break;
				char[][] c=new char[W][H];
				for(int y=0; y<H; y++){
					String line=sc.next();
					for(int x=0; x<W; x++){
						c[x][y]=line.charAt(x);
						if(c[x][y]=='@'){
							sx=x;	sy=y;
						}else if(c[x][y]=='c'){
							cx[cc]=x;	cy[cc]=y;
							cc++;	c[x][y]='.';
						}else if(c[x][y]=='w'){
							wx[ww]=x;	wy[ww]=y;
							ww++;	c[x][y]='.';
						}
					}
				}
				LinkedList<DC> open=new LinkedList<DC>();
				open.add(new DC(0,sx,sy,cx,cy,wx,wy));
				//HashSet<DC> close=new HashSet<DC>();
				TreeSet<DC> close=new TreeSet<Main.AOJ1038.DC>();
				close.add(new DC(0,sx,sy,cx,cy,wx,wy));
				int ans=INF;
				while(!open.isEmpty()){
					DC now=open.poll();
					for(int i=0; i<4; i++){
						int xx=now.x+vx[i],yy=now.y+vy[i];
						if(c[xx][yy]=='#')	continue;
						if(now.panel(xx, yy)>=0)	continue;
						DC next=new DC(now.step+1,xx,yy,now.cx,now.cy,now.wx,now.wy);
						if(close.contains(next)){
							//System.out.println("CONT:"+xx+" "+yy+" "+(now.step+1));
							continue;
						}
						int cidx=now.container(xx, yy);
						if(cidx>=0){
							if(c[xx+vx[i]][yy+vy[i]]!='#' && now.container(xx+vx[i], yy+vy[i])<0){
								int xxx=xx,yyy=yy;
								int[] wwx=now.wx.clone(),wwy=now.wy.clone(),ccx=now.cx.clone(),ccy=now.cy.clone();
								while(true){
									xxx+=vx[i];	yyy+=vy[i];
									int pidx=now.panel(xxx, yyy);
									if(pidx>=0){
										wwx[pidx]=-1;	wwy[pidx]=-1;
										ccx[cidx]=-1;	ccy[cidx]=-1;
										break;
									}
									if(now.container(xxx, yyy)>=0){
										ccx[cidx]=xxx-vx[i];	ccy[cidx]=yyy-vy[i];
										break;
									}
									if(c[xxx][yyy]=='#'){
										ccx[cidx]=xxx-vx[i];	ccy[cidx]=yyy-vy[i];
										break;
									}
								}
								//DC next2=new DC(now.step+1,xx,yy,ccx.clone(),ccy.clone(),wwx.clone(),wwy.clone());
								//open.add(next2);
								//close.add(next2);
								DC next3=new DC(now.step,xx-vx[i],yy-vy[i],ccx.clone(),ccy.clone(),wwx.clone(),wwy.clone());
								open.add(next3);
								close.add(next3);
							}
							continue;
						}
						if(c[xx][yy]=='E'){
							ans=min(ans,now.step+1);
							break;
							//continue;
						}
						//System.out.println(xx+" "+yy+" "+(now.step+1));
						open.add(next);
						close.add(next);
					}
				}
				//System.out.print("ANS=");
				System.out.println((ans>=INF?"-1":ans));
			}
		}
		
		void disp(char[][] c){
			for(int y=0; y<c[0].length; y++){
				for(int x=0; x<c.length; x++)	System.out.print(c[x][y]);
				System.out.println();
			}
		}
		class DC implements Comparable<DC>{
			int step,x,y;
			int[] cx,cy,wx,wy;
			public DC(int step,int x,int y,int[] cx,int[] cy,int[] wx,int[] wy) {
				this.step = step; this.x = x; this.y = y;
				this.cx=cx; this.cy=cy; this.wx=wx; this.wy=wy;
			}
			int panel(int x,int y){
				for(int i=0; i<3; i++)	if(this.wx[i]==x && this.wy[i]==y)	return i;
				return -1;
			}
			int container(int x,int y){
				for(int i=0; i<3; i++)	if(this.cx[i]==x && this.cy[i]==y)	return i;
				return -1;
			}
			@Override public int compareTo(DC o) {
				if(this.step<o.step)	return -1;
				if(this.x<o.x)	return -1;
				if(this.x>o.x)	return 1;
				if(this.y<o.y)	return -1;
				if(this.y>o.y)	return 1;
				if(this.step>=o.step)
					if(Arrays.equals(this.cx, o.cx) && Arrays.equals(this.cy, o.cy) && Arrays.equals(this.wx, o.wx) && Arrays.equals(this.wy, o.wy))	return 0;
				return -1;
			}
		}
		char[][] deepCopy(char[][] c){
			char[][] res=new char[c.length][c[0].length];
			for(int i=0; i<c.length; i++){
				for(int j=0; j<c[0].length; j++)	res[i][j]=c[i][j];
			}
			return res;
		}
	}
	
	// ICPC2011 - E
	class AOJ1169{
		int s,W,H,sum;
		int[][] a,aa;
		AOJ1169(){
			while(true){
				H=sc.nextInt();	W=sc.nextInt();	s=sc.nextInt();
				if((H|W)==0)	break;
				a=new int[W+1][H+1];	aa=new int[W+1][H+1];
				for(int y=1; y<=H; y++){
					for(int x=1; x<=W; x++)	a[x][y]=sc.nextInt();
				}
				aa[1][1]=a[1][1];
				for(int i=2; i<=W; i++)	aa[i][1]=aa[i-1][1]+a[i][1];
				for(int i=2; i<=H; i++)	aa[1][i]=aa[1][i-1]+a[1][i];
				for(int x=2; x<=W; x++){
					for(int y=2; y<=H; y++)	aa[x][y]=aa[x-1][y]+aa[x][y-1]+a[x][y]-aa[x-1][y-1];
				}
				sum=aa[W][H];
				pair[][][][] dp=new pair[W+1][H+1][W+1][H+1];
				
//				for(int y=1; y<=H; y++){
//					for(int x=1; x<=W; x++)	System.out.printf("%4d",aa[x][y]);
//					System.out.println();
//				}
				
				//System.out.print("ANS=");
				System.out.println(solve(dp,new pair(0,INF),1,1,W,H));
			}
		}
		pair solve(pair[][][][] dp,pair p,int lx,int ly,int rx,int ry){
			if(dp[lx][ly][rx][ry]!=null)	return dp[lx][ly][rx][ry];
			else{
				int region=aa[rx][ry]-(aa[lx-1][ry]+aa[rx][ly-1])+aa[lx-1][ly-1];
				pair r1=new pair(),r2=new pair(),ret=new pair(p.depth+1,s-(sum-region));
				for(int x=lx; x<rx; x++){
					int rr1=aa[x][ry]-(aa[lx-1][ry]+aa[x][ly-1])+aa[lx-1][ly-1];
					int rr2=aa[rx][ry]-(aa[x][ry]+aa[rx][ly-1])+aa[x][ly-1];
					if(sum-rr1<=s && sum-rr2<=s){
						r1=solve(dp,p,lx,ly,x,ry);
						dp[lx][ly][x][ry]=r1;
						r2=solve(dp,p,x+1,ly,rx,ry);
						dp[x+1][ly][rx][ry]=r2;
						ret=pmax(ret,new pair(r1.depth+r2.depth-p.depth,min(r1.margin,r2.margin)));
					}
				}
				for(int y=ly; y<ry; y++){
					int rr1=aa[rx][y]-(aa[lx-1][y]+aa[rx][ly-1])+aa[lx-1][ly-1];
					int rr2=aa[rx][ry]-(aa[lx-1][ry]+aa[rx][y])+aa[lx-1][y];
					if(sum-rr1<=s && sum-rr2<=s){
						r1=solve(dp,p,lx,ly,rx,y);
						dp[lx][ly][rx][y]=r1;
						r2=solve(dp,p,lx,y+1,rx,ry);
						dp[lx][y+1][rx][ry]=r2;
						ret=pmax(ret,new pair(r1.depth+r2.depth-p.depth,min(r1.margin,r2.margin)));
					}
				}
				//System.out.println(ret);
				return ret;
			}
		}
		pair pmax(pair r1, pair r2) {
			if(r1.depth<r2.depth)	return r2;
			if(r1.depth>r2.depth)	return r1;
			if(r1.margin<r2.margin)	return r2;
			if(r1.margin>r2.margin)	return r1;
			return r1;
		}
		class pair{
			int depth,margin;
			pair(int d,int m){this.depth=d; this.margin=m;}
			pair(int d){this.depth=d; this.margin=0;}
			pair(){this.depth=-1;this.margin=-1;}
			pair(pair p){this.depth=p.depth; this.margin=p.margin;}
			@Override public pair clone(){	return new pair(this);}
			@Override public String toString(){return this.depth+" "+this.margin;}
		}
	}

	
	void AOJ2200(){
		int c=0;
		while(true){
			int N=sc.nextInt(),M=sc.nextInt();
			if((N|M)==0)	break;
			int[][] L=new int[N+1][N+1],S=new int[N+1][N+1];
			for(int i=0; i<=N; i++){
				for(int j=0; j<=N; j++){
					if(i==j)	continue;
					L[i][j]=INF;	S[i][j]=INF;
				}
			}
			for(int i=0; i<M; i++){
				int x=sc.nextInt(),y=sc.nextInt(),t=sc.nextInt();
				if(sc.next().equals("L")){
					L[x][y]=min(L[x][y], t);	L[y][x]=min(L[y][x], t);
				}else{
					S[x][y]=min(S[x][y], t);	S[y][x]=min(S[y][x], t);
				}
			}
			for(int i=1; i<=N; i++){
				for(int j=1; j<=N; j++){
					for(int k=1; k<=N; k++){
						L[j][k]=min(L[j][k],L[j][i]+L[i][k]);
						S[j][k]=min(S[j][k],S[j][i]+S[i][k]);
					}
				}
			}
			
			//debug
//			for(int i=1; i<=N; i++){
//				for(int j=1; j<=N; j++){
//					System.out.print(L[i][j]+" ");
//				}
//				System.out.println();
//			}
			
			int R=sc.nextInt();
			int[] d=new int[R];
			for(int i=0; i<R; i++)	d[i]=sc.nextInt();
			LinkedList<C2200> open=new LinkedList<C2200>();
			//PriorityQueue<C2200> open=new PriorityQueue<C2200>();
			open.add(new C2200(0,d[0],0));
			int[][] close=new int[R][N+1];
			for(int i=0; i<R; i++){
				for(int j=0; j<=N; j++)	close[i][j]=INF;
			}
			int ans=INF;
			close[0][d[0]]=0;
			
			System.err.print(++c+" ");
			System.err.print("R "+R+" N "+N+" M"+M+" ANS=");
			
			while(!open.isEmpty()){
				C2200 now=open.poll();
				if(now.now==R-1){
					ans=min(ans,now.time);
					continue;
				}
				//System.err.println("STEP"+now.now+" NOW"+d[now.now]+" BOAT"+now.boat+" TIME"+now.time+" NEXT"+d[now.now+1]);
				boolean goal=now.now+1==R-1;
				if(now.boat==d[now.now]){	// S
					if(S[d[now.now]][d[now.now+1]]<INF){
						int nt=now.time+S[d[now.now]][d[now.now+1]];
						if(goal)	ans=min(ans,nt);
						else if(close[now.now+1][d[now.now+1]]>nt){
							open.add(new C2200(now.now+1, d[now.now+1], nt));
							close[now.now+1][d[now.now+1]]=nt;
						}
					}
				}
				
				for(int i=1; i<=N; i++){
					// S > L
					if(now.boat==d[now.now] && S[d[now.now]][i]<INF && L[i][d[now.now+1]]<INF && d[now.now]!=i && d[now.now+1]!=i){
						int nt=now.time+S[d[now.now]][i]+L[i][d[now.now+1]];
						if(goal)	ans=min(ans,nt);
						else if(close[now.now+1][i]>nt){
							open.add(new C2200(now.now+1, i, nt));
							close[now.now+1][i]=nt;
						}
					}
					// L > S > L
					if(L[d[now.now]][now.boat]<INF && S[now.boat][i]<INF && L[i][d[now.now+1]]<INF && d[now.now]!=i && d[now.now+1]!=i && now.boat!=i){
						int nt=now.time+L[d[now.now]][now.boat]+S[now.boat][i]+L[i][d[now.now+1]];
						if(goal)	ans=min(ans,nt);
						else if(close[now.now+1][i]>nt){
							open.add(new C2200(now.now+1, i, nt));
							close[now.now+1][i]=nt;
						}
					}
				}
				
				if(L[d[now.now]][now.boat]<INF){
					if(S[now.boat][d[now.now+1]]<INF){	// L > S
						int nt=now.time+L[d[now.now]][now.boat]+S[now.boat][d[now.now+1]];
						if(goal)	ans=min(ans,nt);
						else if(close[now.now+1][d[now.now+1]]>nt){
							open.add(new C2200(now.now+1, d[now.now+1], nt));
							close[now.now+1][d[now.now+1]]=nt;
						}
					}
				}
				if(L[d[now.now]][d[now.now+1]]<INF){	// L
					int nt=now.time+L[d[now.now]][d[now.now+1]];
					if(goal)	ans=min(ans,nt);
					else if(close[now.now+1][now.boat]>nt){
						open.add(new C2200(now.now+1, now.boat, nt));
						close[now.now+1][now.boat]=nt;
					}
				}
			}
			System.out.println(ans);
		}
	}
	class C2200 implements Comparable<C2200>{
		int now,boat,time;
		C2200(int n,int b,int t){this.now=n; this.boat=b; this.time=t;}
		@Override public int compareTo(C2200 o) {
			if(this.time<o.time)	return -1;
			if(this.time>o.time)	return 1;
			if(this.now<o.now)	return -1;
			if(this.now>o.now)	return 1;
			if(this.boat<o.boat)	return -1;
			if(this.boat>o.boat)	return 1;
			return 0;
		}
	}
	
	void AOJ2021(){
		while(true){
			int N=sc.nextInt(),M=sc.nextInt(),L=sc.nextInt(),K=sc.nextInt(),A=sc.nextInt(),H=sc.nextInt();
			if(N==0)	break;
			int[][] d=new int[N][N];
			int[] l=new int[L+1];
			for(int i=0; i<N; i++){
				for(int j=0; j<N; j++){
					if(i==j)	continue;
					d[i][j]=INF;
				}
			}
			for(int i=0; i<L; i++)	l[i]=sc.nextInt();
			l[L]=H;
			for(int i=0; i<K; i++){
				int x=sc.nextInt(),y=sc.nextInt(),t=sc.nextInt();
				d[x][y]=t;	d[y][x]=t;
			}
			for(int i=0; i<N; i++){
				for(int j=0; j<N; j++){
					for(int k=0; k<N; k++)	d[j][k]=min(d[j][k],d[j][i]+d[i][k]);
				}
			}
			PriorityQueue<C2021> open=new PriorityQueue<C2021>();
			open.add(new C2021(A,M,0));
			int[][] close=new int[N][M+1];
			for(int i=0; i<N; i++){
				for(int j=0; j<=M; j++)	close[i][j]=INF;
			}
			close[A][M]=0;
			int ans=INF;
			while(!open.isEmpty()){
				C2021 now=open.poll();
				for(int i=0; i<=L; i++){
					if(now.now==l[i])	continue;
					if(d[now.now][l[i]]>M)	continue;
					int t=now.time+d[now.now][l[i]],r=now.remain-d[now.now][l[i]];
					if(r<0){
						t+=-1*r;
						r=0;
					}
					if(close[l[i]][r]<=t)	continue;
					if(l[i]==H){
						ans=min(ans,t);
						continue;
						//break;
					}
					open.add(new C2021(l[i],r,t));
					close[l[i]][r]=t;
				}
			}
			System.out.println((ans>=INF?"Help!":ans));
		}
	}
	class C2021 implements Comparable<C2021>{
		int now,remain,time;
		C2021(int n,int r,int t){this.now=n; this.remain=r; this.time=t;}
		@Override public int compareTo(C2021 o) {
			if(this.time<o.time)	return -1;
			if(this.time>o.time)	return 1;
			return 0;
		}
	}
	
	void AOJ2151(){
		while(true){
			int N=sc.nextInt(),M=sc.nextInt(),L=sc.nextInt();
			if(N==0)	break;
			int[][] cost=new int[N+1][N+1],robber=new int[N+1][N+1];
			for(int i=0; i<=N; i++){
				for(int j=0; j<=N; j++){
					if(i==j)	continue;
					cost[i][j]=INF;	robber[i][j]=INF;
				}
			}
			for(int i=0; i<M; i++){
				int a=sc.nextInt(),b=sc.nextInt(),c=sc.nextInt(),d=sc.nextInt();
				cost[a][b]=c;	cost[b][a]=c;
				robber[a][b]=d;	robber[b][a]=d;
			}
			PriorityQueue<C2151> open=new PriorityQueue<C2151>();
			open.add(new C2151(1,L,0));
			int[][] close=new int[N+1][L+1];
			for(int i=0; i<=N; i++){
				for(int j=0; j<=L; j++)	close[i][j]=INF;
			}
			close[1][L]=0;
			int ans=INF;
			while(!open.isEmpty()){
				C2151 now=open.poll();
				for(int i=1; i<=N; i++){
					if(now.now==i)	continue;
					if(cost[now.now][i]>=INF)	continue;
					if(now.remains>=cost[now.now][i]){
						int re2=now.remains-cost[now.now][i];
						if(close[i][re2]>now.robbers){
							if(i==N){
								ans=min(ans,now.robbers);
								continue;
							}else{
								open.add(new C2151(i,re2,now.robbers));
								close[i][re2]=now.robbers;
							}
						}
					}
					int rob2=now.robbers+robber[i][now.now];
					if(close[i][now.remains]<=rob2)	continue;
					if(i==N)	ans=min(ans,rob2);
					else{
						open.add(new C2151(i,now.remains,rob2));
						close[i][now.remains]=rob2;
					}
				}
			}
			System.out.println(ans);
		}
	}
	class C2151 implements Comparable<C2151>{
		int now,remains,robbers;
		C2151(int n,int r,int r2){this.now=n; this.remains=r; this.robbers=r2;}
		@Override public int compareTo(C2151 o) {
			if(this.robbers<o.robbers)	return -1;
			if(this.robbers>o.robbers)	return 1;
			return 0;
		}
	}
	
	void AOJ1144(){
		while(true){
			int W=sc.nextInt(),H=sc.nextInt(),sx=0,sy=0;
			if((W|H)==0)	break;
			int[][] b=new int[W][H];
			for(int y=0; y<H; y++){
				for(int x=0; x<W; x++){
					b[x][y]=sc.nextInt();
					if(b[x][y]==2){
						sx=x;	sy=y;
					}
				}
			}
			PriorityQueue<C1144> open=new PriorityQueue<C1144>();
			int[] temp=new int[10];
			Arrays.fill(temp, -1);
			open.add(new C1144(sx,sy,0,temp,temp));
			TreeSet<C1144> close=new TreeSet<C1144>();
			close.add(new C1144(sx,sy,0,temp,temp));
			int ans=INF;
			while(!open.isEmpty()){
				C1144 now=open.poll();
				for(int i=0; i<4; i++){
					int xx=now.x,yy=now.y;
					if((0<=xx+vx[i] && xx+vx[i]<W && 0<=yy+vy[i] && yy+vy[i]<H) && b[xx+vx[i]][yy+vy[i]]==1 && !now.stone(xx+vx[i], yy+vy[i]))	continue;
					while(true){
						xx+=vx[i];	yy+=vy[i];
						if(!(0<=xx && xx<W && 0<=yy && yy<H))	break;
						if(b[xx][yy]==3){
							ans=min(ans,now.step+1);
							break;
						}
						if(b[xx][yy]==1 && !now.stone(xx, yy)){
							if(now.step==9)	break;
							int[] tx=now.x2.clone(),ty=now.y2.clone();
							for(int j=0; j<10; j++){
								if(tx[j]<0 && ty[j]<0){
									tx[j]=xx;	ty[j]=yy;
									break;
								}
							}
							xx-=vx[i];	yy-=vy[i];
							C1144 next=new C1144(xx,yy,now.step+1,tx,ty);
							if(close.contains(next))	break;
							open.add(next);
							close.add(next);
						}
					}
				}
			}
			System.out.println((ans>=INF?"-1":ans));
		}
	}
	class C1144 implements Comparable<C1144>{
		int x,y,step;
		int[] x2,y2;
		C1144(int x,int y,int step,int[] x2,int[] y2){this.x=x; this.y=y; this.step=step; this.x2=x2; this.y2=y2;}
		@Override public int compareTo(C1144 o) {
			if(this.step<o.step)	return -1;
			if(this.step>o.step)	return 1;
			if(Arrays.equals(this.x2, o.x2) && Arrays.equals(this.y2, o.y2))	return 0;
			return -1;
		}
		boolean stone(int x,int y){
			for(int i=0; i<10; i++){
				if(x2[i]<0 && y2[i]<0)	return false;
				if(x2[i]==x && y2[i]==y)	return true;
			}
			return false;
		}
	}
	
	void AOJ1145(){
		while(true){
			StringBuilder line=new StringBuilder(sc.next());
			int n=sc.nextInt();
			if(line.toString().equals("0"))	break;
			char last=line.charAt(0);
			for(int i=1; i<line.length(); i++){
				if(Character.isDigit(last)){
					if(Character.isUpperCase(line.charAt(i)))	line.insert(i++, '*');
					else if(line.charAt(i)=='(')	line.insert(i++, '*');
				}else if(Character.isUpperCase(last)){
					if(Character.isUpperCase(line.charAt(i)))	line.insert(i++, '+');
					else if(Character.isDigit(line.charAt(i)))	line.insert(i++, '+');
				}else if(last==')' && line.charAt(i)!=')')	line.insert(i++, '+');
				last=line.charAt(i);
			}
			line.append("#");
			//System.out.println("L: "+line);
			try{
				System.out.println(new parsed1145(line.toString(), n).toString().charAt(n));
			}catch(Exception e){
				System.out.println(0);
			}
		}
	}
	class parsed1145{
		String line,ans;
		int pos=0,n;
		public parsed1145(String line, int n) { this.line=line; this.n=n; ans=expr();}
		private String expr(){
			String res=term();
			if(res.length()>n)	return res;
			while(true){
				char op=line.charAt(pos);
				if(op=='+'){
					pos++;
					res+=term();
				}else	break;
			}
			return res;
		}
		private String term(){
			String res=fact();
			//if(res.length()>n)	return res;
			while(true){
				char op=line.charAt(pos);
				if(op=='*'){
					int t=Integer.parseInt(res);
					pos++;
					res=fact();
					if(res.length()>n)	return res;
					StringBuilder sb=new StringBuilder();
					while(--t>=0 && sb.length()<=n)	sb.append(res);
					res=sb.toString();
				}else	break;
			}
			return res;
		}
		private String fact(){
			if(Character.isDigit(line.charAt(pos))){
				String t=""+(line.charAt(pos)-'0');
				pos++;
				while(Character.isDigit(line.charAt(pos))){
					t+=(line.charAt(pos)-'0');
					pos++;
				}
				return t;
			}else if(line.charAt(pos)=='('){
				pos++;
				String res=expr();
				pos++;
				return res;
			}else if(Character.isUpperCase(line.charAt(pos))){
				return ""+line.charAt(pos++);
			}
			return "";
		}
		@Override public String toString() {	return ans;}
	}
	
	void AOJ1165(){
		final int[] vx2={-1,0,1,0}, vy2={0,-1,0,1};
		while(true){
			int N=sc.nextInt();
			if(N==0)	break;
			int[] x=new int[N],y=new int[N];
			for(int i=1; i<N; i++){
				int n=sc.nextInt(),d=sc.nextInt();
				x[i]=x[n]+vx2[d];	y[i]=y[n]+vy2[d];
			}
			Arrays.sort(x);	Arrays.sort(y);
			System.out.println((x[N-1]-x[0]+1)+" "+(y[N-1]-y[0]+1));
		}
	}
	
	static class Point{
		int x, y;
		Point(int x, int y){	this.x=x;	this.y=y;}
		Point(){	this.x=0; this.y=0;}
		@Override public String toString(){	return "("+this.x+","+this.y+")";}
		static boolean ok(int x,int y,int X,int Y,int min){	return (min<=x&&x<X)&&(min<=y&&y<Y);}
		static boolean ok(int x,int y,int X,int Y){	return ok(x,y,X,Y,0);}
	}
}