1 #include <cstdio>
2 #include <cstdlib>
3 #include <cstring>
4 #include <algorithm>
5 #include <iostream>
6 #include <queue>
7 #include <set>
8 #include <stack>
9 #include <bitset>
10
11 using namespace std;
12
13 #define print(x) cout<<x<<endl
14 #define input(x) cin>>x
15 #define SIZE 12
16 #define elif else if
17 #define INF 1<<30
18 #define MOD 100000007
19
20 struct point
21 {
22 int x,y;
23 point(){x=y=-1;}
24 point(int i_x,int i_y)
25 {
26 x=i_x;y=i_y;
27 }
28 friend bool operator == (const point& a,const point& b)
29 {
30 return a.x==b.x && a.y==b.y;
31 }
32
33 friend bool operator != (const point& a,const point& b)
34 {
35 return !(a.x==b.x && a.y==b.y);
36 }
37 };
38
39 char g[SIZE][SIZE];
40 point piece[SIZE];
41 int m,n,ind;
42 const int mx[]={0,1,0,-1};
43 const int my[]={-1,0,1,0};
44 bitset<MOD> hash;
45 //TLE:
46 //Hash is faster than Set
47
48
49 int makeStatus(const point& pawn,const point& mir,const point& knight,int knightDir,int getMem)
50 {
51 int res=0;
52 res|=getMem;
53 res<<=4;res|=knight.x;
54 res<<=4;res|=knight.y;
55 res<<=2;res|=knightDir;
56 res<<=4;res|=mir.x;
57 res<<=4;res|=mir.y;
58 res<<=4;res|=pawn.x;
59 res<<=4;res|=pawn.y;
60 return res;
61 }
62
63 bool inMap(const point& p)
64 {
65 if(p.x>=0 && p.x<m && p.y>=0 && p.y<n)
66 {
67 if(g[p.y][p.x]=='R') return false;
68 else return true;
69 }
70 return false;
71 }
72
73 struct node
74 {
75 unsigned int status;
76 int step;
77
78 node(){}
79 node(int i_status,int i_step)
80 {
81 status=i_status;
82 step=i_step;
83 }
84 int OK()//Drei Status caused WA
85 {
86 int st=status;
87 int res=status>>26;
88 int a,b;
89 a=b=(1<<4)-1;
90 b&=st;st>>=4;
91 a&=st;st>>=4;
92 point pawn=point(a,b);
93 a=b=(1<<4)-1;
94 b&=st;st>>=4;
95 a&=st;st>>=4;
96 point mirPawn=point(a,b);
97 int ok=(1<<ind)-1;
98 if(ind==0) ok=0;
99 if(g[pawn.y][pawn.x]=='E' && g[mirPawn.y][mirPawn.x]=='E')
100 {
101 if(res==ok) return true;
102 else return -1;
103 }
104 else return false;
105 }
106 bool move(int dir)
107 {
108 step++;
109 int a,b;
110 a=b=(1<<4)-1;
111 b&=status;status>>=4;
112 a&=status;status>>=4;
113 point pawn=point(a,b);
114
115 a=b=(1<<4)-1;
116 b&=status;status>>=4;
117 a&=status;status>>=4;
118 point mirPawn=point(a,b);
119
120 a=(1<<2)-1;
121 a&=status;
122 int knightDir=a;
123 status>>=2;
124
125 a=b=(1<<4)-1;
126 b&=status;status>>=4;
127 a&=status;status>>=4;
128 point knight=point(a,b);
129
130 int gain=status;
131
132 point nextPawn=pawn;
133 nextPawn.x+=mx[dir];
134 nextPawn.y+=my[dir];
135 if(inMap(nextPawn))
136 {
137 if(nextPawn==knight || nextPawn==mirPawn) return false;
138 pawn=nextPawn;
139 }
140 else return false;
141
142 point nextMirPawn=mirPawn;
143 nextMirPawn.x+=mx[(dir+2)%4];
144 nextMirPawn.y+=my[(dir+2)%4];
145 if(inMap(nextMirPawn) && nextMirPawn!=knight && nextMirPawn!=pawn)
146 {
147 mirPawn=nextMirPawn;
148 }
149 point nextKnight=knight;
150 nextKnight.x+=mx[knightDir];
151 nextKnight.y+=my[knightDir];
152 if(inMap(nextKnight)) knight=nextKnight;
153 else knightDir=(knightDir+2)%4;
154
155 if(g[pawn.y][pawn.x]=='E' && g[mirPawn.y][mirPawn.x]=='E')
156 {
157 status=makeStatus(pawn,mirPawn,knight,knightDir,gain);
158 }
159 else
160 {
161 if(knight==pawn || knight==mirPawn) return false;
162 for(int i=0;i<ind;i++)
163 {
164 if(pawn==piece[i]) gain|=(1<<i);//Only Alice can attach to the Memory Piece WA
165 }
166 status=makeStatus(pawn,mirPawn,knight,knightDir,gain);
167 }
168 return true;
169 }
170
171 void printinfo()
172 {
173 char tg[SIZE][SIZE];
174 memcpy(tg,g,sizeof(g));
175 print("INFO:"<<step);
176 int st=status;
177 int a,b;
178 a=b=(1<<4)-1;
179 b&=status;status>>=4;
180 a&=status;status>>=4;
181 point pawn=point(a,b);
182 tg[b][a]='A';
183
184 a=b=(1<<4)-1;
185 b&=status;status>>=4;
186 a&=status;status>>=4;
187 point mirPawn=point(a,b);
188 tg[b][a]='B';
189
190 a=(1<<2)-1;
191 a&=status;
192 int knightDir=a;
193 status>>=2;
194 printf("KnightDir:%d\n",knightDir);
195
196 a=b=(1<<4)-1;
197 b&=status;status>>=4;
198 a&=status;status>>=4;
199 point knight=point(a,b);
200 tg[b][a]='K';
201 int gain=status;
202 printf("Gain:%d\n",gain);
203 status=st;
204 for(int i=0;i<ind;i++)
205 {
206
207 if(!(gain & (1<<i)))
208 {
209 tg[piece[i].y][piece[i].x]='M';
210 }
211 }
212 for(int i=0;i<n;i++) print(tg[i]);
213 print("-------------------");
214 }
215 };
216
217
218 inline int char2Dir(char x)
219 {
220 switch(x)
221 {
222 case 'N':return 0;break;
223 case 'E':return 1;break;
224 case 'S':return 2;break;
225 case 'W':return 3;break;
226 }
227 return -1;
228 }
229
230
231 int bfs(int i_status)
232 {
233 queue<node> q;
234 int ans=INF;
235 hash.reset();
236 q.push(node(i_status,0));
237 while(!q.empty())
238 {
239 node now=q.front();
240 q.pop();
241 //now.printinfo();
242 if(hash[now.status%MOD]) continue;
243 else hash[now.status%MOD]=1;
244 int ok=now.OK();
245 if(ok==1)
246 {
247 ans=min(ans,now.step);
248 break;
249 }
250 elif(ok==-1) continue;
251 for(int i=0;i<4;i++)
252 {
253 node next=now;
254 if(next.move(i)) q.push(next);
255 }
256 }
257 return ans;
258 }
259
260 int main()
261 {
262 //freopen("input.txt","r",stdin);
263 char cmd[4];
264 while(input(n>>m))
265 {
266 for(int i=0;i<n;i++) scanf("%s",g[i]);
267
268 scanf("%s",cmd);
269 ind=0;
270 point pawn,mirPawn;
271 point knight;
272 for(int i=0;i<n;i++)
273 {
274 for(int j=0;j<m;j++)
275 {
276 if(g[i][j]=='A') pawn=point(j,i);
277 elif(g[i][j]=='B') mirPawn=point(j,i);
278 elif(g[i][j]=='K') knight=point(j,i);
279 elif(g[i][j]=='M') piece[ind++]=point(j,i);
280
281 if(g[i][j]!='E' && g[i][j]!='*' && g[i][j]!='R')
282 {
283 g[i][j]='*';
284 }
285 }
286 }
287 int status=makeStatus(pawn,mirPawn,knight,char2Dir(*cmd),0);
288 int ans=bfs(status);
289 if(ans>=INF) ans=-1;
290 print(ans);
291 }
292 return 0;
293 }