// Tom Wexler import java.util.*; import java.io.*; class node { ArrayList outE; ArrayList inE; int tDist; int sDist; public node() { outE = new ArrayList(); inE = new ArrayList(); tDist = Integer.MAX_VALUE; sDist = Integer.MAX_VALUE; } public void addE(node b) { outE.add(b); b.inE.add(this); } } public class F { public static void main(String[] args) { long time = System.currentTimeMillis(); Scanner input = new Scanner(System.in); int n = input.nextInt(); // rows int m = input.nextInt(); // cols int caseNo = 1; while (n > 0) { node[] nodes = new node[n*m]; // node[i] is at x = i%m, y = i/m for (int i = 0; i < n*m; i++) { nodes[i] = new node(); } for (int i = 0; i < n*m-1; i++) { String dir = input.next(); int off = Integer.parseInt(dir.substring(0,dir.length()-1)); if (dir.charAt(dir.length()-1) == 'N') { int next = i-m*off; if (next >= 0 && off < n) nodes[i].addE(nodes[next]); } if (dir.charAt(dir.length()-1) == 'S') { int next = i + m*off; if (next < n*m && off < n) nodes[i].addE(nodes[next]); } if (dir.charAt(dir.length()-1) == 'W') { int next = i-off; if (next >= 0 && next%m < i%m && off < m) nodes[i].addE(nodes[next]); } if (dir.charAt(dir.length()-1) == 'E'){ int next = i+off; if (next%m > i%m && off < m) nodes[i].addE(nodes[next]); } } // Compute s distance nodes[0].sDist = 0; node curr = nodes[0]; boolean stuck = false; while (curr.outE.size() > 0 && !stuck) { node next = curr.outE.get(0); if (next.sDist > 1 + curr.sDist) { next.sDist = 1 + curr.sDist; curr = next; } else stuck = true; } // Compute t distance nodes[n*m-1].tDist = 0; LinkedList queue = new LinkedList(); queue.add(nodes[n*m-1]); while(!queue.isEmpty()) { node v = queue.poll(); for(node x : v.inE) { if (x.tDist > 1 + v.tDist) { x.tDist = 1 + v.tDist; queue.add(x); } } } // Print /* System.out.println("Distance from s"); for (int i = 0; i < n*m; i++) { if (nodes[i].sDist == Integer.MAX_VALUE) System.out.print("X "); else System.out.print(nodes[i].sDist + " "); if (i%m==m-1) System.out.println(); } System.out.println("Distance to t"); for (int i = 0; i < n*m; i++) { if (nodes[i].tDist == Integer.MAX_VALUE) System.out.print("X "); else System.out.print(nodes[i].tDist + " "); if (i%m==m-1) System.out.println(); }*/ int bestDist = nodes[0].tDist; int bestX = -1; int bestY = -1; // check for horizontal moves for (int y = 0; y < n; y++) { //System.out.println("Checking y = "+y); int bestS = nodes[y*m].sDist; int bestT = nodes[y*m].tDist; int bestRowX = 0; for (int x = 1; x < m; x++) { if (nodes[y*m+x].sDist < bestS) { bestS = nodes[y*m+x].sDist; bestRowX = x; //System.out.println("Found better s distance ("+bestS+") at x = "+x); } if (nodes[y*m+x].tDist < bestT) { bestT = nodes[y*m+x].tDist; } } if (bestS < Integer.MAX_VALUE && bestT < Integer.MAX_VALUE) { if (bestS+bestT+1 < bestDist) { bestDist = bestS+bestT+1; bestX = bestRowX; bestY = y; } } } // check for vertical moves for (int x = 0; x < m; x++) { int bestS = nodes[x].sDist; int bestT = nodes[x].tDist; int bestColY = 0; for (int y = 1; y < n; y++) { if (nodes[y*m+x].sDist < bestS) { bestS = nodes[y*m+x].sDist; bestColY = y; } if (nodes[y*m+x].tDist < bestT) { bestT = nodes[y*m+x].tDist; } } if (bestS < Integer.MAX_VALUE && bestT < Integer.MAX_VALUE) { if (bestS+bestT+1 < bestDist || (bestS+bestT+1== bestDist && ((bestColY < bestY)||(bestColY == bestY && x < bestX)))) { bestDist = bestS+bestT+1; bestX = x; bestY = bestColY; } } } if (bestDist == Integer.MAX_VALUE) { System.out.println("Case "+caseNo+": impossible"); } else if (bestDist == nodes[0].tDist) { System.out.println("Case "+caseNo+": none "+nodes[0].tDist); } else { // find best lexicographically int target = bestDist - 1 - nodes[bestX+m*bestY].sDist; String move = ""; for (int d = 1; d < Math.max(m,n); d++) { // EAST if (d + bestX < m) { if (nodes[bestY*m + bestX + d].tDist == target) { move = d+"E"; break; } } // NORTH if (d <= bestY) { if (nodes[(bestY-d)*m + bestX].tDist == target) { move = d+"N"; break; } } // SOUTH if (d + bestY < n) { if (nodes[(bestY+d)*m + bestX].tDist == target) { move = d+"S"; break; } } // WEST if (d <= bestX) { if (nodes[bestY*m + bestX - d].tDist == target) { move = d+"W"; break; } } } System.out.println("Case "+caseNo+": "+bestY +" "+ bestX +" "+ move+" "+bestDist); } caseNo++; n = input.nextInt(); m = input.nextInt(); } } }