#include <bits/stdc++.h>
#define err(args...) {}
#ifdef DEBUG
#include "_debug.cpp"
#endif
using namespace std;
using ll = long long;
using ld = long double;
template <typename T> using lim = numeric_limits<T>;
template <typename T> istream& operator>>(istream& is, vector<T>& a) { for(T& x : a) { is >> x; } return is; }
template <typename Iter, typename T> int gt(Iter L, Iter R, T v) { return upper_bound(L, R, v) - L; }
template <typename Iter, typename T> int ge(Iter L, Iter R, T v) { return lower_bound(L, R, v) - L; }
template <typename Iter, typename T> int lt(Iter L, Iter R, T v) { return lower_bound(L, R, v) - L - 1; }
template <typename Iter, typename T> int le(Iter L, Iter R, T v) { return upper_bound(L, R, v) - L - 1; }
template <typename Bst, typename T> typename Bst::const_iterator gt(const Bst& bst, T v) { return bst.upper_bound(v); }
template <typename Bst, typename T> typename Bst::const_iterator ge(const Bst& bst, T v) { return bst.lower_bound(v); }
template <typename Bst, typename T> typename Bst::const_iterator lt(const Bst& bst, T v) { return bst.lower_bound(v) == bst.begin() ? bst.end() : --bst.lower_bound(v); }
template <typename Bst, typename T> typename Bst::const_iterator le(const Bst& bst, T v) { return bst.upper_bound(v) == bst.begin() ? bst.end() : --bst.upper_bound(v); }
const int N = 500;
int g[N][N], vis[N][N];
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
vector<int> solve_grid() {
    int w, h, x, y;
    cin >> w >> h >> x >> y;
    for(int i = 0; i < h; i++) {
        for(int j = 0; j < w; j++) {
            cin >> g[i][j];
            vis[i][j] = false;
        }
    }
    vector<int> cost(h * w + 1);
    priority_queue<tuple<int, int, int>> pq({}, {make_tuple(-1, y - 1, x - 1)});
    vis[y - 1][x - 1] = true;
    for(int component_size = 1; not pq.empty(); component_size++) {
        int val, y, x;
        tie(val, y, x) = pq.top();
        pq.pop();
        cost[component_size] = max(cost[component_size - 1], -val);
        for(int d = 0; d < 4; d++) {
            int ny = y + dy[d], nx = x + dx[d];
            if(0 <= ny and ny < h and 0 <= nx and nx < w and not vis[ny][nx]) {
                pq.push(make_tuple(-g[ny][nx], ny, nx));
                vis[ny][nx] = true;
            }
        }
    }
    return cost;
}
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int r;
    while(cin >> r and r) {
        auto cost1 = solve_grid();
        auto cost2 = solve_grid();
        int ans = lim<int>::max();
        for(int r1 = 0; r1 <= r; r1++) {
            if(r1 < cost1.size() and r - r1 < cost2.size()) {
                ans = min(ans, cost1[r1] + cost2[r - r1]);
            }
        }
        cout << ans << endl;
    }
    return 0;
}

