#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
#include <cstdlib>
#include <cstring>
#include <climits>
using namespace std;


struct NODE{
	int x,y,cst;
	NODE(int x,int y,int cst) : x(x) , y(y) , cst(cst) {}
};
bool operator < (const NODE &a,const NODE &b){
	return a.cst > b.cst;
}
int room[500][500];
bool flag[500][500];
int from[500*500];
int main(){
	int R;
	while(cin >> R && R){
		map<int,int> result[2];
		result[0][0] = 0;
		result[1][0] = 0;
		
		for(int i = 0 ; i < 2 ; i++){
			int W,H,sx,sy;
			cin >> W >> H >> sx >> sy;
			sx--,sy--;
			for(int y = 0 ; y < H ; y++)
				for(int x = 0 ; x < W ; x++)
					cin >> room[y][x];
			priority_queue<NODE> Q;
			Q.push(NODE(sx,sy,room[sy][sx]));
			memset(flag,0,sizeof(flag));
			while(Q.size()){
				NODE q = Q.top(); Q.pop();
				if(flag[q.y][q.x]) continue;
				else flag[q.y][q.x] = true;
				result[i][q.cst]++;
				int dx[] = {-1,0,1,0} , dy[] = {0,-1,0,1};
				for(int d = 0 ; d < 4 ; d++){
					int tx = q.x + dx[d] , ty = q.y + dy[d];
					if(tx >= 0 && ty >= 0 && tx < W && ty < H && !flag[ty][tx]) Q.push(NODE(tx,ty,max(q.cst,room[ty][tx])));
				}
			}
		}
		vector<int> u;
		int prev = 0;
		for(map<int,int>::iterator it = result[1].begin() ; it != result[1].end() ; ++it){
			from[u.size()] = it->first;
			u.push_back(it->second + prev);
			prev = u.back();
		}
		int ans = INT_MAX;
		u.push_back(INT_MAX);
		int prev2 = 0;
		for(map<int,int>::iterator it = result[0].begin() ; it != result[0].end() ; ++it){
			int thisLevel = it->first;
			int thisCount = it->second + prev2;
			int anotherCount = *lower_bound(u.begin(),u.end(),R-thisCount);
			if(anotherCount != INT_MAX){
				int anotherLevel = from[ lower_bound(u.begin(),u.end(),R-thisCount) - u.begin() ] ;
				ans = min(ans,thisLevel+anotherLevel);
			}
			prev2 += it->second;
		}
		cout << ans << endl;
	}
}