#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <map>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

struct Info{
	Info(int arg_row,int arg_col,int arg_max_level,int arg_max_level_index){
		row = arg_row;
		col = arg_col;
		max_level = arg_max_level;
		max_level_index = arg_max_level_index;
	}
	int row,col,max_level,max_level_index;
};

struct Data{
	Data(int arg_row,int arg_col,int arg_level){
		row = arg_row;
		col = arg_col;
		level = arg_level;
	}
	bool operator<(const struct Data &arg) const{
		return level > arg.level;
	};
	int row,col,level;
};

int R;
int diff_row[4] = {-1,0,0,1},diff_col[4] = {0,-1,1,0};

void func(){

	int W,H,start_col,start_row;
	scanf("%d %d %d %d",&W,&H,&start_col,&start_row);
	start_row--;
	start_col--;

	int table_1[H][W];

	vector<int> first_V;
	first_V.push_back(0);

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			scanf("%d",&table_1[row][col]);
			first_V.push_back(table_1[row][col]);
		}
	}

	sort(first_V.begin(),first_V.end());

	int pre  = -1;

	vector<int> second_V;

	for(int i = 0; i < first_V.size(); i++){
		if(pre != first_V[i]){
			second_V.push_back(first_V[i]);
		}
		pre = first_V[i];
	}

	map<int, int> index_map;

	for(int i = 0; i < second_V.size(); i++){
		index_map[second_V[i]] = i;
	}

	int ruisekiwa_1[second_V.size()];

	for(int i = 0; i < second_V.size(); i++){
		ruisekiwa_1[i] = 0;
	}

	queue<Info> Q;

	bool visited[H][W];
	bool pushed[H][W];

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			visited[row][col] = false;
			pushed[row][col] = false;
		}
	}

	visited[start_row][start_col] = true;
	ruisekiwa_1[1] = 1;

	Q.push(Info(start_row,start_col,1,1));
	int visited_num = 1;
	int limit = H*W;

	int next_row,next_col,next_level,next_index;

	priority_queue<Data> cannot_Q;

	while(visited_num < limit){

		next_level = BIG_NUM;

		while(!Q.empty()){

			for(int i = 0; i < 4; i++){
				next_row = Q.front().row + diff_row[i];
				next_col = Q.front().col + diff_col[i];

				if((next_row < 0 || next_row >= H || next_col < 0 || next_col >= W) || visited[next_row][next_col] == true)continue;

				if(table_1[next_row][next_col] <= Q.front().max_level){
					visited[next_row][next_col] = true;
					visited_num++;
					ruisekiwa_1[Q.front().max_level_index]++;
					Q.push(Info(next_row,next_col,Q.front().max_level,Q.front().max_level_index));
				}else if(table_1[next_row][next_col] > Q.front().max_level && pushed[next_row][next_col] == false){
					pushed[next_row][next_col] = true;
					cannot_Q.push(Data(next_row,next_col,table_1[next_row][next_col]));
				}
			}
			Q.pop();
		}

		if(visited_num == limit)break;

		next_level = cannot_Q.top().level;
		next_index = index_map[next_level];

		while(!cannot_Q.empty()){
			if(cannot_Q.top().level > next_level)break;
			visited[cannot_Q.top().row][cannot_Q.top().col] = true;
			visited_num++;
			ruisekiwa_1[next_index]++;
			Q.push(Info(cannot_Q.top().row,cannot_Q.top().col,next_level,next_index));
			cannot_Q.pop();
		}
	}

	for(int i = 1; i < second_V.size(); i++){
		ruisekiwa_1[i] += ruisekiwa_1[i-1];
	}


	int W_2,H_2;
	scanf("%d %d %d %d",&W_2,&H_2,&start_col,&start_row);
	start_row--;
	start_col--;

	int table_2[H_2][W_2];

	vector<int> first_V2;
	first_V2.push_back(0);

	for(int row = 0; row < H_2; row++){
		for(int col = 0; col < W_2; col++){
			scanf("%d",&table_2[row][col]);
			first_V2.push_back(table_2[row][col]);
		}
	}

	sort(first_V2.begin(),first_V2.end());

	pre  = -1;

	vector<int> second_V2;

	for(int i = 0; i < first_V2.size(); i++){
		if(pre != first_V2[i]){
			second_V2.push_back(first_V2[i]);
		}
		pre = first_V2[i];
	}

	map<int, int> index_map2;

	for(int i = 0; i < second_V2.size(); i++){
		index_map2[second_V2[i]] = i;
	}

	int ruisekiwa_2[second_V2.size()];

	for(int i = 0; i < second_V2.size(); i++){
		ruisekiwa_2[i] = 0;
	}

	queue<Info> Q2;

	bool visited2[H_2][W_2];
	bool pushed2[H_2][W_2];

	for(int row = 0; row < H_2; row++){
		for(int col = 0; col < W_2; col++){
			visited2[row][col] = false;
			pushed2[row][col] = false;
		}
	}

	visited2[start_row][start_col] = true;
	ruisekiwa_2[1] = 1;

	Q2.push(Info(start_row,start_col,1,1));
	int visited_num2 = 1;
	int limit2 = H_2*W_2;

	priority_queue<Data> cannot_Q2;

	while(visited_num2 < limit2){

		next_level = BIG_NUM;

		while(!Q2.empty()){

			for(int i = 0; i < 4; i++){
				next_row = Q2.front().row + diff_row[i];
				next_col = Q2.front().col + diff_col[i];

				if((next_row < 0 || next_row >= H_2 || next_col < 0 || next_col >= W_2) || visited2[next_row][next_col] == true)continue;

				if(table_2[next_row][next_col] <= Q2.front().max_level){
					visited2[next_row][next_col] = true;
					visited_num2++;
					ruisekiwa_2[Q2.front().max_level_index]++;
					Q2.push(Info(next_row,next_col,Q2.front().max_level,Q2.front().max_level_index));
				}else if(pushed2[next_row][next_col] == false){
					pushed2[next_row][next_col] = true;
					cannot_Q2.push(Data(next_row,next_col,table_2[next_row][next_col]));
				}
			}
			Q2.pop();
		}

		if(visited_num2 == limit)break;

		next_level = cannot_Q2.top().level;
		next_index = index_map2[next_level];

		while(!cannot_Q2.empty()){
			if(cannot_Q2.top().level > next_level)break;
			visited2[cannot_Q2.top().row][cannot_Q2.top().col] = true;
			visited_num2++;
			ruisekiwa_2[next_index]++;
			Q2.push(Info(cannot_Q2.top().row,cannot_Q2.top().col,next_level,next_index));
			cannot_Q2.pop();
		}
	}

	for(int i = 1; i < second_V2.size(); i++){
		ruisekiwa_2[i] += ruisekiwa_2[i-1];
	}

	int ans = BIG_NUM;
	int tmp1,tmp2,left,right,m;

	for(int i = 0; i < second_V.size(); i++){
		tmp1 = ruisekiwa_1[i];

		if(tmp1 >= R){
			ans = min(ans,second_V[i]);
			break;
		}

		left = 0,right = second_V2.size()-1,m = (right+left)/2;

		while(left <= right){

			if(ruisekiwa_2[m]+tmp1 >= R){
				ans = min(ans,second_V[i]+second_V2[m]);
				right = m-1;
			}else{
				left = m+1;
			}
			m = (left+right)/2;
		}
	}

	printf("%d\n",ans);
}


int main(){

	while(true){
		scanf("%d",&R);
		if(R == 0)break;

		func();
	}

	return 0;
}

Measured memory_bytes: 35872