#pragma GCC optimize("O3")
#pragma GCC target("avx,avx2,fma")
#include <bits/stdc++.h>

using namespace std;
using ll = long long int;
constexpr ll M = 1e9 + 7;
inline ll sum_1(const ll n) { return ((n * (n + 1)) / 2) % M; }
inline ll sum_2(const ll n) { return ((n * (n + 1) * (2 * n + 1)) / 6) % M; }
inline ll sum_3(const ll n) { return (((n * (n + 1)) / 2) % M * ((n * (n + 1)) / 2) % M) % M; }
inline ll sum_1(const ll i, const ll j) { return (sum_1(j) - sum_1(i - 1) + M) % M; }
inline ll sum_2(const ll i, const ll j) { return (sum_2(j) - sum_2(i - 1) + M) % M; }
inline ll sum_3(const ll i, const ll j) { return (sum_3(j) - sum_3(i - 1) + M) % M; }

ll pow_f(ll b, ll e) {
    ll ans = 1;
    b = b % M;
    while (e) {
        if (e & 1) {
            ans = (ans * b) % M;
        }
        b = (b * b) % M;
        e >>= 1;
    }
    return ans;
}

ll nCr(ll n, ll r) {
    if (r > n || n < 0 || r < 0) { return 0; }
    if (n == r || r == 0) { return 1; }
    r = min(r, n - r);
    ll ans = 1;
    for (ll i = 1; i <= r; ++i) {
        ans = (ans * (n - i + 1)) / (i);
    }
    return ans;
}

ll nCr(tuple<ll, ll> t) {
    auto n = get<0>(t);
    auto k = get<1>(t);
    return nCr(n + k - 1, k);
}

template <typename T>
void print(T v) {
    cout << v << " ";
}

template <typename T>
void print(vector<T> v) {
    for (auto &i : v) {
        print(i);
    }
    cout << endl;
}

class Tree {
    int n;
    vector<ll> a;
    vector<vector<int>> adj;
    vector<int> visited;
    vector<int> ans;

  public:
    Tree(int n, vector<ll> &a) : n(n), a(a), adj(n), visited(n, false), ans(n, -1) {}

    void addEdge(int u, int v) {
        adj[u - 1].push_back(v - 1);
        adj[v - 1].push_back(u - 1);
    }

    inline int getAns(int i) {
        return ans[i];
    }

    void dfs(int root, vector<pair<int, int>> &&v) {
        visited[root] = true;
        int idx = v.size();
        int prev_val = -1;

        //Add info for root
        if (v.empty()) {
            v.push_back({a[root], 1});
        } else {
            //Find subsequence with largest element less than curr ele
            if (v.back().first < a[root]) {
                v.push_back({a[root], v.back().second + 1});
            } else {
                int lo = 0;
                int hi = v.size() - 1;
                int mid = lo + (hi - lo) / 2;
                int ans = mid;

                while (lo <= hi) {
                    mid = lo + (hi - lo) / 2;
                    if (v[mid].first >= a[root]) {
                        ans = mid;
                        hi = mid - 1;
                    } else {
                        lo = mid + 1;
                    }
                }
                idx = ans;
                prev_val = v[ans].first;
                v[ans].first = a[root];
            }
        }

        ans[root] = v.back().second;

        for (auto &i : adj[root]) {
            if (!visited[i]) {
                dfs(i, move(v));
            }
        }
        
        //Roll back
        if (prev_val == -1) {
            v.pop_back();
        } else {
            v[idx].first = prev_val;
        }
    }
};

void solve() {
    int n;
    cin >> n;
    vector<ll> a(n);
    for (auto &i : a) {
        cin >> i;
    }

    Tree t(n, a);
    for (int i = 0; i < n - 1; ++i) {
        int u, v;
        cin >> u >> v;
        t.addEdge(u, v);
    }

    t.dfs(0, {});

    for (int i = 0; i < n; ++i) {
        cout << t.getAns(i) << endl;
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
#ifdef D_LOCAL
    freopen("in.in", "r", stdin);
    freopen("out.out", "w", stdout);
#endif

    solve();

    return 0;
}

Measured memory_bytes: 33248