/*input
6 3 4
SWNEES
2 1 1 2
1 0 1 3
1 1 2 2
*/
#pragma GCC optimize ("O3")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
int kiek = 1e9;
int ans = 0;
int M, R, C;
int U[800][800];
bool uzkrestas[800][800];
int maxi[1 << 4];
const int dx[4] = {0, -1, 0, 1};
const int dy[4] = {1, 0, -1, 0};
bool serga(int i, int j)
{
if (i < 0 || i >= R || j < 0 || j >= C)
return false;
return uzkrestas[i][j];
}
bool uzsikres(int i, int j)
{
if (i < 0 || i >= R || j < 0 || j >= C)
return false;
if (uzkrestas[i][j])
return false;
int mask = 0;
for (int t = 0; t < 4; t++)
if (serga(i + dx[t], j + dy[t]))
{
mask += (1 << t);
if (U[i][j] <= maxi[mask])
return true;
}
return false;
}
int comp[800][800];
const int MAXN = 800 * 800 + 30;
vector<pair<int, int>>X[MAXN];
vector<int>out[MAXN];
vector<int>in[MAXN];
struct SCC
{
vector<vector<int>>adj;
int timer = 2;
vector<int>v;
vector<int>mn;
stack<int>S;
vector<bool> stake;
vector<vector<int>>comp;
SCC()
{
adj = vector<vector<int>>(MAXN);
v = vector<int>(MAXN, 0);
mn = vector<int>(MAXN, 0);
stake = vector<bool>(MAXN, false);
}
void reset()
{
timer = 2;
adj = vector<vector<int>>(MAXN);
v = vector<int>(MAXN, 0);
mn = vector<int>(MAXN, 0);
stake = vector<bool>(MAXN, false);
comp.clear();
}
void dfs(int i)
{
if (v[i] > 0)
return;
v[i] = timer++;
mn[i] = v[i];
stake[i] = true;
S.push(i);
for (int j : adj[i])
{
if (stake[j])
{
mn[i] = min(mn[i], v[j]);
}
else if (v[j] == 0)
{
dfs(j);
mn[i] = min(mn[i], mn[j]);
}
}
if (mn[i] == v[i])
{
comp.push_back({});
while (true)
{
int j = S.top();
S.pop();
stake[j] = false;
comp.back().push_back(j);
if (j == i)
break;
}
}
}
void edge(int a, int b)
{
adj[a].push_back(b);
}
void ieskok(vector<int>V)
{
for (int i : V)
dfs(i);
}
} scc;
void spresk()
{
/*
for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
cout << comp[i][j] << " ";
}
cout << endl;
}*/
for (int i = 0; i < MAXN; i++)
{
X[i].clear();
in[i].clear();
out[i].clear();
}
int mini = 1e9;
for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
if (comp[i][j] >= 0)
{
X[comp[i][j]].push_back({i, j});
mini = min(mini, (int)X[comp[i][j]].size());
}
}
}
if (mini > kiek)
{
cout << kiek << "\n" << ans << "\n";
exit(0);
return;
}
for (int i = 0; i < MAXN; i++)
{
if (X[i].empty())
continue;
for (auto xy : X[i])
{
uzkrestas[xy.first][xy.second] = true;
}
bool blogas = false;
bool kazkur = false;
vector<int>oo;
for (auto xy : X[i])
{
for (int t = 0; t < 4; t++)
{
int x = xy.first + dx[t];
int y = xy.second + dy[t];
if (uzsikres(x, y))
{
if (comp[x][y] == -1)
blogas = true;
else
oo.push_back(comp[x][y]);
kazkur = true;
}
}
}
for (auto xy : X[i])
{
uzkrestas[xy.first][xy.second] = false;
}
if (kazkur == false)
{
int sz = X[i].size();
if (kiek > sz)
{
kiek = sz;
ans = 0;
}
if (kiek == sz)
{
ans += sz;
}
blogas = true;
}
if (blogas)
{
queue<int>Q;
Q.push(i);
out[i].clear();
while (!Q.empty())
{
int j = Q.front();
Q.pop();
for (auto xy : X[j])
{
comp[xy.first][xy.second] = -1;
}
for (int k : in[j])
{
if (out[k].size() > 0)
{
out[k].clear();
Q.push(k);
}
}
in[j].clear();
}
}
else
{
for (int o : oo)
{
out[i].push_back(o);
in[o].push_back(i);
}
}
}
scc.reset();
for (int i = 0; i < MAXN; i++)
{
if (X[i].empty())
continue;
for (int j : out[i])
scc.edge(i, j);
}
for (int i = 0; i < MAXN; i++)
{
if (X[i].empty())
continue;
if (in[i].size() + out[i].size() == 0)
continue;
scc.dfs(i);
}
for (vector<int>i : scc.comp)
{
int c = i[0];
for (int j : i)
{
for (auto xy : X[j])
{
comp[xy.first][xy.second] = c;
}
}
}
spresk();
}
int kryptis[256];
int main()
{
ios_base::sync_with_stdio(false);
cin >> M >> R >> C;
string D;
cin >> D;
kryptis['W'] = 2;
kryptis['S'] = 3;
kryptis['E'] = 0;
kryptis['N'] = 1;
for (int msk = 0; msk < (1 << 4); msk++)
{
int jau = 0;
for (int i = 0; i < 200000; i++)
{
char c = D[i % D.size()];
int ii = kryptis[(int)c];
if ((msk & (1 << ii)) > 0)
{
jau++;
}
else
jau = 0;
maxi[msk] = max(maxi[msk], jau);
}
}
int timer = 0;
for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
cin >> U[i][j];
if (U[i][j] == 0)
{
comp[i][j] = -1;
U[i][j] = 1e8;
}
else
{
comp[i][j] = timer++;
}
}
}
spresk();
}