← Home
/* 省选: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;
}
/*
 
*/