#include <bits/stdc++.h>
#define all(vec) vec.begin(), vec.end()
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
template <class T>
using V = vector<T>;
constexpr ll INF = (1LL << 30) - 1LL;
constexpr ll MOD = 1e9 + 7;
constexpr int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};
template <class T>
void chmin(T &a, T b) { a = min(a, b); }
template <class T>
void chmax(T &a, T b) { a = max(a, b); }
void debug() { cerr << "ok" << endl; }
template <class T>
void printv(const vector<T> &v) {
    for (int i = 0; i < v.size(); i++) cout << v[i] << (i + 1 == v.size() ? '\n' : ' ');
}
template <class T>
void readv(vector<T> &v) {
    for (int i = 0; i < v.size(); i++) cin >> v[i];
}
//@docs Docs/SegmentTree.md
template <class T>
struct Segtree {
    int n;
    vector<T> dat;
    void build(int n_) {
        n = 1;
        while (n < n_) {
            n <<= 1;
        }
        dat.resize(2 * n, T::id());
    }
    /* Segtree(int n_, const vector<T> &a) {
        n = 1;
        while (n < n_) {
            n <<= 1;
        }
        dat.resize(2 * n, T::id());
        for (int i = 0; i < a.size(); i++) {
            dat[i + n] = a[i];
        }
        for (int i = n - 1; i > 0; i--) {
            dat[i] = T::f(dat[i << 1], dat[i << 1 | 1]);
        }
    }*/
    void upd(int k, const T &x) {
        k += n;
        dat[k] = T::g(dat[k], x);
        k >>= 1;
        while (k > 0) {
            dat[k] = T::f(dat[k << 1], dat[k << 1 | 1]);
            k >>= 1;
        }
    }
    T get(const int &a, const int &b, int k, int l, int r) {
        if (b <= l || r <= a) {
            return T::id();
        }
        if (a <= l && r <= b) {
            return dat[k];
        }
        return T::f(get(a, b, k << 1, l, (l + r) >> 1),
                    get(a, b, k << 1 | 1, (l + r) >> 1, r));
    }
    inline T get(const int &a, const int &b) { //[a,b)
        if (a >= b) {
            return T::id();
        }
        return get(a, b, 1, 0, n);
    }
    int find(const int &a, const int &b, const T &x, int k, int l, int r) {
        if (b <= l || r <= a || dat[k] > x) {
            return -1;
        }
        if (k >= n) {
            return k - n;
        }
        int il = find(a, b, x, k << 1, l, (l + r) >> 1);
        if (il != -1) {
            return il;
        }
        return find(a, b, x, k << 1 | 1, (l + r) >> 1, r);
    }
    inline int find(const int &a, const int &b, const T &x) { //[a,b)における、値<=x なる最左のindexを求める
        if (a >= b) {
            return -1;
        }
        return find(a, b, x, 1, 0, n);
    }
};
struct T {
    ll x;
    T() {}
    T(ll x) : x(x) {}
    inline static T id() {
        return 0;
    }
    inline static T f(const T &x, const T &y) {
        return T(max(x.x, y.x));
    }
    inline static T g(const T &a, const T &b) {
        return b;
    }
};
int n;
V<V<int>> G;
V<int> a, res;
Segtree<T> seg;
void calc(int i, int p) {
    int s = seg.get(0, a[i]).x + 1;
    int fl = seg.get(a[i], a[i] + 1).x;
    if (fl < s) seg.upd(a[i], s);
    res[i] = seg.get(0, n).x;
    for (auto &e : G[i]) {
        if (e == p) continue;
        calc(e, i);
    }
    if (fl < s) seg.upd(a[i], fl);
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> n;
    G.resize(n);
    a.resize(n);
    res.resize(n);
    readv(a);
    V<int> as = a;
    sort(all(as));
    as.erase(unique(all(as)), as.end());
    for (int i = 0; i < n; i++) {
        a[i] = lower_bound(all(as), a[i]) - as.begin();
    }
    for (int i = 0; i + 1 < n; i++) {
        int u, v;
        cin >> u >> v;
        --u;
        --v;
        G[u].eb(v);
        G[v].eb(u);
    }
    seg.build(n + 10);
    calc(0, -1);
    for (int i = 0; i < n; i++) {
        cout << res[i] << '\n';
    }
}

Measured memory_bytes: 40640