#include <bits/stdc++.h>

using std::cin;
using std::cout;
using std::cerr;

using std::vector;
using std::string;
using std::array;
using std::pair;
using std::make_pair;

using std::min;
using std::max;
using std::abs;

template <typename T>
T input() {
    T res;
    cin >> res;
    return res;
}

#ifdef LOCAL
#define LASSERT(x) assert(x)
#else
#define LASSERT(x) {}
#endif

int32_t n, m, g;

int32_t id_of(int32_t a, int32_t b) {
    return a * m + b;
}

vector<vector<int32_t>> inter;
vector<int32_t> cur;
void dfs(const vector<vector<int32_t>>& graph, vector<char>& used, int32_t v) {
    cur.push_back(v);
    used[v] = 1;
    for (int32_t u: graph[v]){
        if (used[u] == 1) {
            inter.resize(inter.size() + 1);
            inter.back().push_back(u);
            for (int32_t i = cur.size() - 1; cur[i] != u; --i) {
                inter.back().push_back(cur[i]);
            }
        } else if (used[u] == 0) {
            dfs(graph, used, u);
        }
    }

    cur.pop_back();
    used[v] = 2;
}

void dfs2(const vector<vector<int32_t>>& graph, vector<char>& used, int32_t v, vector<int32_t>& list) {
    used[v] = true;
    list.push_back(v);
    for (int32_t u: graph[v])
        if (not used[u])
            dfs2(graph, used, u, list);
}

int main() {
    // save with C-x C-s
    std::iostream::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
#ifndef LOCAL
#define TASK "robots"
    freopen(TASK ".in", "r", stdin);
    freopen(TASK ".out", "w", stdout);
#endif

    cin >> n >> m >> g;

    vector<vector<int32_t>> graph(n * m);
    vector<vector<int32_t>> rgraph(n * m);
    vector<char> good(n * m, false);

    for (int32_t i = 0; i != n; ++i)
        for (int32_t j = 0; j != m; ++j) {
            char ch = input<char>();
            if ('A' <= ch and ch <= 'Z') {
                good[id_of(i, j)] = true;
                ch -= 'A';
                ch += 'a';
            }

            if (ch == 'n')
                graph[id_of(i, j)].push_back(id_of(i - 1, j));
            else if (ch == 'e')
                graph[id_of(i, j)].push_back(id_of(i, j + 1));
            else if (ch == 'w')
                graph[id_of(i, j)].push_back(id_of(i, j - 1));
            else if (ch == 's')
                graph[id_of(i, j)].push_back(id_of(i + 1, j));
            else
                LASSERT(false);
        }

    for (int32_t i = 0; i != n * m; ++i)
        for (auto v: graph[i])
            rgraph[v].push_back(i);

    vector<char> used(n * m, 0);
    for (int32_t i = 0; i != n * m; ++i)
        if (used[i] == 0)
            dfs(graph, used, i);

    std::fill(used.begin(), used.end(), 0);
    int32_t ans = 0;
    for (int32_t i = 0; i != int32_t(inter.size()); ++i) {
        if (used[inter[i][0]] == 1) {
            LASSERT(false);
        } else {
            vector<int32_t> list;
            dfs2(rgraph, used, inter[i][0], list);
            int32_t cnt = 0;
            for (int32_t u: list)
                cnt += good[u];
            ans += min(cnt, int32_t(inter[i].size()));
        }
    }
    cout << ans << "\n";
    return 0;
}