#define ENABLE_DEBUG 1
// hidden common codes{{{
#include<bits/stdc++.h>
#define ALL(v) std::begin(v),std::end(v)
#define LOOP(k) for(lint ngtkana_is_a_genius=0; ngtkana_is_a_genius<(lint)k; ngtkana_is_a_genius++)
using lint=long long;
using ld=long double;
template<class T> using numr=std::numeric_limits<T>;
struct input_t {
    template<class T> operator T() {
        T t;
        std::cin>>t;
        return t;
    }
} input;
#ifdef NGTKANA
#include<debug.hpp>
#else
#define DEBUG(...)(void)0
#endif
/*}}}*/

// segtree {{{
/* APIs
 * - segtree(sz)
 * - size()
 * - fold(l, r)
 * - set(i, x)
 * - lazy_set(i, x)
 * - build()
 * - to_vec()
 */
template <class Monoid> struct segtree{/*{{{*/
    // a type alias
    using value_type = typename Monoid::value_type;

    // member variables
    std::vector<value_type>table;

    // trivial constructors
    segtree()=default;
    segtree(segtree const&)=default;
    segtree(segtree&&)=default;
    segtree&operator=(segtree const&)=default;
    segtree&operator=(segtree&&)=default;

    // a non-trivial constructor
    segtree(std::size_t n) : table(2*n, Monoid::id) {}

    // resize
    void resize(std::size_t n) {
        assert(table.empty());
        table.resize(2*n);
    }

    // size
    std::size_t size() const { return table.size() / 2; }

    // fold
    value_type fold(std::size_t l, std::size_t r) const {
        value_type fl = Monoid::id;
        value_type fr = Monoid::id;

        for(l+=size(),r+=size();l<r;l>>=1,r>>=1){
            if(l&1u) fl=Monoid::op(fl, table.at(l++));
            if(r&1u) fr=Monoid::op(fr, table.at(--r));
        }

        return Monoid::op(fl, fr);
    }

    // set
    void set(std::size_t i, value_type x) {
        assert(0 <= i);
        assert(i < size());

        i+=size();
        table.at(i) = x;

        for(i>>=1;i;i>>=1){ table.at(i) = Monoid::op(table.at(2*i), table.at(2*i+1)); }
    }

    // lazy_set
    void lazy_set(std::size_t i, value_type x) {
        assert(0 <= i);
        assert(i < size());

        i+=size();
        table.at(i) = x;
    }

    // map
    template <class F>
        void map(std::size_t i, F const& f) { set(i, f(at(i))); }

    // build
    void build() {
        for(std::size_t i=size()-1;i;i--){ table.at(i) = Monoid::op(table.at(2*i), table.at(2*i+1)); }
    }

    // at
    value_type at(std::size_t i) const { return table.at(size() + i); }

    // to_vec
    std::vector<value_type> to_vec() const {
        std::vector<value_type> ret(size());
        std::copy(table.begin()+size(), table.end(), ret.begin());
        return ret;
    }

};/*}}}*/
/*}}}*/

// max-monoid{{{
template <class Value> struct max_monoid_t {
    using value_type = Value;
    static value_type op(value_type l, value_type r) { return std::max(l, r); }
    static const value_type id;
};
template <class Value> const typename max_monoid_t<Value>::value_type
max_monoid_t<Value>::id = 0;
/*}}}*/

int main(){
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);

    lint n=input;
    std::vector<lint>old_a(n);
    for(lint&x:old_a)x=input;
    std::vector<std::vector<lint>>g(n);
    for(lint i=0;i<n-1;i++){
        lint u=(lint)input-1;
        lint v=(lint)input-1;
        g.at(u).push_back(v);
        g.at(v).push_back(u);
    }

    std::vector<lint>ord,ord_rev(n);
    auto dfs=[&](auto&&f, lint x, lint p) -> void {
        auto&&v=g.at(x);
        if (x!=p) {
            v.erase(std::find(ALL(v), p));
        }

        ord_rev.at(x)=ord.size();
        ord.push_back(x);

        for(lint y:g.at(x)){
            f(f, y, x);
        }
    };
    dfs(dfs, 0, 0);


    std::vector<std::tuple<lint,lint,lint>>pri(n);
    for(lint i=0;i<n;i++){
        pri.at(i)=std::tuple(old_a.at(i), -ord_rev.at(i), i);
    }
    std::sort(ALL(pri));
    std::vector<lint>a(n);
    for(lint i=0;i<n;i++){
        a.at(std::get<2>(pri.at(i)))=i;
    }

    std::vector<lint>ans(n);
    auto seg=segtree<max_monoid_t<lint>>(n);
    auto efs=[&](auto&&f, lint x) -> void {
        // 自分で終わるもの
        lint self = seg.fold(0, a.at(x)) + 1;

        // 自分のスコア
        ans.at(x) = std::max(seg.fold(0, n), seg.fold(0, a.at(x)) + 1);

        // ご入会
        seg.set(a.at(x), self);

        for(lint y:g.at(x)){
            f(f, y);
        }
        // ご退会
        seg.set(a.at(x), 0);
    };
    efs(efs, 0);

    for(lint x:ans) std::cout<<x<<'\n';
}

/*
 * まずは同じ場合は祖先が大きいように、distince 化をします。
 * LIS を dp[ 値 ] = それで終わるときの長さとします。
 * この配列に、祖先の分だけ入ってる状態を保ちながら DFS です。
 * 
 * 抜けるときには、自分のいるところを 0 にするとよいです。
 * 自分のスコアを決めるときにはそれより小さいものの最大 + 1 です。
 * 答えは、自分を入れる前の全体の最大と、自分スコアの大きい方です。
 */


Measured memory_bytes: 44172