// Arup Guha
// 5/2/2012
// Solution to 2011 South East Regional Problem E: Robot Navigation


import java.util.*;

public class e {

	final static char[] dir = {'N', 'E', 'S', 'W'};

	public static void main(String[] args) {

		Scanner stdin = new Scanner(System.in);

		int nR = stdin.nextInt();
		int nC = stdin.nextInt();

		while (nR != 0 && nC != 0) {

			char[][] grid = new char[nR][nC];

			// Read in the grid.
			for (int i=0; i<nR; i++) {
				String row = stdin.next();
				for (int j=0; j<nC; j++)
					grid[i][j] = row.charAt(j);
			}

			// First find if we can get there.
			if (reachable(grid))
				solve(grid);
			else
				System.out.println("0 0");
				
			nR = stdin.nextInt();
			nC = stdin.nextInt();
		}
	}

	// Just run a BFS...
	public static boolean reachable(char[][] grid) {
		
		int startX=0, startY=0, endX=0, endY=0;
		int nR = grid.length;
		int nC = grid[0].length;
		
		// Just find where we start and end...
		for (int i=0; i<nR; i++) {
			for (int j=0; j<nC; j++) {
				if (grid[i][j] == 'N' || grid[i][j] == 'S' || grid[i][j] == 'E' || grid[i][j] == 'W') {
					startX = i;
					startY = j;
				}
				else if (grid[i][j] == 'X') {
					endX = i;
					endY = j;
				}
			}
		}
		
		// Set up our BFS.
		boolean[][] found = new boolean[nR][nC];
		for (int i=0; i<nR; i++)
			for (int j=0; j<nC; j++)
				found[i][j] = false;
				
		LinkedList<Integer> q = new LinkedList<Integer>();
		q.add(100*startX+startY);
		found[startX][startY] = true;
		
		// Run the BFS. Search all four directions...
		while (q.size() > 0) {
			int t = q.remove();
			int x = t/100;
			int y = t%100;
			
			if (x-1 >= 0 && !found[x-1][y] && grid[x-1][y] != '*') {
				q.add(100*(x-1)+y);
				found[x-1][y] = true;
			}
			
			if (x+1 < nR && !found[x+1][y] && grid[x+1][y] != '*') {
				q.add(100*(x+1)+y);
				found[x+1][y] = true;
			}
			
			if (y-1 >= 0 && !found[x][y-1] && grid[x][y-1] != '*') {
				q.add(100*x+y-1);
				found[x][y-1] = true;
			}

			if (y+1 < nC && !found[x][y+1] && grid[x][y+1] != '*') {
				q.add(100*x+y+1);				
				found[x][y+1] = true;
			}
		}
		
		// Did we get there?
		return found[endX][endY];	
	}
	
	public static int lookUp(char c) {

		for (int i=0; i<3; i++)
			if (c == dir[i])
				return i;

		// Illegal directions are West...
		return 3;
	}

	// Solve the problem, knowing that we can using a DP.
	// DP[i][j][k] stands for the minimum number of moves to 
	// get to position (i,j) in direction k.
	public static void solve(char[][] grid) {

		int nR = grid.length, nC = grid[0].length;

		// -1 means we haven't solved this subproblem yet.
		int[][][] dp = new int[nR][nC][4];
		for (int i=0; i<nR; i++)
			for (int j=0; j<nC; j++)
				for (int k=0; k<4; k++)
					dp[i][j][k] = 0;

		// Initialize the start spot to 0, and store
		// both the starting and ending locations.
		int startX, startY, endX=0, endY=0;
		for (int i=0; i<nR; i++) {
			for (int j=0; j<nC; j++) {
				for (int k=0; k<4; k++) {
					if (grid[i][j] == dir[k]) {
						dp[i][j][k] = 1;
						startX = i;
						startY = j;
					}
					else if (grid[i][j] == 'X') {
						endX = i;
						endY = j;
					}
				}

			}
		}

		// We run our DP one step at a time, storing new places we can reach.
		// This is actually similar to a BFS.
		int nummoves = 0;
		while (notdone(dp, endX, endY)) {
			dp = onestep(dp, grid);
			nummoves++;
		}
		
		// Add up all ways to get to this spot.
		int sum = 0;
		for (int i=0; i<4; i++) {
			sum = (sum + dp[endX][endY][i])%1000000;
		}

		// Print result.
		System.out.println(nummoves+" "+sum);
	}

	// We can stop when at least one path reaches our end location (in any direction).
	public static boolean notdone(int[][][] dp, int endX, int endY) {

		for (int i=0; i<4; i++)
			if (dp[endX][endY][i] != 0)
				return false;
		return true;
	}

	// Runs one step.
	public static int[][][] onestep(int[][][] dp, char[][] grid) {

		int nR = grid.length;
		int nC = grid[0].length;

		int[][][] next = new int[nR][nC][4];
		for (int i=0; i<nR; i++)
			for (int j=0; j<nC; j++)
				for (int k=0; k<4; k++)
					next[i][j][k] = 0;

		for (int i=0; i<nR; i++) {
			for (int j=0; j<nC; j++) {

				// Add in contribution of programs from left and right.
				for (int k=0; k<4; k++)	{
					next[i][j][k] += (dp[i][j][(k+1)%4] + dp[i][j][(k+3)%4]);
				}

				// Go as far as you can up.
				int tryx = i-1;
				while (tryx >= 0 && grid[tryx][j] != '*') {
					next[i][j][2] += dp[tryx][j][2];
					tryx--;
				}

				// Down.
				tryx = i+1;
				while (tryx < nR && grid[tryx][j] != '*') {
					next[i][j][0] += dp[tryx][j][0];
					tryx++;
				}

				// Left.
				int tryy = j-1;
				while (tryy >= 0 && grid[i][tryy] != '*') {
					next[i][j][1] += dp[i][tryy][1];
					tryy--;
				}

				// Right.
				tryy = j+1;
				while (tryy < nC && grid[i][tryy] != '*') {
					next[i][j][3] += dp[i][tryy][3];
					tryy++;
				}
			}
		}

		// Reduce our values before returning.
		for (int i=0; i<nR; i++) {
			for (int j=0; j<nC; j++) {
				for (int k=0; k<4; k++) {
					if (next[i][j][k] > 1000000)
						next[i][j][k] = next[i][j][k] % 1000000;
				}
			}
		}

		return next;
	}
}