#include <bits/stdc++.h>
#define N (int) 3e5
using namespace std;
int n;
int a[N];
struct Edge {
	int v, nxt;
} edge[N<<1];
int fst[N], ecnt;
void add_edge (int u, int v) {
	edge[ecnt].v = v, edge[ecnt].nxt = fst[u], fst[u] = ecnt ++;
}
void init_e () {
	memset (fst, -1, sizeof (fst));
}

struct Sgtree {
	int mx[N<<2];
	int rt;
	int lson[N<<2], rson[N<<2], size;
	void update (int & id, int l, int r, int pos, int val) {
		if (! id) id = ++ size;
		if (l == pos && l == r) {
			mx[id] = val;
			return ;
		}
		int mid = l + r >> 1;
		if (pos <= mid) update (lson[id], l, mid, pos, val);
		else update (rson[id], mid+1, r, pos, val);
		mx[id] = max (mx[rson[id]], mx[lson[id]]);
	}
	int query (int & id, int l, int r, int L, int R) {
		if (! id) id = ++ size;
//		cout << l << " " << r << " " << L << " " << R << endl;
//		system ("pause");
		if (L <= l && r <= R) return mx[id];
		int mid = l + r >> 1, ret = 0;
		if (L <= mid) ret = max (ret, query (lson[id], l, mid, L, R));
		if (R > mid) ret = max (ret, query (rson[id], mid+1, r, L, R));
		return ret;
	}
	Sgtree () {
		rt = 1;
		memset (mx, 0, sizeof (mx));
		memset (lson, 0, sizeof (lson));
		memset (rson, 0, sizeof (rson));
		size = 1;
	}
} sgtree;

struct Node {
	int fth, sz, wson, top;
	Node () {
		fth = wson = top = 0;
		sz = 1;
	}
} node[N];
void dfs1 (int u, int f) {
	int mx = 0;
	for (int e = fst[u]; e != -1; e = edge[e].nxt) {
		int v = edge[e].v;
		if (v == f) continue;
		node[v].fth = u;
		dfs1 (v, u);
		node[u].sz += node[v].sz;
		if (node[v].sz > mx) mx = node[v].sz, node[u].wson = v;
	}
}
int tot;
int ID[N];
void dfs2 (int u, int f, int t) {
	ID[u] = ++ tot;
	node[u].top = t;
	if (! node[u].wson) return ;
	dfs2 (node[u].wson, u, t);
	for (int e = fst[u]; e != -1; e = edge[e].nxt) {
		int v = edge[e].v;
		if (v == f || v == node[u].wson) continue;
		dfs2 (v, u, v);
	}
}
int Query (int u) {
	int ret = 0;
	while (u) {
		ret = max (ret, sgtree.query (sgtree.rt, 1, n, ID[node[u].top], ID[u]));
//		cout << node[u].top << " " << u << " " << ret << endl;
		u = node[node[u].top].fth;
	}
	return ret;
}

pair <int, int> b[N];

bool cmp (const pair <int, int> & x, const pair <int, int> & y) {
	return x.first < y.first;
}

int dp[N];

void dfs (int u, int f) {
	for (int e = fst[u]; e != -1; e = edge[e].nxt) {
		int v = edge[e].v;
		if (v == f) continue;
		dp[v] = max (dp[v], dp[u]);
		dfs (v, u);
	}
}

int main () {
	init_e ();
	
	cin >> n;
	for (int i = 1; i <= n; i ++) cin >> a[i];
	for (int i = 1; i < n; i ++) {
		int u, v;
		cin >> u >> v;
		add_edge (u, v), add_edge (v, u);
	}
	
	dfs1 (1, 0);
	dfs2 (1, 0, 1);
	
	
	for (int i = 1; i <= n; i ++) b[i] = make_pair (a[i], i);
	
	sort (b+1, b+n+1, cmp);
	
//	for (int i = 1; i <= n; i ++) cout << b[i].first << " " << b[i].second << endl;
	
	for (int i = 1; i <= n;) {
		int j = i;
		while (b[j].first == b[i].first) {
			dp[b[j].second] = Query (b[j].second) + 1;
//			cout << b[j].second << " " << dp[b[j].second] << endl;
			j ++;
		}
		j = i;
		while (b[j].first == b[i].first) {
			sgtree.update (sgtree.rt, 1, n, ID[b[j].second], dp[b[j].second]);
//			cout << sgtree.query (sgtree.rt, 1, n, ID[b[j].second], ID[b[j].second]) << " ";
			j ++;
		}
//		cout << endl;
		i = j;
//		cout << i << endl;
	}
	
	dfs (1, 0);
	
	for (int i = 1; i <= n; i ++) cout << dp[i] << endl;
	
	return 0;
}

Measured memory_bytes: 45668