#include <iostream>
#include <vector>
#include <limits.h>
#include <algorithm>
#include <string>
#include <math.h>
#include <limits.h>
#include <queue>
#include <map>
#include <set>
#include <iomanip>
#include <bitset>
#include <cassert>
#include <random>
#include <functional>
#include <stack>
#include <iomanip>
#include <cassert>
//#include <boost/multiprecision/cpp_int.hpp>
#include <complex>
#include <cstdio>
#include <list>
#include <bitset>

//< in.txt > out.txt
using namespace std;
//std::ios::sync_with_stdio(false);
//std::cin.tie(0);
const long long MOD = 1e9 + 7;
const long long INF = 1e18;
typedef long long LL;
typedef long double LD;
typedef pair<LL, LL> PLL;
typedef pair<LD, LL> pdl;
typedef pair<LD, LD> pdd;
typedef vector<LL> VLL;
typedef vector<VLL> VVLL;
typedef unsigned long long ULL;
//typedef boost::multiprecision::cpp_int bigint;

template<class T>
struct Gedge {
	LL src, to;
	T cost;
	Gedge(LL s, LL t, T c) :src(s), to(t), cost(c) {}
	Gedge(LL t, T c) :src(-1), to(t), cost(c) {}
};

template<class T>
using WeightedGraph = vector<vector<Gedge<T>>>;
using UnweightedGraph = vector<vector<LL>>;
template<class T>
using Gedges = vector<Gedge<T>>;

struct TNode {
	LL parent;
	VLL childs;
	TNode() :parent(-1) {};
};
using Tree = vector<TNode>;

class HLD {
public:
	Tree& tree;
	LL V;
	VLL depth;   //各頂点が属するHeavy集合の深さ
	VLL top;   //各頂点が属するHeavy集合の一番上の頂点
	VLL in;   //各頂点がEuler-Tourでどこにいるか
	VLL out;   //各頂点の部分木の終わり
	HLD(Tree& t, LL root = 0) :tree(t) {
		V = t.size();
		VLL subtrees(V, -1);
		//各部分木のサイズを求める
		{
			stack<LL> order;
			stack<LL> hold;
			hold.push(root);
			while (!hold.empty()) {
				LL cur = hold.top();
				hold.pop();
				order.push(cur);
				for (LL ch : tree[cur].childs) {
					hold.push(ch);
				}
			}
			while (!order.empty()) {
				LL cur = order.top();
				order.pop();
				subtrees[cur] = 1;
				for (LL& ch : tree[cur].childs) {
					subtrees[cur] += subtrees[ch];
					if (subtrees[ch] > subtrees[tree[cur].childs[0]]) {
						swap(ch, tree[cur].childs[0]);
					}
				}
			}
		}
		//HL分解 with eulertour
		{
			in.resize(V);
			out.resize(V);
			depth.resize(V);
			top.resize(V);
			LL cur = root;
			LL nextid = 0;
			dfs(cur, nextid);
		}
	}
	void dfs(LL cur, LL& nextind) {
		in[cur] = nextind++;
		for (auto ch : tree[cur].childs) {
			//0番目の子は同じHeavy集合
			if (ch == tree[cur].childs[0]) {
				top[ch] = top[cur];
				depth[ch] = depth[cur];
			}
			//それ以外は新しいHeavy集合
			else {
				top[ch] = ch;
				depth[ch] = depth[cur] + 1;
			}
			dfs(ch, nextind);
		}
		out[cur] = nextind - 1;
	}
	LL LCA(LL u, LL v) {
		//uの属するnode.depth >= vの属するnode.depthにする
		if (depth[u] < depth[v]) {
			swap(u, v);
		}
		while (depth[u] > depth[v]) {
			u = tree[top[u]].parent;
		}
		while (top[u] != top[v]) {
			u = tree[top[u]].parent;
			v = tree[top[v]].parent;
		}
		if (in[u] > in[v])return v;
		else return u;
	}
};

void SetTree(UnweightedGraph& G, Tree& T, LL root = 0) {
	T.resize(G.size());
	stack<PLL> st;
	st.push(PLL(root, -1));
	while (!st.empty()) {
		LL cur = st.top().first;
		LL p = st.top().second;
		st.pop();
		T[cur].parent = p;
		for (LL ch : G[cur]) {
			if (ch == p)continue;
			T[cur].childs.push_back(ch);
			st.push(PLL(ch, cur));
		}
	}
}

