#include <bits/stdc++.h>
#define rep(i, n) for(int i=0; i<(n); i++)
#define all(x) (x).begin(), (x).end()
#define bit(x) (1L << (x))
using ll = long long;
using namespace std;

template<typename T>
vector<T> make_v(size_t a,T b){return vector<T>(a,b);}

template<typename... Ts>
auto make_v(size_t a,Ts... ts){
        return vector<decltype(make_v(ts...))>(a,make_v(ts...));
}

using graph = vector<vector<int>>;

/**
 * verified at: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_A&lang=jp
 * see also   : https://codeforces.com/blog/entry/18051
 */
template<class Monoid>
class SegmentTree{
private:
        using T = typename Monoid::T;
        const size_t n;
        vector<T> d;

        void build(){
                for(size_t b = n - 1; b > 0; b--) d[b] = Monoid::op(d[b << 1], d[b << 1 | 1]);
        }

public:
        SegmentTree(size_t n)
                : n(n), d(2 * n, Monoid::identify()) {}

        template<typename InputItr>
                SegmentTree(InputItr first, InputItr last)
                : n(distance(first, last)), d(2 * n, Monoid::identify()){
                        copy(first, last, next(d.begin(), n));
                        build();
                }

        /* set one value */
        void modify(size_t k, T v){
                for(d[k += n] = v; k > 1; k >>= 1) d[k >> 1] = Monoid::op(d[k], d[k ^ 1]);
        }

        /* return [l, r) value */
        T query(size_t l, size_t r){
                T res {Monoid::identify()};
                for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
                        if (l&1) res = Monoid::op(res, d[l++]);
                        if (r&1) res = Monoid::op(res, d[--r]);
                }
                return res;
        }
};

/* Range Sum Query */
template<typename U = ll>
struct RMQ{
        using T = U;
        static T op(const T& a, const T& b){ return max<T>(a, b); };
        static constexpr T identify(){ return 0; };
};


int main() {
        int n;
        cin >> n;

        vector<int> a(n), b(n);
        rep (i, n) cin >> a[i];

        // coorinate compression
        vector<int> t = a;
        sort(t.begin(), t.end());
        t.erase(unique(t.begin(), t.end()), t.end());
        rep (i, n) {
                b[i] = lower_bound(t.begin(), t.end(), a[i]) - t.begin();
        }
        
        graph g(n);
        rep (i, n - 1) {
                int u, v;
                cin >> u >> v;
                --u;
                --v;

                g[u].push_back(v);
                g[v].push_back(u);
        }

        vector<int> ans(n, -1);
        SegmentTree<RMQ<int>> st(n);
        function<void(int, int)> rec = [&](int bv, int v) {
                int m = st.query(0, b[v]), tmp = st.query(b[v], b[v] + 1);
                if (tmp < m + 1) {
                        st.modify(b[v], m + 1);
                }

                ans[v] = st.query(0, n);

                for (int u : g[v]) {
                        if (u == bv) continue;
                        rec(v, u);
                }

                st.modify(b[v], tmp);
        };

        rec(-1, 0);
        rep (i, n) cout << ans[i] << endl;

        return 0;
}


Measured memory_bytes: 35924