#ifdef LOCAL
#include <iostream>
#else
#include <fstream>
#endif
#include <vector>
#include <stack>
#include <queue>

using namespace std;

int main(void) {
  #ifndef LOCAL
  ifstream cin("robots.in");
  ofstream cout("robots.out");
  #endif
  int n, m, g, lid = 0;
  char c;
  cin >> n >> m >> g;
  vector<int> dest(n * m, 0);
  vector<bool> hasBot(n * m, false);
  vector<int> color(n * m, -1);
  vector<int> enter(n * m, -1);
  vector<priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>>> childs(n * m, priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>>());
  vector<int> cid(n * m, -1);
  vector<int> robotsOnCycle, cellsOnCycle, robotsAroundCycle, cycleNode;
  vector<pair<int, int>> fullAns;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> c;
      switch (c) {
        case 'E':
          hasBot[i * m + j] = true;
        case 'e':
          dest[i * m + j] = i * m + j + 1;
          break;
        case 'N':
          hasBot[i * m + j] = true;
        case 'n':
          dest[i * m + j] = i * m + j - m;
          break;
        case 'W':
          hasBot[i * m + j] = true;
        case 'w':
          dest[i * m + j] = i * m + j - 1;
          break;
        case 'S':
          hasBot[i * m + j] = true;
        case 's':
          dest[i * m + j] = i * m + j + m;
          break;
      }
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (color[i * m + j] == -1) {
        stack<int> st;
        st.push(i * m + j);
        while (color[dest[st.top()]] == -1) {
          color[st.top()] = -2;
          st.push(dest[st.top()]);
        }
        if (color[dest[st.top()]] == -2) {
          int good = dest[st.top()];
          robotsOnCycle.push_back(0);
          robotsAroundCycle.push_back(0);
          cellsOnCycle.push_back(0);
          cycleNode.push_back(n * m);
          while (st.top() != good) {
            enter[st.top()] = st.top();
            color[st.top()] = 0;
            cid[st.top()] = lid;
            cellsOnCycle[lid]++;
            cycleNode[lid] = min(cycleNode[lid], st.top());
            if (hasBot[st.top()]) robotsOnCycle[lid]++;
            st.pop();
          }
          int cnt = 0;
          while (!st.empty()) {
            enter[st.top()] = good;
            color[st.top()] = cnt;
            cid[st.top()] = lid;
            if (cnt == 0) {
              cellsOnCycle[lid]++;
              if (hasBot[st.top()]) robotsOnCycle[lid]++;
              cycleNode[lid] = min(cycleNode[lid], st.top());
            } else {
              if (hasBot[st.top()]) {
                robotsAroundCycle[lid]++;
                childs[good].push(make_pair(color[st.top()], st.top()));
              }
            }
            cnt++;
            st.pop();
          }
          lid++;
        } else {
          int ent = enter[dest[st.top()]];
          int rcid = cid[dest[st.top()]];
          int cnt = color[dest[st.top()]];
          while (!st.empty()) {
            cnt++;
            color[st.top()] = cnt;
            enter[st.top()] = ent;
            cid[st.top()] = rcid;
            if (hasBot[st.top()]) {
              childs[ent].push(make_pair(color[st.top()], st.top()));
              robotsAroundCycle[rcid]++;
            }
            st.pop();
          }
        }
      }
    }
  }
  int ans = 0;
  for (int i = 0; i < lid; i++) {
    ans += min(robotsOnCycle[i] + robotsAroundCycle[i], cellsOnCycle[i]);
    int current = cycleNode[i];
    int estimated = min(robotsAroundCycle[i], cellsOnCycle[i] - robotsOnCycle[i]);
    priority_queue<int, vector<int>, greater<int>> freeDists;
    int id = 0;
    while (current != cycleNode[i] || id == 0) {
      if (!hasBot[current])
        freeDists.push((cellsOnCycle[i] - id) % cellsOnCycle[i]);
      else
        fullAns.push_back(make_pair(current, 0));
      current = dest[current];
      id++;
    }
    id = 0;
    while (estimated > 0) {
      while (childs[current].empty()) {
        current = dest[current];
        id++;
      }
      estimated--;
      pair<int, int> nextGood = childs[current].top();
      fullAns.push_back(make_pair(nextGood.second, (freeDists.top() + id) % cellsOnCycle[i] + nextGood.first));
      childs[current].pop();
      freeDists.pop();
    }
  }
  cout << ans << endl;
  if (g == 0) return 0;
  for (int i = 0, sz = fullAns.size(); i < sz; i++) {
    cout << fullAns[i].first / m + 1 << " " << fullAns[i].first % m + 1 << " " << fullAns[i].second << endl;
  }
  return 0;
}
