#include
#include
#include
#include
#include
#include
using namespace std;
struct node {
int year, idx, x, y;
bool ok;
node () {}
node(int _year, int _idx, int _x, int _y, bool _ok) {
year = _year;
idx = _idx;
x = _x;
y = _y;
ok = _ok;
}
bool operator < (const node &tmp) const {
if(year == tmp.year) {
return ok > tmp.ok;
}
return year < tmp.year;
}
};
const int maxn = 1e5 + 10;
int mat[333][333];
bool exploited[333][333];
int root[maxn];
int sz[maxn];
void init() {
for(int i = 0; i < maxn; i++) {
root[i] = i;
sz[i] = 1;
}
}
int find_root(int x) {
while(root[x] != x) {
root[x] = root[root[x]];
x = root[x];
}
return x;
}
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];
root[root_a] = root[root_b];
}
else {
sz[root_a] += sz[root_b];
root[root_b] = root[root_a];
}
}
}
int main()
{
init();
int n;
cin >> n;
vector years(n);
vector v;
for(int i = 0; i < n; i++) {
cin >> years[i];
v.push_back(node(years[i], i, -1, -1, false));
}
vector result(n);
int r, c;
cin >> r >> c;
for(int i = 0; i < r; i++) {
for(int j = 0; j < c; j++) {
cin >> mat[i][j];
v.push_back(node(mat[i][j], -1, i, j, true));
}
}
memset(exploited, false, sizeof exploited);
sort(v.begin(), v.end());
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].ok == false) {
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 k = 0; k < 4; k++){
int ti = pos_i + di[k];
int tj = pos_j + dj[k];
if(ti >= 0 and tj >= 0 and ti < r and tj < c and exploited[ti][tj] == true) {
int A = pos_i * c + pos_j;
int B = ti * c + tj;
if(find_root(A) != find_root(B)) {
oblasti--;
}
unite(A, B);
}
}
}
}
for(int i = 0; i < n; i++) {
cout << result[i] << endl;
}
return 0;
}
/*
2013 2015 2023 2018 2023 2019
2013 2023 2015 2013 2021 2025
2015 2013 2022 2016 2015 2015
2013 2015 2020 2020 2015 2013
**/