#include <iostream>
#include <fstream>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <string>
#include <tuple>
#include <vector>
#include <map>
#include <unordered_map>
#include <list>
#include <set>
#include <stack>
#include <queue>
#include <cstdlib>
#include <algorithm>
#include <random>
#include <cassert>
using namespace std;
#define LL long long
#define MP(a, b) make_pair(a, b)
#define MMP(a, b, c) make_pair(make_pair(a, b), c)
#define MAX 1000000000
#undef INT_MIN
#undef INT_MAX
#define INT_MIN -2147483647
#define INT_MAX 2147483647
#define LL_MIN (LL)-9223372036854775807
#define LL_MAX (LL)9223372036854775807
#define PI 3.14159265359

int main(){
    ios::sync_with_stdio(false);

    START:

    int R;
    cin >> R;
    if(R == 0) return 0;

    int W1, H1, X1, Y1;
    cin >> W1 >> H1 >> X1 >> Y1;
    X1--; Y1--;
    int room1[500][500];
    vector<pair<int,pair<int,int> > > level1;
    for(int i=0; i<H1; i++){
        for(int j=0; j<W1; j++){
            cin >> room1[i][j];
            level1.push_back(MP(room1[i][j], MP(i,j)));
        }
    }
    sort(level1.begin(), level1.end());
    vector<pair<int, int> > ans1;
    ans1.push_back(MP(0, 0));
    bool already1[500][500] = {};
    queue<pair<int,int> > que;
    int tmp = 0;
    for(int i=0; i<level1.size(); i++){
        int y = level1[i].second.first;
        int x = level1[i].second.second;
        if(y == Y1 && x == X1){
            que.push(MP(Y1, X1));
            already1[Y1][X1] = true;
            tmp++;
        }
        else if((y-1>=0 && already1[y-1][x]) || (y+1<H1 && already1[y+1][x])
        || (x-1>=0 && already1[y][x-1]) || (x+1<W1 && already1[y][x+1]) ){
            que.push(MP(y, x));
            already1[y][x] = true;
            tmp++;
        }
        if(i != level1.size()-1 && level1[i].first == level1[i+1].first) continue;

        while(!que.empty()){
            y = que.front().first;
            x = que.front().second;
            if(y-1>=0 && room1[y-1][x]<=level1[i].first && !already1[y-1][x]){
                que.push(MP(y-1, x));
                already1[y-1][x] = true;
                tmp++;
            }
            if(y+1<H1 && room1[y+1][x]<=level1[i].first && !already1[y+1][x]){
                que.push(MP(y+1, x));
                already1[y+1][x] = true;
                tmp++;
            }
            if(x-1>=0 && room1[y][x-1]<=level1[i].first && !already1[y][x-1]){
                que.push(MP(y, x-1));
                already1[y][x-1] = true;
                tmp++;
            }
            if(x+1<W1 && room1[y][x+1]<=level1[i].first && !already1[y][x+1]){
                que.push(MP(y, x+1));
                already1[y][x+1] = true;
                tmp++;
            }
            que.pop();
        }
        ans1.push_back(MP(tmp, level1[i].first));
        if(tmp >= R) while(!que.empty()) que.pop();
    }

    int ans = INT_MAX;
    auto itr = lower_bound(ans1.begin(), ans1.end(), MP(R,0));
    if(itr != ans1.end()) ans = itr->second;

    int W2, H2, X2, Y2;
    cin >> W2 >> H2 >> X2 >> Y2;
    X2--; Y2--;
    int room2[500][500];
    vector<pair<int,pair<int,int> > > level2;
    for(int i=0; i<H2; i++){
        for(int j=0; j<W2; j++){
            cin >> room2[i][j];
            level2.push_back(MP(room2[i][j], MP(i,j)));
        }
    }
    sort(level2.begin(), level2.end());
    bool already2[500][500] = {};
    tmp = 0;
    for(int i=0; i<level2.size(); i++){
        int y = level2[i].second.first;
        int x = level2[i].second.second;
        if(y == Y2 && x == X2){
            que.push(MP(Y2, X2));
            already2[Y2][X2] = true;
            tmp++;
        }
        else if((y-1>=0 && already2[y-1][x]) || (y+1<H2 && already2[y+1][x])
        || (x-1>=0 && already2[y][x-1]) || (x+1<W2 && already2[y][x+1]) ){
            que.push(MP(y, x));
            already2[y][x] = true;
            tmp++;
        }
        if(i != level2.size()-1 && level2[i].first == level2[i+1].first) continue;

        while(!que.empty()){
            y = que.front().first;
            x = que.front().second;
            if(y-1>=0 && room2[y-1][x]<=level2[i].first && !already2[y-1][x]){
                que.push(MP(y-1, x));
                already2[y-1][x] = true;
                tmp++;
            }
            if(y+1<H2 && room2[y+1][x]<=level2[i].first && !already2[y+1][x]){
                que.push(MP(y+1, x));
                already2[y+1][x] = true;
                tmp++;
            }
            if(x-1>=0 && room2[y][x-1]<=level2[i].first && !already2[y][x-1]){
                que.push(MP(y, x-1));
                already2[y][x-1] = true;
                tmp++;
            }
            if(x+1<W2 && room2[y][x+1]<=level2[i].first && !already2[y][x+1]){
                que.push(MP(y, x+1));
                already2[y][x+1] = true;
                tmp++;
            }
            que.pop();
        }
        itr = lower_bound(ans1.begin(), ans1.end(), MP(R-tmp,0));
        if(itr != ans1.end()) ans = min(ans, itr->second + level2[i].first);
        if(tmp >= R) while(!que.empty()) que.pop();
    }

    cout << ans << endl;

    goto START;

    return 0;
}


Measured memory_bytes: 14320