#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <cstdlib>
#include <string>
#include <map>
#include <vector>
#define ll long long
using namespace std;

const int MAXN = 1e3 + 111;

int n, m, g;

string s[MAXN];

int len[MAXN * MAXN], cnt[MAXN * MAXN];

int ans = 0;

int cur = 0;

int cc = 0;

int dst[MAXN][MAXN];

int cycle[MAXN][MAXN];

int t[MAXN][MAXN];

vector <vector <int> > vv;

vector <pair <int, int> > path;

map <char, pair <int, int> > mp;

int tt[MAXN][MAXN];

int was[MAXN][MAXN];

bool good[MAXN][MAXN];

pair <int, int> go[MAXN][MAXN];

void init()
{
	vv.resize(MAXN * MAXN);
	//memset(dst, -1, sizeof dst);
	memset(cycle, -1, sizeof cycle);
	mp['S'] = mp['s'] = make_pair(1, 0);
	mp['N'] = mp['n'] = make_pair(-1, 0);
	mp['W'] = mp['w'] = make_pair(0, -1);
	mp['E'] = mp['e'] = make_pair(0, 1);
}

bool have(int x, int y)
{
	return s[x][y] < 'a';
}

void cover(int x, int y, int cur)
{
	int id = path.size() - 1;
	int ln = 0;
	bool f = false;
	int curtt = 0;
	while (id >= 0)
	{
		if (!f)
		{
			ln++;
			go[path[id].first][path[id].second] = path[id];
			tt[path[id].first][path[id].second] = curtt++;
		}
		else
			go[path[id].first][path[id].second] = make_pair(x, y);
		cycle[path[id].first][path[id].second] = cur;
		if (path[id] == make_pair(x, y))
			f = true;
		id--;
	}
	len[cur] = ln;
	cnt[cur] = 1;
	for (int i = 0; i < ln; i++)
		vv[cur].push_back(i);
}

void recalc(int x, int y, int cur)
{
	int id = path.size() - 1;
	while (id >= 0)
	{
		go[path[id].first][path[id].second] = make_pair(x, y);
		cycle[path[id].first][path[id].second] = cur;
		id--;
	}
}

bool solve(int x, int y)
{
	path.clear();
	cc++;
	while (true)
	{
		was[x][y] = cc;
		path.push_back(make_pair(x, y));
		if (cycle[x][y] != -1)
		{
			recalc(go[x][y].first, go[x][y].second, cycle[x][y]);
			if (cnt[cycle[x][y]] < len[cycle[x][y]])
			{
				cnt[cycle[x][y]]++;
				ans++;
				return true;
			}
			return false;
		}
		int nx = x + mp[s[x][y]].first;
		int ny = y + mp[s[x][y]].second;
		if (was[nx][ny] == cc)
		{
			cover(nx, ny, cur++);
			ans++;
			return true;
		}
		x = nx;
		y = ny;
	}
	return false;
}

int get(int x, int y)
{
	if (was[x][y])
		return dst[x][y];
	if (go[x][y] == make_pair(x, y))
		return dst[x][y] = 0;
	was[x][y] = true;
	int nx = x + mp[s[x][y]].first;
	int ny = y + mp[s[x][y]].second;
	return dst[x][y] = get(nx, ny) + 1;
}

int main()
{
	freopen("robots.in", "r", stdin);
	freopen("robots.out", "w", stdout);
	scanf("%d %d %d", &n, &m, &g);
	for (int i = 0; i < n; i++)
		cin >> s[i];
	init();
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			if (have(i, j))
				good[i][j] = solve(i, j);
		}
	}
	memset(was, 0, sizeof was);
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			if (have(i, j) && good[i][j])
				get(i, j);
		}
	}
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			if (have(i, j) && good[i][j])
			{
				int nx = go[i][j].first;
				int ny = go[i][j].second;
				int cc = cycle[i][j];
				t[i][j] = (dst[i][j] + tt[nx][ny]) % len[cc];
				int sz = vv[cc].size();
				int time = vv[cc][sz - 1] + len[cc];
				t[i][j] = (time - t[i][j]) % len[cc];
				t[i][j] %= len[cc];
				vv[cc].pop_back();
			}
		}
	}
	if (g)
	{
		printf("%d\n", ans);
		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < m; j++)
			{
				if (have(i, j) && good[i][j])
				{
					printf("%d %d %d\n", i + 1, j + 1, t[i][j] + 1);
				}
			}
		}
	}
	else
		cout << ans;
	return 0;
}