/* Author: Rennan Rocha
 * Time: $%Y%$-$%M%$-$%D%$ $%h%$:$%m%$:$%s%$
**/

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define F first
#define S second
#define PB push_back
#define MP make_pair

#define ll long long
#define vi vector<int>
#define vll vector<ll>
#define pi pair<int,int>
#define pll pair<ll, ll>
#define vpi vector<pi>
#define vpll vector<pll>
#define LEFT(x) (x<<1)
#define RIGHT(x) (x<<1|1)

#define INF 1e18
#define MOD 1000000007

using namespace std;
//using namespace __gnu_pbds;

//typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
//*find_by_order(); order_of_key();

map<int,int> comp;
vi adj[200010];
ll a[200010];
ll tree[200010*4];
ll lazy[200010*4];
int ans[200010];
int n;

void doLazy(int i, int l, int r) {
    if(lazy[i] == INF) {
        tree[i] = INF;
        if(l != r) {
            lazy[LEFT(i)] = lazy[RIGHT(i)] = INF;
        }
        lazy[i] = 0;
    }
}

bool debug;

ll val_ant;

void update(int i, int l, int r, ll val, bool volta) {
    doLazy(i, l, r);
    if(debug) {
        //cout << "tree l:" << l << " r: " << r << " tval: " << tree[i] << " val: " << val << endl;
    }
    if(l == r) {
        if(volta) tree[i] = val_ant;
        else {
            val_ant = tree[i];
            tree[i] = val;
        }
    }else {
        int mid = (l+r)>>1;
        doLazy(RIGHT(i), mid+1, r);
        doLazy(LEFT(i), l, mid);
        if(tree[LEFT(i)] < val)
            update(RIGHT(i), mid+1, r, val, volta);
        else
            update(LEFT(i), l, mid, val, volta);
        tree[i] = max(tree[LEFT(i)], tree[RIGHT(i)]);
    }
}

void update2(int i, int l, int r, int x, int y) {
    doLazy(i, l, r);
    if(l >= x && r <= y) {
        lazy[i] = INF;
        doLazy(i, l, r);
    }else if(r < x || l > y) return;
    else {
        int mid = (l+r)>>1;
        update2(LEFT(i), l, mid, x, y);
        update2(RIGHT(i), mid+1, r, x, y);
        tree[i] = max(tree[LEFT(i)], tree[RIGHT(i)]);
    }
}

ll query(int i, int l, int r) {
    doLazy(i, l, r);
    if(debug) {
        cout << "tree l:" << l << " r: " << r << " val: " << tree[i] << endl;
    }
    if(l == r) return (tree[i] < INF ? l : l-1);
    else {
        int mid = (l+r)>>1;
        doLazy(RIGHT(i), mid+1, r);
        doLazy(LEFT(i), l, mid);
        if(tree[LEFT(i)] < INF)
            return query(RIGHT(i), mid+1, r);
        else
            return query(LEFT(i), l, mid);
    }
}

int cnt = 0;

void dfs(int u, int p, int cntp) {
    int me = ++cnt;
    update(1, 1, n, a[u], false);
    ll va = val_ant;
    ans[u] = query(1, 1, n);
    //cout << "u: " << u << " cnt: " << me << " ans: " << ans[u] << endl;
    for(int v : adj[u]) {
        if(v == p) continue;
        //cout << "cleaning: " << me+1 << " " << n << endl;
        //update2(1, 1, n, me+1, n);
        dfs(v, u, me);
    }
    val_ant = va;
    update(1, 1, n, a[u], true);
}

int main() {
    ios_base::sync_with_stdio(false);
    cin >> n;
    for(int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    update2(1, 1, n, 1, n);
    for(int i = 0; i < n-1; i++) {
        int a, b;
        cin >> a >> b;
        adj[a].PB(b);
        adj[b].PB(a);
    }

    dfs(1, 1, 1);
    for(int i = 1; i <= n; i++) cout << ans[i] << "\n";
}


Measured memory_bytes: 31316