// Solution to Path

import java.util.*;

public class bpath {
  public static Scanner in;
  public static int casenum;
  public static int n, m;
  public static String grid[][]; // the input
  public static int[][] fromStart, toEnd; // distances from start and end
  public static boolean[][] marked; // vertices reachable from start
  public static int[] rowmin,colmin; // min distance in row(col) to End
  public static ArrayList[] rowloc, colloc;

  public static void main(String[] args) {
    in = new Scanner(System.in);
    casenum = 0;
    while(true) {
      n = in.nextInt();
      m = in.nextInt();
      if (n ==0 && m == 0) break;
      casenum++;
      System.out.print("Case " + casenum + ": ");
      grid = new String[n][m];
      for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
          if (i == n-1 && j == m-1) break;
          grid[i][j] = in.next();
        }
      }
      grid[n-1][m-1] = "End";


      // Distances "from start" and "to end":
      fromStart = new int[n][m];
      toEnd = new int[n][m];

      // Shortest distance to "End" in each row and col:
      rowmin = new int[n];
      colmin = new int[m];

      // Location of shortest distance to "End" in each row and col:
      rowloc = new ArrayList[n];
      colloc = new ArrayList[m];

      for (int i = 0; i < n; i++) {
        Arrays.fill(fromStart[i],n*m); // longest possible path is nm-1
        Arrays.fill(toEnd[i],n*m);
        rowloc[i] = new ArrayList<Integer>();
      }
      Arrays.fill(rowmin,n*m);
      Arrays.fill(colmin,n*m);
      for (int i = 0; i < m; i++) {
        colloc[i] = new ArrayList<Integer>();
      }
      rowmin[n-1] = 0; // min distance to "End" is 0
      rowloc[n-1].add(m-1);
      colmin[m-1] = 0; // min distance to "End" is 0
      colloc[m-1].add(n-1);

      fromStart[0][0] = 0;
      toEnd[n-1][m-1] = 0;
      int[] delta;
      
      marked = new boolean[n][m];
      for (int i = 0; i < n; i++)
        Arrays.fill(marked[i],false);

      int count = 0; // count forward steps from (0,0)
      for (int r = 0; r < n; r++) {
        for (int c = 0; c < m; c++) {
         // Follow the path from row r, col c, unless... 
          if (r==n-1 && c==m-1) { // it's the "End" cell...
            break;
          }
          if (marked[r][c]) continue; // ... or a previous path hit it

          // Advance forward from this cell:

          marked[r][c] = true; // so if we return here we'll know it

          // Use a stack to hold visited grid cells so we can 
          // reverse-traverse from "End" (or from an already-visited cell)
          // to compute "toEnd" value for (r,c)

          Stack<int[]> st = new Stack<int[]>();
          st.push(new int[]{r,c}); 

          // ONLY for searches that originated at "Start", update
          // "fromStart" using value of count:
          if (r==0 && c==0)
            fromStart[r][c] = count;

          int r1=r,c1=c; // cell currently being visited
          delta = decode(grid[r][c]); // contents of current cell
          while(true) {
            // at top of loop: (r,c) = starting point of search; (r1,c1) =
            // current point in search; count = # steps from (r,c) to
            // (r1,c1); delta = contents of (r1,c1); stack top = (r1,c1);
            // (r1,c1) (and previous cells along path and on stack) are
            // "marked" as having been visited
            count++; // count next step
            r1 += delta[0]; // compute next cell
            c1 += delta[1];

            if (r1 < 0 || r1 >= n || c1 < 0 || c1 >= m) { // invalid grid entry!
              break; // can't reach "End" from (r,c)
            }

            if (r==0 && c==0 && !marked[r1][c1]) // on a path from start
              fromStart[r1][c1] = count;

            if ((r1==n-1 && c1==m-1) || marked[r1][c1]) {
             // Either we reached "End" or we reached an already-visited
             // cell; empty the stack and fill in dist to end:
              int j = toEnd[r1][c1];
              while(!st.empty()) {
                j++;
                int[] rc = st.pop();
                toEnd[rc[0]][rc[1]] = j;
                if (j < rowmin[rc[0]]) { // nearest to "End" in this row?
                  rowmin[rc[0]] = j;
                  rowloc[rc[0]] = new ArrayList<Integer>();
                  rowloc[rc[0]].add(rc[1]);
                }
                else if (j == rowmin[rc[0]]) {
                  if (rowloc[rc[0]].size() > 0) {
                    rowloc[rc[0]].add(rc[1]);
                  }
                }
                if (j < colmin[rc[1]]) { // nearest to "End" in this col?
                  colmin[rc[1]] = j;
                  colloc[rc[1]] = new ArrayList<Integer>();
                  colloc[rc[1]].add(rc[0]);
                }
                else if (j == colmin[rc[1]]) {
try {
                  if (rc[0] < m && colloc[rc[0]].size() > 0) {
                    colloc[rc[1]].add(rc[0]);
                  }
} catch (Exception e) {System.out.println("index = " + rc[0] + ", m = " + m);}
                }
              }

              break; // we're done with path from (r,c)
            }
            // Still extending the path from (r,c)...
            marked[r1][c1] = true; // so we can't enter infinite loop

            st.push(new int[]{r1,c1});
            delta = decode(grid[r1][c1]);
          }
        }
      }

