import java.io.BufferedReader;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;

public class Solution {
	public static final boolean std = false;
	public static final String ioFile = "robots";
	
	public final RFScanner in;
	public final PrintWriter out;
	
	public Solution() throws Exception {
		if (std) {
			in = new RFScanner(System.in);
			out = new PrintWriter(System.out);
		} else {
			in = new RFScanner(new FileInputStream(ioFile+".in"));
			out = new PrintWriter(new File(ioFile+".out"));
		}
		run();
		in.close();
		out.close();
	}

	public static void main(String[] args) throws Exception {
		new Solution();
	}


	int n, m, g;
	Field[][] fls;
	Field[] fsall;
	void run() throws Exception {
		n = in.nextInt();
		m = in.nextInt();
		g = in.nextInt();
		fls = new Field[n][m];
		fsall = new Field[n*m];
		for (int i=0; i<n; i++) {
			char[] s = in.nextLine().toCharArray();
			for (int j=0; j<m; j++) {
				fsall[i*m+j] = fls[i][j] = new Field(i, j, s[j]);
			}
		}
		for (Field f : fsall) {
//			out.printf("%d %d %s%n", f.x, f.y, f.direction);
//			out.flush();
			if (f.direction == 's') {
				f.direct = fls[f.x+1][f.y];
			}
			if (f.direction == 'n') {
				f.direct = fls[f.x-1][f.y];
			}
			if (f.direction == 'w') {
				f.direct = fls[f.x][f.y-1];
			}
			if (f.direction == 'e') {
				f.direct = fls[f.x][f.y+1];
			}
		}
		
		for (Field f : fsall) {
			if (f.hasStartRobot) {
				f.dfs();
				Field cy = f.cycans.get(0);
				if (cy.robots == null) {
					cy.robots = new ArrayList<>();
				}
				cy.robots.add(f);
			}
		}
		
		int ans = Arrays.stream(fsall).mapToInt((f) -> {
			if (f.cycans == null || f.robots == null) return 0;
			return Math.min(f.robots.size(), f.cycans.size());
		}).sum();
		out.println(ans);
		
		if (g == 1) {
			for (Field f : fsall) {
				if (f.cycans == null || f.robots == null) continue;
				int l = f.cycans.size();
				int free = 0;
				
				for (Field rob : f.robots) {
					int time = rob.cycdist + rob.enterPoint.enterOffset;
					time %= l;
					int oktime = free;
					while (oktime < time) oktime += l;
					rob.startTime = oktime - time;
					free++;
					if (free == l) break;
				}
			}
		}
		
		if (n*m < 20_000)
			for (Field f : fsall) {
				if (f.hasStartRobot && f.startTime >= 0) {
					out.printf("%d %d %d\n", f.x+1, f.y+1, f.startTime+1);
				}
			}
	}
	
	static class Field implements Comparable<Field> {
		public final int x, y;
		public final boolean hasStartRobot;
		public final char direction;
		
		public Field direct;
		public boolean used;
		public List<Field> cycans;
		
		public int enterOffset = -1;
		public Field enterPoint;
		public int cycdist = -1;
		
		public List<Field> robots;
		public int tinfo = 0;
		
		public int startTime = -1;
		
		public Field(int i, int j, char c) {
			x = i;
			y = j;
			direction = Character.toLowerCase(c);
			hasStartRobot = Character.isUpperCase(c);
		}
		
		public Field dfs() {
			if (cycans != null) return null;
			if (used) {
				cycans = new ArrayList<Field>();
				cycans.add(this);
				enterPoint = this;
				cycdist = 0;
				enterOffset = 0;
				return this;
			}
			used = true;
			Field cns = direct.dfs();
			cycans = direct.cycans;
			enterPoint = direct.enterPoint;
			cycdist = direct.cycdist+1;
			if (cns == this) {
				cns = null;
				cycdist = 0;
				enterPoint = this;
			}
			if (cns != null) {
				cycans.add(this);
				cycdist = 0;
				enterPoint = this;
				enterOffset = direct.enterOffset+1;
			}
			return cns;
		}
		
		@Override
		public int compareTo(Field f) {
			return x == f.x ? Integer.compare(y, f.y) : Integer.compare(x, f.x);
		}
	}
	
	class RFScanner implements Closeable {
		private BufferedReader rd;
		private StringTokenizer tk;
		
		public RFScanner(InputStream in) throws IOException {
			rd = new BufferedReader(new InputStreamReader(in));
			tk = new StringTokenizer("");
		}
		
		public String next() throws IOException {
			while (!tk.hasMoreTokens()) {
				tk = new StringTokenizer(rd.readLine());
			}
			return tk.nextToken();
		}
		
		public String nextLine() throws IOException {
			return rd.readLine();
		}
		
		public int nextInt() throws NumberFormatException, IOException {
			return Integer.parseInt(next());
		}

		@Override
		public void close() throws IOException {
			rd.close();
		}
	}
}
