#include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)n; ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cout<<*i<<" "; cout<<endl; }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int R;
int W[2], H[2], X[2], Y[2];
int grid[500][500][2];
bool used[500][500];
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
/*
int count(int B, int idx){
  if(grid[Y[idx]][X[idx]][idx] > B) return 0;
  queue<int> qx, qy;
  qx.push(X[idx]);
  qy.push(Y[idx]);
  bool used[500][500] = {};
  used[Y[idx]][X[idx]] = true;
  int res = 1;
  while(!qx.empty()){
    int x = qx.front(), y = qy.front();
    qx.pop(), qy.pop();
    REP(r, 4){
      int nx = x + dx[r];
      int ny = y + dy[r];
      if(nx >= 0 && nx < W[idx] && ny >= 0 && ny < H[idx] && grid[ny][nx][idx] <= B && !used[ny][nx]){
        used[ny][nx] = true;
        res++;
        qx.push(nx), qy.push(ny);
      }
    }
  }
  return res;
}
*/
typedef pair<int, int> P;
struct S{
  P p;
  int d;
  S() {}
  S(P p, int d) : p(p), d(d) {}
  bool operator < (const S& s) const {
    return d > s.d;
  }
};
int get_index(vector<int>& v, int n){
  return (lower_bound(v.begin(), v.end(), n) - v.begin());
}

int main(){
  while(cin>>R && R){
    vector<int> cand[2];
    REP(i, 2){
      cin>>W[i]>>H[i]>>X[i]>>Y[i];
      X[i]--; Y[i]--;
      REP(y, H[i])REP(x, W[i]){
        cin>>grid[y][x][i];
        cand[i].push_back(grid[y][x][i]);
      }
    }
    REP(i, 2){
      sort(cand[i].begin(), cand[i].end());
      cand[i].erase(unique(cand[i].begin(), cand[i].end()), cand[i].end());
    }
    vector<int> count[2];
    REP(i, 2)count[i] = vector<int>(cand[i].size());
    REP(i, 2){
      int memo[500][500] = {};
      REP(y, H[i])REP(x, W[i]) memo[y][x] = INF;
      priority_queue<S> que;
      que.push(S(P(X[i], Y[i]), grid[Y[i]][X[i]][i]));
      memo[Y[i]][X[i]] = grid[Y[i]][X[i]][i];
      while(!que.empty()){
        S s = que.top(); que.pop();
        int x = s.p.first, y = s.p.second;
        if(memo[y][x] < s.d) continue;
        REP(r, 4){
          int nx = x + dx[r], ny = y + dy[r];
          if(nx >= 0 && nx < W[i] && ny >= 0 && ny < H[i]){
            int next_d = max(grid[ny][nx][i], s.d);
            if(next_d >= memo[ny][nx]) continue;
            memo[ny][nx] = next_d;
            que.push(S(P(nx, ny), next_d));
          }
        }
      }
      REP(y, H[i])REP(x, W[i]) count[i][get_index(cand[i], memo[y][x])] ++;
    }
    vector<int> sum[2];
    REP(i, 2){
      sum[i] = vector<int>(cand[i].size() + 1);
      REP(j, cand[i].size()) sum[i][j + 1] = sum[i][j] + count[i][j];
    }
    int ans = INF;
    REP(i, cand[0].size() + 1){
      int rest = R - sum[0][i];
      int j = get_index(sum[1], rest);
      ans = min(ans, ((i != 0) ? cand[0][i - 1] : 0) + ((j == 0) ? 0 : (j == cand[1].size() + 1) ? INF : cand[1][j - 1]));
    }
    cout<<ans<<endl;
  }
  return 0;
}

Measured memory_bytes: 10908