#include <iostream>
#include <vector>
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

#define SIZE 1228
#define TotSize 1000228
#define pint pair<int, int>
#define mp make_pair

char p[SIZE][SIZE];
int n, m, g;
int gr[TotSize];
vector<int> rgr[TotSize];
vector<pint> gr_comp[TotSize];
int sz[TotSize];
int in[TotSize];
int cntout[TotSize];
//int come[TotSize];
int comp[TotSize];
bool r[TotSize];
bool used[TotSize];
int cntC = 0;
int szts = 0;
int TopSort[TotSize];
int cyclepos[TotSize];
vector<int> inc[TotSize];
vector<pair<pint, int> > nwcycle;
vector<pint> print;

void Dfs(int v)
{
	used[v] = true;
	if (!used[gr[v]])
		Dfs(gr[v]);
	TopSort[szts] = v;
	szts++;
}

void DfsBuild(int v, int ncomp)
{
	used[v] = true;
	comp[v] = ncomp;
	cyclepos[v] = sz[ncomp];
	inc[ncomp].push_back(v);
	if (r[v])
		in[ncomp]++;
	sz[ncomp]++;
	for (size_t i = 0; i < rgr[v].size(); i++)
	{
		if (!used[rgr[v][i]])
			DfsBuild(rgr[v][i], ncomp);
		else if (comp[rgr[v][i]] != ncomp)
		{
			gr_comp[ncomp].push_back(mp(comp[rgr[v][i]], cyclepos[v]));
			cntout[comp[rgr[v][i]]]++;
		}
	}
}

int DfsCnt(int v, int d, int pos)
{
	int ans = in[v];
	for (size_t i = 0; i < inc[v].size(); i++)
	{
		if (r[inc[v][i]])
		{
			if (d != 0)
				nwcycle.push_back(mp(mp(inc[v][i], d), pos));
		}
	}
	for (size_t i = 0; i < gr_comp[v].size(); i++)
	{
		if (d == 0)
			ans += DfsCnt(gr_comp[v][i].first, d + 1 + gr_comp[v][i].second, gr_comp[v][i].second);
		else
			ans += DfsCnt(gr_comp[v][i].first, d + 1 + gr_comp[v][i].second, pos);
	}
	return ans;
}

int main()
{
	freopen("robots.in", "r", stdin);
	freopen("robots.out", "w", stdout);
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin >> n >> m >> g;
	for (int i = 0; i < n; i++)
	{
		for (int q = 0; q < m; q++)
		{
			cin >> p[i][q];
			char c = tolower(p[i][q]);
			int nnum = i * m + q;
			if (c != p[i][q])
				r[nnum] = true;
			switch (c)
			{
			case 's':
				gr[nnum] = nnum + m;
				rgr[nnum + m].push_back(nnum);
				break;
			case 'e':
				gr[nnum] = nnum + 1;
				rgr[nnum + 1].push_back(nnum);
				break;
			case 'w':
				gr[nnum] = nnum - 1;
				rgr[nnum - 1].push_back(nnum);
				break;
			case 'n':
				gr[nnum] = nnum - m;
				rgr[nnum - m].push_back(nnum);
				break;
			}
		}
	}
	for (int i = 0; i < n * m; i++)
	{
		if (!used[i])
			Dfs(i);
	}
	reverse(TopSort, TopSort + n * m);
	memset(used, 0, sizeof(used));
	for (int i = 0; i < n * m; i++)
	{
		if (!used[TopSort[i]])
		{
			DfsBuild(TopSort[i], cntC);
			cntC++;
		}
	}
	/*for (int i = 0; i < n * m; i++)
	{
		if (cyclepos[i] != 0)
			cyclepos[i] = sz[comp[i]] - cyclepos[i];
	}
	for (int i = 0; i < cntC; i++)
	{
		for (size_t q = 0; q < gr_comp[i].size(); q++)
		{
			if (gr_comp[i][q].second != 0)
				gr_comp[i][q].second = sz[i] - gr_comp[i][q].second;
		}
	}*/
	int ans = 0;
	for (int i = 0; i < cntC; i++)
	{
		if (cntout[i] == 0)
		{
			nwcycle.clear();
			int cm = DfsCnt(i, 0, -1);
			cm -= in[i];
			ans += in[i] + min(cm, sz[i] - in[i]);
			int it = 0;
			for (size_t q = 0; q < inc[i].size(); q++)
			{
				if (r[inc[i][q]])
					print.push_back(mp(inc[i][q], 0));
				else
				{
					if (it < nwcycle.size())
					{
						int coming = nwcycle[it].second;
						int go;
						if (coming >= cyclepos[inc[i][q]])
							go = coming - cyclepos[inc[i][q]];
						else
							go = sz[i] - cyclepos[inc[i][q]] + coming;
						int gov = nwcycle[it].first.second - coming;
						print.push_back(mp(nwcycle[it].first.first, coming - cyclepos[inc[i][q]] - gov + sz[i] * 1000));
						it++;
					}
				}
			}
		}
	}
	cout << ans << endl;
	if (g == 1)
	{
		for (int i = 0; i < ans; i++)
			cout << print[i].first / m + 1 << ' ' << print[i].first % m + 1 << ' ' << print[i].second + 1 << endl;
	}
	return 0;
}