#include <bits/stdc++.h>
using namespace std;
#define SZ(x) (int)(x.size())
#define REP(i, n) for(int i=0;i<(n);++i)
#define FOR(i, a, b) for(int i=(a);i<(b);++i)
#define RREP(i, n) for(int i=(int)(n)-1;i>=0;--i)
#define RFOR(i, a, b) for(int i=(int)(b)-1;i>=(a);--i)
#define ALL(a) a.begin(),a.end()
#define DUMP(x) cerr<<#x<<" = "<<(x)<<endl
#define DEBUG(x) cerr<<#x<<" = "<<(x)<<" (L"<<__LINE__<<")"<< endl;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using P = pair<int, int>;
const double EPS = 1e-8;
const ll MOD = 1000000007;
const int INF = INT_MAX / 2;
const ll LINF = LLONG_MAX / 2;
template <typename T1, typename T2>
bool chmax(T1 &a, const T2 &b) {
    if (a < b) { a = b; return true; }
    return false;
}
template <typename T1, typename T2>
bool chmin(T1 &a, const T2 &b) {
    if (a > b) { a = b; return true; }
    return false;
}
template<typename T1, typename T2>
ostream &operator<<(ostream &os, const map<T1, T2> &mp);
template<typename T>
ostream &operator<<(ostream &os, const vector<T> &v);

template<typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
    os << "(" << p.first << ":" << p.second << ")";
    return os;
}
template<typename T1, typename T2>
ostream &operator<<(ostream &os, const map<T1, T2> &mp) {
    os << "{";
    int a = 0;
    for (auto &tp : mp) {
        if (a) os << ", ";
        a = 1; os << tp;
    }
    return os << "}";
}
template<typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
    os << "[";
    REP(i, SZ(v)) {
        if (i) os << ", ";
        os << v[i];
    }
    return os << "]";
}

template<typename M>
struct PersistentSegmentTree {
    struct Node {
        Node *l, *r;
        M data;
        Node() : l(nullptr), r(nullptr) {}
    };

    const function<M(M,M)> f;
    const M e;
    const int sz;

    PersistentSegmentTree(const function<M(M,M)>& f, const M& e, int sz) :
            f(f), e(e), sz(sz) {}

    Node* _new(const M& data) const {
        auto t = new Node();
        t->data = data;
        return t;
    }

    Node* _new(Node* l, Node* r) const {
        auto t = new Node();
        t->l = l, t->r = r, t->data = f(l->data, r->data);
        return t;
    }

    Node* _build(int l, int r) const {
        assert(l < r);
        if (l+1 == r) return _new(e);
        return _new(_build(l, (l+r)>>1), _build((l+r)>>1, r));
    }

    Node* build() const {
        return _build(0, sz);
    }

    template<typename UpdateQuery>
    Node* _update(Node* t, const UpdateQuery& q, int pos, int l, int r) const {
        if (pos == l and pos+1 == r) return _new(q(t->data));
        if (r <= pos or pos < l) return t;
        return _new(_update(t->l, q, pos, l, (l+r)>>1),
                    _update(t->r, q, pos, (l+r)>>1, r));
    }

    template<typename UpdateQuery>
    Node* update(Node* root, const UpdateQuery& q, int pos) const {
        return _update(root, q, pos, 0, sz);
    }

    M _query(Node* t, int a, int b, int l, int r) const {
        if (r <= a or b <= l) return e;
        if (a <= l and r <= b) return t->data;
        return f(_query(t->l, a, b, l, (l+r)>>1),
                 _query(t->r, a, b, (l+r)>>1, r));
    }

    M query(Node* root, int a, int b) const {
        // return f[a,b)
        return _query(root, a, b, 0, sz);
    }

};

void build_rooted_tree(
        vector<int>& par,
        vector<int>& ord,
        const vector<vector<int>>& g, int v, int p) {
    par[v] = p;
    ord.push_back(v);
    for (auto u : g[v]) {
        if (u == p) {
            continue;
        }
        build_rooted_tree(par, ord, g, u, v);
    }
}


int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);

    int N; cin >> N;
    vi a(N);
    map<int,int> comp;
    REP(i, N) {
        cin >> a[i];
        comp[a[i]] = -1;
    }
    int cnt = 0;
    for (auto &tp : comp) tp.second = cnt++;

    vvi 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> par(N, -1);
    vector<int> ord;
    build_rooted_tree(par, ord, G, 0, -1);

    PersistentSegmentTree<int> segt(
            [](int a,int b){ return max(a,b); },
            0, comp.size());

    map<int,PersistentSegmentTree<int>::Node*> root;

    root[-1] = segt.build();

    vi ans(N);
    for (auto id : ord) {
        int ma = segt.query(root[par[id]], 0, comp[a[id]]);
        root[id] = segt.update(root[par[id]],
                               [&](int a){ return max(ma + 1, a); }, comp[a[id]]);
        ans[id] = segt.query(root[id], 0, comp.size());
    }

    for (int v : ans) {
        cout << v << endl;
    }

    return 0;
}


Measured memory_bytes: 177724