      // Now solve it: 
      int minval = toEnd[0][0];
      int minr=-1,minc=-1;
      String mind = "";

      // For each entry, see if it can be changed to shorten the path:
      for(int r = 0; r < n; r++) {
        for (int c = 0; c < m; c++) {
          if (r==n-1 && c==m-1) break; // End
          if (fromStart[r][c] >= m*n) continue; // can't reach this cell from start

          String min1 = lexifirstcol(rowloc[r],r,c);
          String min2 = lexifirstrow(colloc[c],r,c);
          String min3 = "";
          if (min1.equals("9999Z") && min2.equals("9999Z")) continue;

          if (min1.equals("9999Z")) min3 = min2;
          else if (min2.equals("9999Z")) min3 = min1;
          else if (compare(min1,min2) < 0) min3 = min1;
          else min3 = min2;

          int temp = fromStart[r][c]+1+rowmin[r];
          if (temp < minval) {
            minval = temp;
            minr = r; minc = c;
            mind = min1;
          }
          temp = fromStart[r][c]+1+colmin[c];
          if (temp < minval) {
            minval = temp;
            minr = r; minc = c;
            mind = min2;
          }
        }
      }
      
      if (minval >= n*m)
        System.out.println("impossible");
      else if (mind.equals(""))
        System.out.println("none "+minval);
      else
        System.out.println(minr+" "+minc+" "+mind+" "+minval);
              
    }
  }

  public static int[] decode(String dir) {
    int[] result = new int[2];
    if (dir.equals("End")) 
      result[0] = result[1] = 0;
    else {
      char c = dir.charAt(dir.length()-1);
      int d = Integer.parseInt(dir.substring(0,dir.length()-1));
      switch(c) {
        case 'E': result[0] = 0; result[1] = d; break; // right
        case 'W': result[0] = 0; result[1] = -d; break; // left
        case 'N': result[0] = -d; result[1] = 0; break; // up
        case 'S': result[0] = d; result[1] = 0; break; // down
      }
    }
    return result;
  }

  public static void show() {
      for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++)
          System.out.printf("%4s",grid[i][j]);
        System.out.println();
      }
      System.out.println("\nFromStart:");
      for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++)
          System.out.printf("%4d",fromStart[i][j]);
        System.out.println();
      }
      System.out.println("\nToEnd:");
      for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++)
          System.out.printf("%4d",toEnd[i][j]);
        System.out.printf("| rowmin=%d,loc=",rowmin[i]);
        for (int j:(ArrayList<Integer>)(rowloc[i])) {
          System.out.printf("%d ",j);
        }
        System.out.println();

      }
      System.out.println("------colmin------");
      for (int j=0;j<m;j++)
        System.out.printf("%4d",colmin[j]);
      System.out.println();
      for (int j = 0; j < m; j++) {
        System.out.printf("rowloc %d: ",j);
        for (int k:(ArrayList<Integer>)(colloc[j])) {
          System.out.printf("%d ",k);
        }
        System.out.println();
      }
  }

  // compare two instructions lexicographically--first by distance,
  // then by compass direction
  public static int compare(String s1, String s2) {
    int dist1 = Integer.parseInt(s1.substring(0,s1.length()-1));
    int dist2 = Integer.parseInt(s2.substring(0,s2.length()-1));
    if (dist1 < dist2) return -1;
    else if (dist1 > dist2) return 1;
    else {
      char c1 = s1.charAt(s1.length()-1);
      char c2 = s2.charAt(s2.length()-1);
      return c1 - c2;
    } 
  }

  public static String lexifirstcol(ArrayList<Integer> rowloc, int r, int c) {
    if (rowloc.isEmpty()) return "9999Z";
    if (rowloc.get(0) == -1) return "9999Z";
    int bestdist = 9999;
    char bestdir = 'Z';
    for (int j:rowloc) {
      if (j==c) continue; // same column we're in
      int d = Math.abs(j-c);
      if (d < bestdist) {
        bestdist = d;      
        if (j < c) bestdir = 'W';
        else bestdir = 'E';
      }
      else if (d==bestdist && j > c) bestdir = 'E';
    }
    
    return ""+bestdist+bestdir;
  }
  public static String lexifirstrow(ArrayList<Integer> colloc,int r, int c) {
    if (colloc.isEmpty()) return "9999Z";
    if (colloc.get(0) == -1) return "9999Z";
    int bestdist = 9999;
    char bestdir = 'Z';
    for (int j:colloc) {
      if (j==r) continue; // same row we're in
      int d = Math.abs(j-r);
      if (d < bestdist) {
        bestdist = d;      
        if (j < r) bestdir = 'N';
        else bestdir = 'S';
      }
      else if (d==bestdist && j < r) bestdir = 'N';
    }
    
    return ""+bestdist+bestdir;
  }
}
