#include using namespace std; using pii=pair; using tii=tuple; using qii=tuple; using ll=long long; using ull=unsigned long long; using ld=long double; constexpr int INF=1e9; constexpr ll INF_ll=1e18; #define rep(i,n) for (int i=0;i<(int)(n);i++) #define replr(i,l,r) for (int i=(int)(l);i<(int)(r);i++) #define all(v) v.begin(),v.end() #define len(v) ((int)v.size()) template inline bool chmin(T &a,T b){ if(a>b){ a=b; return true; } return false; } template inline bool chmax(T &a,T b){ if(a inline bool chmin_ref(T &a,const T &b){ if(a>b){ a=b; return true; } return false; } template inline bool chmax_ref(T &a,const T &b){ if(a(now-start).count(); return ms; } int get_ms_all_program(){ auto now=chrono::steady_clock::now(); int ms=chrono::duration_cast(now-program_start).count(); return ms; } } mt19937 mt; uint32_t rand_int(uint32_t r){ //[0,r) assert(r!=0); return ((uint64_t)mt()*r)>>32; } int rand_int(int l,int r){ //[l,r) assert(l T get_random_element(const vector &v){ assert(!v.empty()); return v[rand_int(len(v))]; } template void add(vector &a,vector b){ for(auto i:b) a.push_back(i); } constexpr int N=60,H=1500,L=60; int D,M; string S; constexpr string UDLR="UDLR"; vector P,K; array,N*N> G; int Start,Key,Goal; int one(int i,int j){ return i*N+j; } pii two(int x){ return {x/N,x%N}; } namespace Solver{ array,N*N> grid_damage; array,N*N> dijkstra_cost; array,N*N> dijkstra_pre; array,N*N> last_vis; int vis_cnt=0; void dijkstra(int s,int start_turn,const array &vis,bool goal_ng,int g=-1){ vis_cnt++; dijkstra_cost[s][start_turn%L]=0; last_vis[s][start_turn%L]=vis_cnt; priority_queue,greater> pq; pq.push({0,s,start_turn%L}); while(!pq.empty()){ auto [d,x,tx]=pq.top(); pq.pop(); if(dijkstra_cost[x][tx]!=d) continue; if(g==-1&&!vis[x]&&S[x]=='J') break; if(g!=-1&&x==g) break; if(goal_ng&&x==Goal) break; int ty=(tx+1)%L; for(auto y:G[x]){ if(y==-1) continue; if(last_vis[y][ty]!=vis_cnt||dijkstra_cost[x][tx]+grid_damage[y][ty] get_tour(int s,int ts,int g,int tg){ vector ret; int x=g,tx=tg; while(!(x==s&&tx==ts)){ ret.push_back(x); auto [y,ty]=dijkstra_pre[x][tx]; assert(y!=-1); assert(ty!=-1); x=y; tx=ty; } reverse(all(ret)); return ret; } vector get_ans(const vector> &tours){ vector ans; for(const auto &tour:tours){ int s=tour.back(); array vis; vis.fill(false); bool have_key=false; int cost_sum=0; rep(i,len(tour)){ vis[tour[i]]=true; if(tour[i]==Key) have_key=true; cost_sum+=grid_damage[tour[i]][(i+1)%L]; } vector now_ans=tour; int ans_start=s,ans_cost=cost_sum; if(!have_key){ dijkstra(s,len(tour),vis,false,Key); const auto &key_cost=dijkstra_cost; int min_key_cost=INF,tk=-1; rep(i,L){ if(last_vis[Key][i]==vis_cnt&&chmin(min_key_cost,key_cost[Key][i])) tk=i; } assert(tk!=-1); add(now_ans,get_tour(s,len(tour)%L,Key,tk)); ans_start=Key; ans_cost+=key_cost[Key][tk]; } dijkstra(ans_start,len(now_ans),vis,false,Goal); const auto &goal_cost=dijkstra_cost; int min_goal_cost=INF,tg=-1; rep(i,L){ if(last_vis[Goal][i]==vis_cnt&&chmin(min_goal_cost,goal_cost[Goal][i])) tg=i; } assert(tg!=-1); add(now_ans,get_tour(ans_start,len(now_ans)%L,Goal,tg)); ans_cost+=goal_cost[Goal][tg]; if(ans_cost tour; array vis; vis.fill(false); bool have_key=false; vector> tours; while(true){ //cerr << s << " " << len(tours) <<" " << cost_sum << endl; dijkstra(s,len(tour)%L,vis,have_key); const auto &cost=dijkstra_cost; int x=-1,tx=-1; int min_cost=INF; rep(i,N*N){ if(vis[i]) continue; if(S[i]!='J') continue; rep(j,L){ if(last_vis[i][j]==vis_cnt&&chmin(min_cost,cost[i][j])){ x=i; tx=j; } } } if(H now_tour=get_tour(s,len(tour)%L,x,tx); for(auto e:now_tour){ vis[e]=true; tour.push_back(e); if(e==Key) have_key=true; } cost_sum+=min_cost; s=tour.back(); tours.push_back(tour); } reverse(all(tours)); auto ans=get_ans(tours); cerr << Timer::get_ms() << endl; int x=Start; for(auto p:ans){ int t=-1; rep(k,5){ if(G[x][k]==p) t=k; } assert(t!=-1); if(t==4) cout << "S\n"; else cout << "M " << UDLR[t] << '\n'; x=p; } } } int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); Timer::program_start_snap(); int n,h; cin >> n >> D >> h; rep(i,N){ string s; cin >> s; S+=s; } cin >> M; P.resize(M); K.resize(M); rep(i,M){ int y,x; cin >> y >> x >> K[i]; P[i]=one(y,x); } vector pi={-1,1,0,0,0},pj={0,0,-1,1,0}; rep(i,N){ rep(j,N){ G[one(i,j)].fill(-1); //if(S[one(i,j)]=='#'||S[one(i,j)]=='E') continue; rep(k,5){ int ti=i+pi[k],tj=j+pj[k]; if(ti<0||N<=ti||tj<0||N<=tj) continue; if(S[one(ti,tj)]=='#'||S[one(ti,tj)]=='E') continue; G[one(i,j)][k]=one(ti,tj); } } } rep(i,N*N){ if(S[i]=='S') Start=i; if(S[i]=='K') Key=i; if(S[i]=='G') Goal=i; } Solver::solve(); exit(0); }