#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
 
using namespace __gnu_pbds;
using namespace std;
#define ll long long
#define hii cout << "hii" << endl
#define int ll
#define endl '\n'
#define all(s) s.begin(), s.end()
 
template <class T> ostream& operator << (ostream &os, const vector<T> &v) { for (T i : v) os << i << ' '; return os; }
template <class T> ostream& operator << (ostream &os, const set<T> &v) { for (T i : v) os << i << ' '; return os; }
template <class T, class S> ostream& operator << (ostream &os, const pair<T, S> &v) { os << v.first << ' ' << v.second; return os; }
template <class T, class S> ostream& operator << (ostream &os, const unordered_map<T, S> &v) { for (auto i : v) os << '(' << i.first << "=>" << i.second << ')' << ' '; return os; } 
 
 
#ifndef ONLINE_JUDGE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template <class Arg1> void __f(const char* name, Arg1&& arg1) { cerr << name << " : " << arg1 << endl; }
    template <class Arg1, class... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args) {
        const char* sep = strchr(names + 1, ',');
        cerr.write(names, sep - names) << " : " << arg1 << "  ";
        __f(sep + 1, args...);
    }
#else
#define trace(...) 0
#pragma GCC optimize ("O3")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("avx2,sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define _CRT_SECURE_NO_WARNINGS
#endif // ifndef ONLINE_JUDGE
 
 
const int N = 3e5 + 5;
const int MAXN = 1e5 + 5;
const int M = 1e5;
const int mod = 998244353;
const int MOD = 998244353;
const int INF = 1e15;
const int LG = 21;

int arr[N];
int query = 1;
int n;
vector<int> v[N];

class SegmentTree2
{
public:
	int N;
	vector<int> t;
	vector<int> lazy;
 
	SegmentTree2(int n)
	{
		N = n;
		t.resize(4 * n + 5, 0);
	}
 
	void build(int a[], int v, int tl, int tr) 
	{
	    if(tl == tr) 
	    {
	        t[v] = a[tl];
	    }
	    else 
	    {
	        int tm = (tl + tr) / 2;
	        build(a, v*2, tl, tm);
	        build(a, v*2+1, tm+1, tr);
	        t[v] = max(t[v*2] , t[v*2+1]);
	    }
	}
	void update(int v, int tl, int tr, int pos, int new_val) 
	{
		// trace(pos, new_val);
	    if (tl == tr) 
	    {
	        t[v] = new_val;
	    }
	    else 
	    {
	        int tm = (tl + tr) / 2;
	        if (pos <= tm)
	        {
	            update(v*2, tl, tm, pos, new_val);
	        }
	        else
	        {
	            update(v*2+1, tm+1, tr, pos, new_val);
	        }
	        t[v] = max(t[v*2], t[v*2+1]);
	     }
	}
 
	int sum(int v, int tl, int tr, int l, int r) 
	{
	    if (l > r) 
	        return 0;
	    if (l == tl && r == tr)
	    {
	        return t[v];
	    }
	    int tm = (tl + tr) / 2;
	    return max(sum(v*2, tl, tm, l, min(r, tm)), sum(v*2+1, tm+1, tr, max(l, tm+1), r));
	}
 
};

int DP[N];
int ret[N];
SegmentTree2 stree(N);

void dfs(int sv, int par)
{
	DP[sv] = 1 + stree.sum(1, 1, N, 1, arr[sv] - 1);
	int store = stree.sum(1, 1, N, arr[sv], arr[sv]);
	stree.update(1, 1, N, arr[sv], DP[sv]);
	for(int x : v[sv])
	{
		if(x == par)
		{
			continue;
		}
		dfs(x, sv);
	}
	stree.update(1, 1, N, arr[sv], store);
}

void dfs2(int sv, int par, int pass)
{
	ret[sv] = max(DP[sv], pass);
	for(int x : v[sv])
	{
		if(x == par)
		{
			continue;
		}
		dfs2(x, sv, ret[sv]);
	}
}

void solve() 
{
	cin >> n;
	map<int, int> mp;
	for(int i = 1; i <= n; i++)
	{
		cin >> arr[i];
		mp[arr[i]];
	}
	int ptr = 0;
	for(auto x : mp)
	{
		mp[x.first] = ++ptr;
	}
	for(int i = 1; i <= n; i++)
	{
		arr[i] = mp[arr[i]];
	}
	int t = n - 1;
	while(t--)
	{
		int a, b;
		cin >> a >> b;
		v[a].push_back(b);
		v[b].push_back(a);
	}
	dfs(1, 0);
	dfs2(1, 0, 0);
	for(int i = 1; i <= n; i++)
	{
		cout << ret[i] << endl;
	}
}



 
 
int32_t main() 
{	
    ios_base:: sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	    int t = 1;
	    // cin >> t;
	while(t--)solve();
	return 0;
}

Measured memory_bytes: 52552