import java.io.*;
import java.util.*;

import javax.swing.text.AbstractDocument.LeafElement;

public class Pr2Robots {
	public static void main(String[] args) throws IOException {
		new Pr2Robots().run();
	}

	BufferedReader in;
	PrintWriter out;
	StringTokenizer st;

	String nextToken() throws IOException {
		while (st == null || !st.hasMoreTokens()) {
			st = new StringTokenizer(in.readLine());
		}
		return st.nextToken();
	}

	int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}

	void run() throws IOException {
		in = new BufferedReader(new FileReader("robots.in"));
		out = new PrintWriter("robots.out");
		solve();
		out.flush();
	}

	int[][] was;
	int[] cycleLen;
	int[][] distToCycle;
	int[][] numOfCycle;
	char[][] table;
	int[][] stack;
	int[][] numInStack;
	int sz = 0;
	int cycles = 0;
	ArrayList<Long>[] onCycle;
	ArrayList<Long>[] toCycle;

	void dfs(int curi, int curj) {
		was[curi][curj] = 1;
		int nexti = curi;
		int nextj = curj;
		stack[sz][0] = curi;
		stack[sz][1] = curj;
		numInStack[curi][curj] = sz;
		sz++;
		if (table[curi][curj] == 'E' || table[curi][curj] == 'e') {
			nextj++;
		}
		if (table[curi][curj] == 'W' || table[curi][curj] == 'w') {
			nextj--;
		}
		if (table[curi][curj] == 'N' || table[curi][curj] == 'n') {
			nexti--;
		}
		if (table[curi][curj] == 'S' || table[curi][curj] == 's') {
			nexti++;
		}
		if (was[nexti][nextj] == 1) {
			addCycle(numInStack[nexti][nextj]);
			was[curi][curj] = 2;
			numOfCycle[curi][curj] = cycles - 1;
			return;
		} else if (was[nexti][nextj] == 0) {
			dfs(nexti, nextj);
		}
		if (distToCycle[curi][curj] == -1) {
			distToCycle[curi][curj] = distToCycle[nexti][nextj] + 1;
		}
		numOfCycle[curi][curj] = numOfCycle[nexti][nextj];
		sz--;
		was[curi][curj] = 2;
	}

	void addCycle(int pos) {
		cycleLen[cycles] = sz - pos;
		int mini = -1;
		int minj = -1;
		int minp = -1;
		for (int i = pos; i < sz; i++) {
			// if (Character.isUpperCase(table[stack[i][0]][stack[i][1]])) {
			onCycle[cycles].add(stack[i][0] * 10000L + stack[i][1]);
			// distToCycle[stack[i][0]][stack[i][1]] = 0;
			if (mini == -1 || stack[i][0] + stack[i][1] < mini + minj) {
				mini = stack[i][0];
				minj = stack[i][1];
				minp = i;
			}
			// }
		}
		distToCycle[mini][minj] = 0;
		int last = 1;
		for (int i = minp - 1; i >= pos; i--) {
			distToCycle[stack[i][0]][stack[i][1]] = last;
			last++;
		}
		for (int i = sz - 1; i > minp; i--) {
			distToCycle[stack[i][0]][stack[i][1]] = last;
			last++;
		}
		cycles++;
	}

	void solve() throws IOException {
		int n = nextInt();
		int m = nextInt();
		int g = nextInt();
		table = new char[n][m];
		for (int i = 0; i < n; i++) {
			String s = nextToken();
			for (int j = 0; j < m; j++) {
				table[i][j] = s.charAt(j);
			}
		}
		was = new int[n][m];
		cycleLen = new int[n * m];
		distToCycle = new int[n][m];
		numOfCycle = new int[n][m];
		stack = new int[n * m][2];
		numInStack = new int[n][m];
		for (int i = 0; i < n; i++) {
			Arrays.fill(numOfCycle[i], -1);
			Arrays.fill(distToCycle[i], -1);
		}
		onCycle = new ArrayList[n * m];
		toCycle = new ArrayList[n * m];
		for (int i = 0; i < n * m; i++) {
			onCycle[i] = new ArrayList<>();
			toCycle[i] = new ArrayList<>();
		}
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				if (Character.isUpperCase(table[i][j])) {
					if (was[i][j] == 0) {
						dfs(i, j);
					}
					toCycle[numOfCycle[i][j]].add(i * 10000L + j);
				}
			}
		}
		int ans = 0;
		for (int i = 0; i < cycles; i++) {
			ans += Math.min(cycleLen[i], toCycle[i].size());
		}
		out.println(ans);
		if (g == 0) {
			return;
		}
		boolean[][] killed = new boolean[n][m];
		boolean[][] was = new boolean[n][m];
		ArrayList<String> sans = new ArrayList<>();
		for (int i = 0; i < cycles; i++) {
			int lasti = 0;
			int lastj = 0;
			int temp = 0;
			for (long t : onCycle[i]) {
				int ci = (int) (t / 10000);
				int cj = (int) (t % 10000);
				if (Character.isUpperCase(table[ci][cj])) {
					killed[ci][cj] = true;
					sans.add((ci + 1) + " " + (cj + 1) + " 1");
					temp++;
				}
				lasti = ci;
				lastj = cj;
			}
			if (temp == Math.min(cycleLen[i], toCycle[i].size())) {
				continue;
			}
			// System.err.println(lasti + " " + lastj);
			int time = 1;
			int curR = 0;
			while (!was[lasti][lastj]) {
				// System.err.println(lasti + " " + lastj + " !" + " " + curR);
				was[lasti][lastj] = true;
				if (Character.isUpperCase(table[lasti][lastj])) {
					if (table[lasti][lastj] == 'E' || table[lasti][lastj] == 'e') {
						lastj++;
					} else if (table[lasti][lastj] == 'W' || table[lasti][lastj] == 'w') {
						lastj--;
					} else if (table[lasti][lastj] == 'N' || table[lasti][lastj] == 'n') {
						lasti--;
					} else if (table[lasti][lastj] == 'S' || table[lasti][lastj] == 's') {
						lasti++;
					}
					continue;
				}
				while (curR < toCycle[i].size()
						&& killed[(int) (toCycle[i].get(curR) / 10000)][(int) (toCycle[i].get(curR) % 10000)]) {
					curR++;
				}
				if (curR == toCycle[i].size())
					break;
				int ri = (int) (toCycle[i].get(curR) / 10000);
				int rj = (int) (toCycle[i].get(curR) % 10000);
				// System.err.println(killed[ri][rj]);
				if ((distToCycle[ri][rj] + time - distToCycle[lasti][lastj]) % cycleLen[i] == 0) {
					sans.add((ri + 1) + " " + (rj + 1) + " " + time);
					killed[ri][rj] = true;
				} else {
					time += cycleLen[i] - (distToCycle[ri][rj] + time - distToCycle[lasti][lastj]) % cycleLen[i];
					sans.add((ri + 1) + " " + (rj + 1) + " " + time);
					killed[ri][rj] = true;
				}
				if (table[lasti][lastj] == 'E' || table[lasti][lastj] == 'e') {
					lastj++;
				} else if (table[lasti][lastj] == 'W' || table[lasti][lastj] == 'w') {
					lastj--;
				} else if (table[lasti][lastj] == 'N' || table[lasti][lastj] == 'n') {
					lasti--;
				} else if (table[lasti][lastj] == 'S' || table[lasti][lastj] == 's') {
					lasti++;
				}
			}
		}
		for (String s : sans) {
			out.println(s);
		}
	}
}
