#include
#include
#include
#include
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 v;
int k;
cin >> k;
vector 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 > mat(n, vector(m));
vector > exploited(n, vector(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 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;
}