#include <bits/stdc++.h>

using namespace std;
using ll = long long;
#define int ll
using PII = pair<int, int>;
template <typename T> using V = vector<T>;
template <typename T> using VV = vector<V<T>>;
template <typename T> using VVV = vector<VV<T>>;

#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()
#define PB push_back

const ll INF = (1LL<<60);
const int MOD = 1000000007;

template <typename T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <typename T> T &chmax(T &a, const T &b) { return a = max(a, b); }
template <typename T> bool IN(T a, T b, T x) { return a<=x&&x<b; }
template<typename T> T ceil(T a, T b) { return a/b + !!(a%b); }
template<class S,class T>
ostream &operator <<(ostream& out,const pair<S,T>& a){
  out<<'('<<a.first<<','<<a.second<<')';
  return out;
}
template<class T>
ostream &operator <<(ostream& out,const vector<T>& a){
  out<<'[';
  REP(i, a.size()) {out<<a[i];if(i!=a.size()-1)out<<',';}
  out<<']';
  return out;
}

int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};

class UnionFind {
public:
  const static int MAX_N = 250010;
  int par[MAX_N];
  int s[MAX_N];
  UnionFind() { init(); }
  UnionFind(int n) { init(n); }
  void init() { for(int i=0; i<MAX_N; ++i) par[i] = i, s[i] = 1; }
  void init(int n) { for(int i=0; i<n; ++i) par[i] = i, s[i] = 1; }
  int find(int x) {
    if(par[x] == x) return x;
    return par[x] = find(par[x]);
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if(x == y) return;
    if(s[x] < s[y]) par[x] = y, s[y] = s[x] + s[y];
    else par[y] = x, s[x] = s[x] + s[y];
  }
  bool same(int x, int y) { return find(x) == find(y);}
};
UnionFind uf;

signed main(void)
{
  cin.tie(0);
  ios::sync_with_stdio(false);

  while(1) {
    int r;
    cin >> r;
    if(!r) break;
    int h, w, x, y;
    VV<int> a;

    auto func = [&]() -> V<int> {
      V<int> v;
      REP(i, h) REP(j, w) v.PB(a[i][j]);
      sort(ALL(v));
      v.erase(unique(ALL(v)), v.end());

      // cout << v << endl;

      VV<int> g2(v.size());
      REP(i, h) REP(j, w) {
        g2[lower_bound(ALL(v), a[i][j]) - v.begin()].PB(i*w+j);
      }

      // REP(i, v.size()) {
      //   cout << i << "," << g2[i] << endl;
      // }

      VV<int> g(h*w);
      REP(i, h) REP(j, w) {
        REP(k, 4) {
          int nx = j + dx[k], ny = i + dy[k];
          if(IN(0LL,w,nx) && IN(0LL,h,ny) && a[i][j]>=a[ny][nx]) {
            g[i*w+j].PB(ny*w+nx);
            // cout << i << "," << j << " " << ny << "," << nx << endl;
            // cout << i*w+j << " " << ny*w+nx << endl;
          }
        }
      }

      // b[i] = (部屋をi個訪れるときに必要な最小の認証レベル)
      V<int> b(h*w+1, INF);
      b[0] = 0, b[1] = 1;
      uf.init(h*w);
      REP(i, v.size()) {
        // cout << "i=" << i << " " << v[i] << endl;
        for(auto j: g2[i]) {
          for(auto k: g[j]) {
            // cout << j << "," << k << endl;
            uf.unite(j, k);
          }
        }
        chmin(b[uf.s[uf.find(y*w+x)]], v[i]);
      }
      return b;
    };

    cin >> w >> h >> x >> y, x--, y--;
    a = VV<int>(h, V<int>(w));
    REP(i, h) REP(j, w) cin >> a[i][j];
    V<int> p = func();
    for(int i=p.size()-2; i>=0; --i) {
      chmin(p[i], p[i+1]);
    }
    // cout << p << endl;

    cin >> w >> h >> x >> y, x--, y--;
    a = VV<int>(h, V<int>(w));
    REP(i, h) REP(j, w) cin >> a[i][j];
    V<int> q = func();
    for(int i=q.size()-2; i>=0; --i) {
      chmin(q[i], q[i+1]);
    }
    // cout << q << endl;

    int ret = INF;
    REP(i, r+1) {
      if(!IN(0LL,(int)p.size(),i) || !IN(0LL,(int)q.size(),r-i)) continue;
      chmin(ret, p[i]+q[r-i]);
      // cout << ret << " " << p[i] << " " << q[r-i] << endl;
    }
    cout << ret << endl;
  }

  return 0;
}

