#include <iostream>
#include <fstream>
#include <algorithm>
#include <iomanip>
#include <random>
#include <ctime>
#include <bitset>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <cmath>
#include <cstring>
#include <queue>
#include <deque>
#include <stack>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define ld long double
#define ull unsigned long long
#define ll long long
#define pb push_back
#define pii pair<int, int>
#define pll pair<ll, ll>
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define fast_io cout.tie(0), cin.tie(0), ios_base::sync_with_stdio(0)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
using namespace std;
//using namespace __gnu_pbds;
//typedef tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
ld eps = (ld)1 / 1e9;
ll inf = 1e18, mod2 = 998244353, mod1 = 1e9 + 7;
ll sqr(ll a) { return a * a; }
ll qb(ll a) { return a * a * a; }
ll gcd(ll a, ll b) { return !a ? b : gcd(b % a, a); }
ll binpow(ll a, ll b, ll mod) { return b ? (b % 2 ? (a * (sqr(binpow(a, b / 2, mod)) % mod)) % mod : sqr(binpow(a, b / 2, mod)) % mod) : 1; }
ll binmult(ll a, ll b, ll mod) { return b ? (b % 2 ? (2 * binmult(a, b / 2, mod) + a) % mod : (2 * binmult(a, b / 2, mod)) % mod) : 0; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct str { int zn; vector<pii> vc; };
str DO[800004];
int n, a[200001], ans[200001], maxx[200001];
vector<int> gr[200001];
map<int, int> mp;
void update(int l, int r, int ind, int v, int now, bool tp)
{
    if (l == r)
    {
        if (DO[v].vc.empty()) DO[v].vc.pb({0, 0});
        if (tp) DO[v].vc.pb({now, max(now, DO[v].vc.back().second)});
        else DO[v].vc.pop_back();
        DO[v].zn = DO[v].vc.back().second;
        return;
    }
    ll m = (l + r) / 2;
    if (ind <= m) update(l, m, ind, 2 * v, now, tp);
    else update(m + 1, r, ind, 2 * v + 1, now, tp);
    DO[v].zn = max(DO[2 * v].zn, DO[2 * v + 1].zn);
}
int get(int l, int r, int tl, int tr, int v)
{
    if (l == tl && r == tr) return DO[v].zn;
    if (l > r || tl > tr) return 0;
    int m = (l + r) / 2;
    if (tr <= m) return get(l, m, tl, tr, 2 * v);
    else if (tl > m) return get(m + 1, r, tl, tr, 2 * v + 1);
    else return max(get(l, m, tl, m, 2 * v), get(m + 1, r, m + 1, tr, 2 * v + 1));
}
void dfs(int v, int pr)
{
    int x = get(1, n, 1, a[v] - 1, 1);
    ans[v] = x + 1;
    maxx[v] = max(ans[v], maxx[pr]);
    update(1, n, a[v], 1, ans[v], 1);
    for (auto f: gr[v])
    {
        if (f == pr) continue;
        dfs(f, v);
    }
    update(1, n, a[v], 1, ans[v], 0);
}

int main()
{
    fast_io;
    int i, x, y, st = 1;
    cin >> n;
    for (i = 1; i <= n; i++)
    {
        cin >> a[i];
        mp.insert({a[i], 0});
    }
    for (auto f = mp.begin(); f != mp.end(); f++) f->second = st++;
    for (i = 1; i <= n; i++) a[i] = mp[a[i]];
    for (i = 1; i < n; i++)
    {
        cin >> x >> y;
        gr[x].pb(y);
        gr[y].pb(x);
    }
    dfs(1, 0);
    for (i = 1; i <= n; i++) cout << maxx[i] << '\n';
    return 0;
}

Measured memory_bytes: 65052