#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 100005;
struct node {
    int year, idx, x, y;
    bool query;
    node() {}
    node(int _year, int _idx, int _x, int _y, bool _query) {
        year = _year;
        idx = _idx;
        x = _x;
        y = _y;
        query = _query;
    }
    bool operator < (const node &tmp) const {
        if(year == tmp.year) {
            return query < tmp.query;
        }
        return year < tmp.year;
    }
};
int parent[maxn], sz[maxn];

void init() {
    for(int i = 0; i < maxn; i++) {
        parent[i] = i;
        sz[i] = 1;
    }
}
int find_root(int x) {
    while(x != parent[x]) {
        parent[x] = parent[parent[x]];
        x = parent[x];
    }
    return x;
}
bool check(int A, int B) {
    return find_root(A) == find_root(B);
}
void unite(int A, int B) {
    int root_a = find_root(A);
    int root_b = find_root(B);
    
    if(root_a != root_b) {
        if(sz[root_a] < sz[root_b]) {
            sz[root_b] += sz[root_a];
            parent[root_a] = parent[root_b];
        }
        else {
            sz[root_a] += sz[root_b];
            parent[root_b] = parent[root_a];
        }
    }
}
int main() {
    ios_base::sync_with_stdio(false);
    init();
    vector<node> v;
    
    int k;
    cin >> k;
    vector<int> y(k);
    for(int i = 0; i < k; i++) {
        cin >> y[i];
        v.push_back(node(y[i], i, -1, -1, true));
    }
    int n, m;
    cin >> n >> m;
    vector<vector<int> > mat(n, vector<int>(m));
    vector<vector<bool> > exploited(n, vector<bool>(m, false));
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < m; j++) {
            cin >> mat[i][j];
            v.push_back(node(mat[i][j], -1, i, j, false));
        }
    }
    sort(v.begin(), v.end());
    
    vector<int> result(k);
    int oblasti = 0;
    int di[] = {-1, 1, 0, 0};
    int dj[] = {0, 0, -1, 1};
    for(int i = (int) v.size() - 1; i >= 0; i--) {
        if(v[i].query) {
            result[v[i].idx] = oblasti;
        }
        else {
            int pos_i = v[i].x;
            int pos_j = v[i].y;
            exploited[pos_i][pos_j] = true;
            oblasti++;
            
            for(int p = 0; p < 4; p++) {
                int ti = pos_i + di[p];
                int tj = pos_j + dj[p];
                if(ti >= 0 and ti < n and tj >= 0 and tj < m and exploited[ti][tj]) {
                    int A = ti * m + tj;
                    int B = pos_i * m + pos_j;
                    if(!check(A, B)) {
                        oblasti--;
                    }
                    unite(A, B);
                }
            }
        }
    }
    for(int i = 0; i < k; i++) {
        cout << result[i] << "\n";
    }
    return 0;
}
