/*
Do a vector of stacks 
in place of multiple d's

And also keep one stack of indices
which points to the last stack we modified;


So say we have [1,3,9,inf,inf,inf], with indices []
and we came upon a 10;  Then we would have
d = [1,3,[9,10],inf,inf,inf] with indices [2]

Then when we need to "roll back" to the previous d,
we use the top index (2) and pop d[2]



But instead of doing this, because then
we can't keep d "sorted" and do a binary search on it,
we only put the top of the stack in d,
and our stack of indices actually has {index,value}
where the value is the thing that we just covered.



*/
#include <iostream>
#include <cassert>
#include <vector>
#include <algorithm>
#include <climits>
#include <bitset>

#include <stack>
#include <queue>
// #include <deque>
#include <set>
#include <map>
#include <string>
// #include <unordered_set>
// #include <unordered_map>

#include <tuple>
// #include <cmath>
// #include <numeric>

using namespace std;


typedef long long ll;
typedef pair<long long,long long> pll;
typedef pair<int,int> pii;
typedef pair<int,long long> pil;
typedef pair<long long,int> pli;
typedef vector<vector<long long>> vvl;
typedef vector<vector<int>> vvi;
typedef vector<int> vi;
typedef vector<long long> vl;
typedef vector<bool> vb;
typedef priority_queue<int, vector<int>, greater<int> > minq;
typedef priority_queue<int> maxq;
// to initialize PQs with a vector, do 
// minq(v.begin(),v.end()) or maxq(v.begin(),v.end())
// or minq(a,a+10) for arrays

#define emplace_back pb
const char el = '\n';
const long long inf = 1e+9;


/*
Edge cases:



*/


int main() {
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);

    int n; cin>>n; 

    vl a(n);
    for (int i=0; i<n; ++i) {
        cin>>a[i];
    }

    vvi nbr(n);
    for (int i = 0; i<n-1; ++i) {
        int u, v; cin>>u>>v;
        --u,--v;
        nbr[u].push_back(v);
        nbr[v].push_back(u);
    }


    //pr.first=path p leading from 1 to curr;
    //pr.second=d[]
    //where d[i] = len of longest LIS
    //that ends at index i,
    //where index i is the index in the path
    //p
    //and d.back() = longest length;
    stack<int> s;
    vl d(n+1,inf);
    // map<int,vi> pathmap{};
    // pathmap[0] = {0};
    stack<pil> dchanges;
    s.push(0);

    vb pushed(n,false);
    pushed[0]=true;
    vb finishedsubtree(n,false);


    vi ret(n);
    while ( !s.empty() ) {

        auto curr = s.top();
        // cout<<" at node "<<curr<<" and d = ";
        // for (auto x: d) if (x!=inf) cout<<x<<" ";
        // cout<<el;
        if (!finishedsubtree[curr]) {
            //first time analyzing curr;
            //calculate the answer;
            //implement changes to d;
            //add children;

            auto it = lower_bound(d.begin(),d.end(),a[curr]);

            if (it == d.end()) {
                //
                assert (it!=d.end());
            } else {
                int j = (int)(it-d.begin());
                dchanges.push({j,d[j]});
                d[j] = a[curr];
                // cout<<"\t made the change d["<<j<<"]="<<a[curr]<<" from "<<dchanges.top().second<<el;
            }

            auto answerit = lower_bound(d.begin(),d.end(),inf);
            ret[curr] = (int)(answerit-d.begin());
            // cout<<"\t longest to node "<<curr<<" = "<<ret[curr]<<el;

            for (auto nb: nbr[curr]) {
                if (pushed[nb]) continue;

                s.push(nb);
                pushed[nb]=true;

            }
            finishedsubtree[curr]=true;
        } else {
            // 2nd time seeing curr; roll back changes
            assert (!dchanges.empty());

            auto pr = dchanges.top();
            int j = pr.first;
            auto oldvalue = pr.second;
            d[j]=oldvalue;
            dchanges.pop();

            s.pop();
        }







    }

    for (auto x: ret) cout<<x<<el;

}

Measured memory_bytes: 21872