#define	_CRT_SECURE_NO_WARNINGS
#define	_USE_MATH_DEFINES
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cassert>
#include <cstdio>
#include <ctime>
#include <iostream>
#include <utility>
#include <string>
#include <algorithm>
#include <functional>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <deque>
#include <vector>

#define	mp	make_pair

using namespace std;

typedef	long long int	ll;
typedef	long double		ld;
typedef	pair<int, int>	ii;
typedef	vector<int>		vi;
typedef	vector<ii>		vii;

const int MAXN = 2000;
const int INF = 1000000010;

int N, M, G;
char s[MAXN][MAXN];
bool r[MAXN][MAXN] = { false };
int cn = 0;
int dfst = 0;
int cid[MAXN][MAXN];
int tin[MAXN][MAXN];
bool ansd[MAXN][MAXN] = { false };
int ri, rj;
set<int> free_places;
vector<ii> cyc;
int curc;
int ans = 0;
int tact[MAXN][MAXN];

inline ii get_next(int pi, int pj) {
	if (pi < 0 || pi >= N || pj < 0 || pj >= M)
		return mp(-1, -1);
	
	int ni = pi, nj = pj;
	switch (s[pi][pj]) {
	case 'n':
		ni--;
		break;
	case 'e':
		nj++;
		break;
	case 's':
		ni++;
		break;
	case 'w':
		nj--;
		break;
	}

	return mp(ni, nj);
}

void fill_ans(int pi, int pj, int curt, int pos) {
	int ptr;
	set<int>::iterator iter;

	if (!ansd[pi][pj]) {
		if (r[pi][pj]) {
			iter = free_places.lower_bound((pos + curt) % cyc.size());

			if (iter != free_places.end()) {
				ans++;

				ptr = *iter;
				curt += ptr - pos;
				tact[pi][pj] = 1 + curt;

				ptr %= cyc.size();
				free_places.erase(ptr);
				free_places.erase(ptr + cyc.size());
			}
		}

		ansd[pi][pj] = true;
	}

	ii curpos = mp(pi, pj);
	if (get_next(pi - 1, pj) == curpos && !ansd[pi - 1][pj])
		fill_ans(pi - 1, pj, curt, (pos + 1) % cyc.size());
	if (get_next(pi + 1, pj) == curpos && !ansd[pi + 1][pj])
		fill_ans(pi + 1, pj, curt, (pos + 1) % cyc.size());
	if (get_next(pi, pj - 1) == curpos && !ansd[pi][pj - 1])
		fill_ans(pi, pj - 1, curt, (pos + 1) % cyc.size());
	if (get_next(pi, pj + 1) == curpos && !ansd[pi][pj + 1])
		fill_ans(pi, pj + 1, curt, (pos + 1) % cyc.size());
}

void dfs(int pi, int pj) {
	tin[pi][pj] = dfst++;
	int ni = pi, nj = pj;

	switch (s[pi][pj]) {
	case 'n':
		ni--;
		break;
	case 'e':
		nj++;
		break;
	case 's':
		ni++;
		break;
	case 'w':
		nj--;
		break;
	}

	if (cid[ni][nj] != -1) {
		cid[pi][pj] = cid[ni][nj];
	}
	else if (tin[ni][nj] != -1) {
		ri = ni;
		rj = nj;

		cid[pi][pj] = cn;
		cn++;
	}
	else {
		dfs(ni, nj);
		cid[pi][pj] = cid[ni][nj];
	}

	if (ri != -1 && rj != -1) {
		cyc.push_back(mp(pi, pj));
	}

	int ptri, ptrj, len = 0;
	if (pi == ri && pj == rj) {
		ri = rj = -1;
		curc = cid[pi][pj];

		for (auto it = cyc.begin(); it != cyc.end(); it++) {
			ptri = it->first;
			ptrj = it->second;

			if (r[ptri][ptrj]) {
				ans++;
				tact[ptri][ptrj] = 1;
			}
			else {
				free_places.insert(len);
				free_places.insert(len + cyc.size());
			}

			ansd[ptri][ptrj] = true;

			len++;
		}

		len = 0;
		for (auto it = cyc.begin(); it != cyc.end(); it++) {
			fill_ans(it->first, it->second, 0, len);
			len++;
		}
	}
}

int main() {
#ifdef FILE_IO
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#else
	freopen("robots.in", "r", stdin);
	freopen("robots.out", "w", stdout);
#endif // FILE_IO

	scanf("%d %d %d", &N, &M, &G);

	for (int i = 0; i < N; i++) {
		scanf("%s", s[i]);
		for (int j = 0; j < M; j++) {
			if ('A' <= s[i][j] && s[i][j] <= 'Z')
				r[i][j] = true;

			s[i][j] = tolower(s[i][j]);
		}
	}

	memset(tin, -1, sizeof(tin));
	memset(cid, -1, sizeof(cid));
	memset(tact, -1, sizeof(tact));

	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			if (!ansd[i][j]) {
				free_places.clear();
				cyc.clear();
				ri = -1;
				rj = -1;
				dfs(i, j);
			}
		}
	}

	printf("%d\n", ans);
	if (G) {
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < M; j++) {
				if (tact[i][j] != -1) {
					assert(tact[i][j] <= 1000000000);

					printf("%d %d %d\n", i + 1, j + 1, tact[i][j]);
				}
			}
		}
	}

	return 0;
}