#include <bits/stdc++.h>
using namespace std;
#define inf (int)(1e9)

struct edge{
	int to;
	int cost;

	edge(int to, int cost) : to(to), cost(cost){}
};

vector<int> dijkstra(vector<vector<edge> > g, int s){
	vector<int> ans(g.size(), inf);
	priority_queue<pair<int, int> > q;//(距離, 頂点番号)
	q.push(pair<int, int>(0, s));
	while(q.size() > 0){
		int dis = q.top().first, v = q.top().second;
		q.pop();
		if(dis < ans[v]){
			ans[v] = dis;
			for(int i = 0; i < g[v].size(); i++){
				q.push(pair<int, int>(dis + g[v][i].cost, g[v][i].to));
			}
		}
	}
	return ans;
}

int align(int x, int y){
	return 5 * x + y;
}

int main(){
	int N, M, Q, i, j;
	scanf("%d%d%d", &N, &M, &Q);
	vector<char> S(N + 2);
	vector<int> nextW(N + 2), nextE(N + 2), prevW(N + 2), prevE(N + 2);
	scanf("%s", &S[1]);
	nextW[N + 1] = N + 1;
	nextE[N + 1] = N + 1;
	for(i = N; i > 0; i--){
		if(S[i] == 'W'){
			nextW[i] = i;
			nextE[i] = nextE[i + 1];
		}
		else{
			nextW[i] = nextW[i + 1];
			nextE[i] = i;
		}
	}
	prevW[0] = 0;
	prevE[0] = 0;
	for(i = 1; i <= N; i++){
		if(S[i] == 'W'){
			prevW[i] = i;
			prevE[i] = prevE[i - 1];
		}
		else{
			prevW[i] = prevW[i - 1];
			prevE[i] = i;
		}
	}

	vector<char> T(M + 2);
	vector<int> nextN(M + 2), nextS(M + 2), prevN(M + 2), prevS(M + 2);
	scanf("%s", &T[1]);
	nextN[M + 1] = M + 1;
	nextS[M + 1] = M + 1;
	for(i = M; i > 0; i--){
		if(T[i] == 'N'){
			nextN[i] = i;
			nextS[i] = nextS[i + 1];
		}
		else{
			nextN[i] = nextN[i + 1];
			nextS[i] = i;
		}
	}
	prevN[0] = 0;
	prevS[0] = 0;
	for(i = 1; i <= M; i++){
		if(T[i] == 'N'){
			prevN[i] = i;
			prevS[i] = prevS[i - 1];
		}
		else{
			prevN[i] = prevN[i - 1];
			prevS[i] = i;
		}
	}
	for(int q = 0; q < Q; q++){
		int a, b, c, d;
		scanf("%d%d%d%d", &a, &b, &c, &d);
		int x[5], y[5];
		x[1] = min(a, c);
		x[3] = max(a, c);
		y[1] = min(b, d);
		y[3] = max(b, d);

		if(S[x[1]] == 'W'){
			x[0] = prevE[x[1] - 1];
			x[2] = min(x[3], nextE[x[1] + 1]);
		}
		else{
			x[0] = prevW[x[1] - 1];
			x[2] = min(x[3], nextW[x[1] + 1]);
		}
		if(x[0] == 0){
			x[0] = x[1];
		}
		if(S[x[3]] == 'W'){
			x[4] = nextE[x[3] + 1];
		}
		else{
			x[4] = nextW[x[3] + 1];
		}
		if(x[4] == N + 1){
			x[4] = x[3];
		}

		if(T[y[1]] == 'N'){
			y[0] = prevS[y[1] - 1];
			y[2] = min(y[3], nextS[y[1] + 1]);
		}
		else{
			y[0] = prevN[y[1] - 1];
			y[2] = min(y[3], nextN[y[1] + 1]);
		}
		if(y[0] == 0){
			y[0] = y[1];
		}
		if(T[y[3]] == 'N'){
			y[4] = nextS[y[3] + 1];
		}
		else{
			y[4] = nextN[y[3] + 1];
		}
		if(y[4] == M + 1){
			y[4] = y[3];
		}

/*		printf("x:");
		for(i = 0; i < 5; i++){
			printf("%d ", x[i]);
		}
		printf("\n");
		printf("y:");
		for(i = 0; i < 5; i++){
			printf("%d ", y[i]);
		}
		printf("\n");
*/
		vector<vector<edge> > g(25, vector<edge>());
		for(i = 0; i < 5; i++){
			if(S[x[i]] == 'W'){
				for(j = 1; j < 5; j++){
					g[align(i, j)].push_back(edge(align(i, j - 1), y[j] - y[j - 1]));
				}
			}
			else{
				for(j = 0; j < 4; j++){
					g[align(i, j)].push_back(edge(align(i, j + 1), y[j + 1] - y[j]));
				}
			}
		}
		for(j = 0; j < 5; j++){
			if(T[y[j]] == 'N'){
				for(i = 1; i < 5; i++){
					g[align(i, j)].push_back(edge(align(i - 1, j), x[i] - x[i - 1]));
				}
			}
			else{
				for(i = 0; i < 4; i++){
					g[align(i, j)].push_back(edge(align(i + 1, j), x[i + 1] - x[i]));
				}
			}
		}
		int s, t;
		for(i = 0; i < 25; i++){
			if(x[i / 5] == a && y[i % 5] == b){
				s = i;
				break;
			}
		}
		for(i = 0; i < 25; i++){
			if(x[i / 5] == c && y[i % 5] == d){
				t = i;
				break;
			}
		}
/*		for(i = 0; i < 25; i++){
			printf("edge[%d]:", i);
			for(j = 0; j < g[i].size(); j++){
				printf("(%d, %d) ", g[i][j].to, g[i][j].cost);
			}
			printf("\n");
		}
		printf("(s, t) = (%d, %d)\n", s, t);
*/		vector<int> res = dijkstra(g, s);
		if(res[t] == inf){
			printf("-1\n");
		}
		else{
			printf("%d\n", res[t]);
		}
	}
	return 0;
}

Measured memory_bytes: 4736