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

using namespace std;

vector<vector<int>> graph, graph_rev;
vector<int> weak, strong, sorted;
vector<bool> used;

long long min(long long a, long long b) {
    return (a > b) ? b : a;
}
long long max(long long a, long long b) {
    return (a > b) ? a : b;
}

void dfs_weak(int u, int cnt) {
    weak[u] = cnt;
    used[u] = true;
    for (int v : graph[u]) {
        if (!used[v]) {
            dfs_weak(v, cnt);
        }
    }
    for (int v : graph_rev[u]) {
        if (!used[v]) {
            dfs_weak(v, cnt);
        }
    }
}

void dfs_strong(int u) {
    used[u] = true;

    for (int v : graph[u]) {
        if (!used[v]) {
            dfs_strong(v);
        }
    }
    sorted.push_back(u);
}

void dfs_revert(int u, int cnt) {
    used[u] = true;
    strong[u] = cnt;
    for (int v : graph_rev[u]) {
        if (!used[v]) {
            dfs_revert(v, cnt);
        }
    }
}

int main() {
    freopen("robots.in", "r", stdin);
    int n, m, g;
    cin >> n >> m >> g;
    graph.resize(n * m);
    graph_rev.resize(n * m);
    weak.resize(n * m);
    strong.resize(n * m);
    vector<bool> colored(n * m, false);
    char c[1179];
    for (int i = 0; i < n; i++) {
        scanf("%s", c);
        for (int j = 0; j < m; j++) {
            int u = i * m + j;
            if (c[j] == 'e' or c[j] == 'E') {
                graph[u].push_back(u + 1);
                graph_rev[u + 1].push_back(u);
            }
            if (c[j] == 'w' or c[j] == 'W') {
                graph[u].push_back(u - 1);
                graph_rev[u - 1].push_back(u);
            }
            if (c[j] == 'N' or c[j] == 'n') {
                graph[u].push_back(u - m);
                graph_rev[u - m].push_back(u);
            }
            if (c[j] == 'S' or c[j] == 's') {
                graph[u].push_back(u + m);
                graph_rev[u + m].push_back(u);
            }
            if (c[j] == 'S' or c[j] == 'E' or c[j] == 'W' or c[j] == 'N') {
                colored[u] = true;
            }
        }
    }
    used.assign(n * m, 0);
    int cnt = 0;
    for (int i = 0; i < n * m; i++) {
        if (!used[i]) {
            dfs_weak(i, cnt++);
        }
    }
    vector<vector<int> > weak_components(cnt);
    for (int i = 0; i < n * m; i++) {
        weak_components[weak[i]].push_back(i);
    }
    used.assign(n * m, 0);
    cnt = 0;
    for (int i = 0; i < n * m; i++) {
        if (!used[i]) {
            dfs_strong(i);
        }
    }
    reverse(sorted.begin(), sorted.end());
    used.assign(n * m, 0);
    for (int u : sorted) {
        if (!used[u]) {
            dfs_revert(u, cnt++);
        }
    }
    vector<vector<int> > strong_components(cnt);
    for (int i = 0; i < n * m; i++) {
        strong_components[strong[i]].push_back(i);
    }
    int ans = 0;
    for (int i = 0; i < cnt; i++) {
        if (strong_components[i].size() > 1) {
            int c_am = 0;
            for (int j : weak_components[weak[strong_components[i][0]]]) {
                c_am += colored[j];
            }
            ans += min(c_am, strong_components[i].size());
        }
    }
    cout << ans << endl;
}
