#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <vector>
#include <list>
#include <array>
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
//#define cerr if(false) cerr
#ifdef DEBUG
#define show(...) cerr << #__VA_ARGS__ << " = ", debug(__VA_ARGS__)
#else
#define show(...) 42
#endif
using namespace std;
using ll = long long;
using pii = pair<int, int>;
template <typename T, typename S>
ostream& operator<<(ostream& os, pair<T, S> a) {
    os << '(' << a.first << ',' << a.second << ')';
    return os;
}
template <typename T>
ostream& operator<<(ostream& os, vector<T> v) {
    for (auto x : v) os << x << ' ';
    return os;
}
void debug() {
    cerr << '\n';
}
template <typename H, typename... T>
void debug(H a, T... b) {
    cerr << a;
    if (sizeof...(b)) cerr << ", ";
    debug(b...);
}
map<int,vector<int>> mp;
vector<vector<int>> g;
int par[2000005];
void dfs(int s, int p){
    par[s] = p;
    for(int x: g[s]){
        if(x!=p){
            dfs(x, s);
        }
    }
}


template<typename T> class segtree {
private:
    int n,sz;
    vector<T> node;
public:
    segtree(const vector<T>& v) : n(1), sz((int)v.size()){
        while(n < sz) n *= 2;
        node.assign(2*n,numeric_limits<T>::min());
        for(int i = 0; i < sz; i++){
            node[i+n] = v[i];
        }
        for(int i=n-1; i>=1; i--){
            node[i] = max(node[2*i],node[2*i+1]);
        }
    }
    void update(int k,T a){
        k += n;
        node[k] = a;
        while(k>>=1){
            node[k] = max(node[2*k],node[2*k+1]);
        }
    }
    T query(int a,int b){
        T res1 = numeric_limits<T>::min();
        T res2 = numeric_limits<T>::min();
        a += n, b += n;
        while(a != b){
            if(a & 1) res1 = max(res1, node[a++]);
            if(b & 1) res2 = max(node[--b], res2);
            a >>= 1, b >>= 1;
        }
        show(max(res1, res2));
        return max(res1, res2);
    }
    void print(){
        for(int i = 0; i < sz; i++){
            cout << query(i,i+1) << " ";
        }
        cout << endl;
    }
};




// 部分木についてのクエリとパスについてのクエリが一つのセグ木で対応可能
// 部分木:O(log(n)), パス:O(log^2(n))

class HLdecomposition{
public:
    int V;
    vector<vector<int> > G;
    vector<int> stsize, parent, pathtop, in, out;
    int root;
    void BuildStsize(int u, int p){
        stsize[u] = 1, parent[u] = p;
        for(int& v : G[u]){
            if(v == p) continue;
            BuildStsize(v, u);
            stsize[u] += stsize[v];
            if(stsize[v] > stsize[G[u][0]]){
                swap(v, G[u][0]);
            }
        }
    }
    void BuildPath(int u, int p, int& tm){
        in[u] = tm++;
        for(int v : G[u]){
            if(v == p) continue;
            pathtop[v] = (v == G[u][0] ? pathtop[u] : v);
            BuildPath(v, u, tm);
        }
        out[u] = tm;
    }


    void add_edge(int u, int v){
        G[u].push_back(v), G[v].push_back(u);
    }
    void build(int _root){
        root = _root;
        int tm = 0;
        BuildStsize(root, -1);
        pathtop[root] = root;
        BuildPath(root, -1, tm);
    }
    //元の頂点のインデックスの配列上でのidを返す
    inline int get(int a){
        return in[a];
    }
    int lca(int a, int b){
        int pa = pathtop[a], pb = pathtop[b];
        while(pathtop[a] != pathtop[b]){
            if(in[pa] > in[pb]){
                a = parent[pa], pa = pathtop[a];
            }else{
                b = parent[pb], pb = pathtop[b];
            }
        }
        if(in[a] > in[b]) swap(a, b);
        return a;
    }
    void subtree_query(int a, const function< void(int, int) > &func){
        func(in[a], out[a]);
    }
    void path_query(int a, int b, const function< void(int, int) > &func){
        int pa = pathtop[a], pb = pathtop[b];
        while(pathtop[a] != pathtop[b]){
            if(in[pa] > in[pb]){
                func(in[pa], in[a] + 1);
                a = parent[pa], pa = pathtop[a];
            }else{
                func(in[pb], in[b] + 1);
                b = parent[pb], pb = pathtop[b];
            }
        }
        if(in[a] > in[b]) swap(a, b);
        func(in[a], in[b] + 1);
    }
    HLdecomposition(int node_size) : V(node_size), G(V), stsize(V, 0), parent(V, -1),
        pathtop(V, -1), in(V, -1), out(V, -1){}
};

int ans[200005];
int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n;
    cin >> n;
    vector<int>a(n);
    rep(i,n)cin >> a[i];
    rep(i,n)mp[a[i]].push_back(i);
    g.resize(n);
    HLdecomposition hld(n);
    rep(i,n-1){
        int u, v;
        cin >> u >> v;
        u--;v--;
        g[u].push_back(v);
        g[v].push_back(u);
        hld.add_edge(u, v);
    }
    dfs(0, -1);
    hld.build(0);
    segtree<int> seg({vector<int>(n)});
    for(auto &x : mp){
        auto xx = x.second;
        show(xx);
        rep(i,xx.size()){
            hld.path_query(0, xx[i], [&](int a, int b){
                ans[xx[i]]=max(seg.query(a,b)+1,ans[xx[i]]);
                
            });
        }
        rep(i,xx.size()){
            seg.update(hld.in[xx[i]], ans[xx[i]]);
        }
    }
    rep(i,n)hld.path_query(0, i, [&](int a, int b){
        ans[i]=max(seg.query(a,b),ans[i]);
    });
    rep(i,n)cout << ans[i] << "\n";
}


Measured memory_bytes: 66712