/* 省选:2026.3.7 */
/* YMao99! */
/* Hatsune Miku x Kasane Teto */
#include <bits/stdc++.h>
#define lowbit(x) ((x) & (-(x)))
using namespace std;
const int N = 100010;
typedef pair < int, int > PAIR;
int n, m, k;
struct Point
{
int x, y, val;
bool operator < (const Point &w) const {return x < w.x;}
bool operator > (const Point &w) const {return x > w.x;}
} s[N]; vector < Point > save[2 * N];
set < PAIR > S[4]; Point pt; int dir;
set < Point > SN[2 * N], SZ[2 * N];
struct Line {Point x, y;}; vector < Line > LN[2 * N], LZ[2 * N];
inline bool check(int x, int y)
{
// 检测 (x, y) 是否 无 障碍物
if(1 <= x && x <= n && 1 <= y && y <= m && !SZ[x + y].count({x, y})) return true;
else return false;
}
struct BIT
{
int c[N * 2];
inline void add(int pos, int num)
{for(int i = pos; i <= n + m; i += lowbit(i)) c[i] += num;}
inline int ask(int pos)
{
int ans = 0;
for(int i = pos; i; i -= lowbit(i)) ans += c[i];
return ans;
}
inline int query(int l, int r) {return ask(r) - ask(l - 1);}
}; BIT T[2];
int main()
{
#ifndef LOCAL
// freopen("color.in", "r", stdin);
// freopen("color.out", "w", stdout);
#endif
#ifdef LOCAL
// freopen("text.in", "r", stdin);
// freopen("prog.out", "w", stdout);
#endif
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
// 读入
cin >> n >> m >> k;
for(int i = 1; i <= k; ++i)
{
cin >> s[i].x >> s[i].y;
SZ[s[i].x + s[i].y].insert(s[i]);
SN[s[i].x - s[i].y + m].insert(s[i]);
}
cin >> pt.x >> pt.y; string str; cin >> str;
if(str == "NW") dir = 0;
else if(str == "NE") dir = 1;
else if(str == "SW") dir = 2;
else dir = 3;
// 反射模拟
while(!S[dir].count({pt.x, pt.y}))
{
function < Point (Point, int) > calc = [&](Point pt, int dir)
{
// 计算 pt 沿着 dir 方向走会到达哪个点
if(dir == 0 || dir == 3)
{
int ID = pt.x - pt.y + m; // 对角线的编号
auto pter = SN[ID].lower_bound(pt);
if(dir == 3)
{
if(pter == SN[ID].end())
{
int delta = min(n - pt.x, m - pt.y);
pt.x += delta, pt.y += delta; return pt;
}
else return (Point){pter -> x - 1, pter -> y - 1};
}
else
{
if(pter == SN[ID].begin())
{
int delta = min(pt.x - 1, pt.y - 1);
pt.x -= delta, pt.y -= delta; return pt;
}
else return (Point){prev(pter) -> x + 1, prev(pter) -> y + 1};
}
}
else
{
int ID = pt.x + pt.y;
auto pter = SZ[ID].lower_bound(pt);
if(dir == 1)
{
if(pter == SZ[ID].begin())
{
int delta = min(pt.x - 1, m - pt.y);
pt.x -= delta, pt.y += delta; return pt;
}
else return (Point){prev(pter) -> x + 1, prev(pter) -> y - 1};
}
else
{
if(pter == SZ[ID].end())
{
int delta = min(n - pt.x, pt.y - 1);
pt.x += delta, pt.y -= delta; return pt;
}
else return (Point){pter -> x - 1, pter -> y + 1};
}
}
};
function < void (Point, int) > simulate = [&](Point pos, int lst)
{
// 从 pos 点,lst 方向开始下一步反射
if(lst == 0)
{
if(check(pos.x, pos.y - 1) && !check(pos.x - 1, pos.y))
pt = pos, --pt.y, dir = 2;
else if(!check(pos.x, pos.y - 1) && check(pos.x - 1, pos.y))
pt = pos, --pt.x, dir = 1;
else pt = pos, dir = 3;
}
else if(lst == 1)
{
if(check(pos.x - 1, pos.y) && !check(pos.x, pos.y + 1))
pt = pos, --pt.x, dir = 0;
else if(!check(pos.x - 1, pos.y) && check(pos.x, pos.y + 1))
pt = pos, ++pt.y, dir = 3;
else pt = pos, dir = 2;
}
else if(lst == 2)
{
// cerr << "? " << pos.x << " " << pos.y << '\n';
if(check(pos.x + 1, pos.y) && !check(pos.x, pos.y - 1))
pt = pos, ++pt.x, dir = 3;
else if(!check(pos.x + 1, pos.y) && check(pos.x, pos.y - 1))
pt = pos, --pt.y, dir = 0;
else pt = pos, dir = 1;
}
else
{
if(check(pos.x + 1, pos.y) && !check(pos.x, pos.y + 1))
pt = pos, ++pt.x, dir = 2;
else if(!check(pos.x + 1, pos.y) && check(pos.x, pos.y + 1))
pt = pos, ++pt.y, dir = 1;
else pt = pos, dir = 0;
}
};
S[dir].insert({pt.x, pt.y});
Point nx = calc(pt, dir);
// cerr << "-> " << pt.x << " " << pt.y << " " << nx.x << " " << nx.y << " " << dir << '\n';
if(pt.x + pt.y == nx.x + nx.y) LZ[pt.x + pt.y].push_back({min(pt, nx), max(pt, nx)});
else LN[pt.x - pt.y + m].push_back({min(pt, nx), max(pt, nx)});
simulate(nx, dir);
}
// 去掉重复的线段
function < void (vector < Line > &) > rebuild = [&](vector < Line > &tmp)
{
if(tmp.empty()) return ;
function < bool (Line, Line) > cmp = [&](Line u, Line v) {return u.x < v.x;};
sort(tmp.begin(), tmp.end(), cmp);
Line lst = tmp.front(); vector < Line > ret;
for(Line li : tmp)
{
if(li.x > lst.y)
{
ret.push_back(lst);
lst = li;
}
else lst.y = max(lst.y, li.y);
}
ret.push_back(lst);
tmp = ret;
};
for(int i = 1; i <= n + m - 1; ++i) rebuild(LN[i]);
for(int i = 2; i <= n + m; ++i) rebuild(LZ[i]);
// 扫描线统计答案
long long ans = 0;
for(int i = 1; i <= n + m - 1; ++i)
{
for(Line li : LN[i])
{
ans += li.y.x - li.x.x + 1;
save[li.x.x + li.x.y].push_back({li.x.x, li.x.y, 1});
save[li.y.x + li.y.y + 2].push_back({li.y.x + 1, li.y.y + 1, -1});
}
}
for(int i = 2; i <= n + m; ++i)
{
for(Point cur : save[i])
{
int ID = cur.x - cur.y + m;
T[ID & 1].add(ID, cur.val);
}
for(Line li : LZ[i])
{
int sum = li.y.x - li.x.x + 1;
int id_x = li.x.x - li.x.y + m, id_y = li.y.x - li.y.y + m;
sum -= T[id_x & 1].query(id_y, id_x);
ans += sum;
}
}
cout << ans << '\n';
return 0;
}
/*
*/