template<class T>
class Segtree {
private:
	vector<T> seg;
	LL RN;
	typedef function<T(T, T)> TT;
	TT f;
	T te;
public:
	Segtree(LL N, TT _f, T e) :te(e) {
		RN = 1;
		while (RN < N)RN *= 2;
		seg.resize(2 * RN, te);
		f = _f;
	}
	Segtree(vector<T>& V, TT _f, T e) :te(e) {
		LL N = V.size();
		RN = 1;
		while (RN < N)RN *= 2;
		seg.resize(2 * RN, te);
		f = _f;
		for (LL n = 0; n < N; n++) seg[RN + n] = V[n];
		for (LL k = RN - 1; k >= 1; k--) {
			seg[k] = f(seg[2 * k], seg[2 * k + 1]);
		}
	}
	//set n-th as x(0 index!!!!!)
	void set(LL n, T x) {
		seg[RN + n] = x;
		n = (RN + n) / 2;
		while (n >= 1) {
			seg[n] = f(seg[2 * n], seg[2 * n + 1]);
			n /= 2;
		}
	}
	//change n-th number p to x*p(0 index!!!!!)
	void addl(LL n, T x) {
		seg[RN + n] = f(x, seg[RN + n]);
		n = (RN + n) / 2;
		while (n >= 1) {
			seg[n] = f(seg[2 * n], seg[2 * n + 1]);
			n /= 2;
		}
	}
	//change n-th number p to p*x(0 index!!!!!)
	void addr(LL n, T x) {
		seg[RN + n] = f(seg[RN + n], x);
		n = (RN + n) / 2;
		while (n >= 1) {
			seg[n] = f(seg[2 * n], seg[2 * n + 1]);
			n /= 2;
		}
	}
	//get [l,r] (0 index!!!!!)
	T get(LL l, LL r) {
		T ansl = te, ansr = te;
		r++;
		l += RN;
		r += RN;
		while (l < r) {
			if (l & 1) {
				ansl = f(ansl, seg[l]);
				l++;
			}
			if (r & 1) {
				r--;
				ansr = f(seg[r], ansr);
			}
			l >>= 1;
			r >>= 1;
		}
		return f(ansl, ansr);
	}
	//get n-th number(0 index!!!!!)
	T get(LL n) {
		return seg[RN + n];
	}
	T operator[](LL n) {
		return seg[RN + n];
	}
};

VLL depth;
Tree T;

void bfs(LL n) {
	for (LL ch : T[n].childs) {
		depth[ch] = depth[n] + 1;
		bfs(ch);
	}
}

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	LL N;
	cin >> N;
	vector<PLL> A(N);
	for (LL n = 0; n < N; n++) {
		cin >> A[n].first;
		A[n].second = n;
	}
	UnweightedGraph G(N);
	for (LL n = 0; n < N - 1; n++) {
		LL a, b;
		cin >> a >> b;
		a--; b--;
		G[a].push_back(b);
		G[b].push_back(a);
	}
	SetTree(G, T, 0);
	HLD hld(T, 0);
	Segtree<LL> seg(N, [](LL a, LL b) {
		return max(a,b);
	}, (LL)0);
	depth.resize(N, 0);
	bfs(0);
	sort(A.begin(), A.end(), [&](PLL a, PLL b) {
		if (a.first != b.first)return a.first < b.first;
		return depth[a.second] > depth[b.second];
	});
	VLL ans(N);
	for (PLL vertex : A) {
		LL n = vertex.second;
		LL temp = 0;
		while (n != -1) {
			LL eind = hld.in[n];
			LL top = hld.top[n];
			LL topind = hld.in[top];
			temp = max(temp,seg.get(topind, eind));
			n = T[top].parent;
		}
		LL eind = hld.in[vertex.second];
		seg.set(eind, temp+1);
		ans[vertex.second] = temp + 1;
	}
	for (LL n = 0; n < N; n++) {
		LL ans = 0;
		LL cur = n;
		while (cur != -1) {
			LL eind = hld.in[cur];
			LL top = hld.top[cur];
			LL topind = hld.in[top];
			ans = max(ans, seg.get(topind, eind));
			cur= T[top].parent;
		}
		cout << ans << "\n";
	}
	return 0;
}


Measured memory_bytes: 54356