#pragma GCC optimize("O3")
#pragma GCC target("avx")

#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <utility>


template <const unsigned int N>
struct FastInput{
    char Input[N];
    char* input;
    FastInput(void):Input(), input(Input){ fread_unlocked(Input, sizeof(char), N, stdin); }
    inline int getint(void){
        int res = 0, c; while((c = *(input++) - '0') >= 0) res = 10 * res  + c;
        return res;
    }
};

constexpr unsigned int MAX_INPUT = 7400'000; //'
FastInput<MAX_INPUT> Input;

char* output = Input.Input;
constexpr int digit = 4;
constexpr int MAX_D_SIZE = 100'00; //'
struct NoName{
    struct Mike{
        long long int str;
        int dig;
        constexpr Mike(void):str(), dig(){}
    };
    Mike S[MAX_D_SIZE];
    long long int T[MAX_D_SIZE];
    constexpr NoName(void): S(), T(){
        char P[8]{}, Q[8]{};
        for(int i = 0; i < MAX_D_SIZE; ++i){
            int t = i;
            char* ptr = P;
            while(t){ S[i].dig++; *(ptr++) = '0' ^ (t % 10); t /= 10; }
            for(int j = 0, j2 = digit - 1; j < digit; ++j, --j2){
                Q[j2] = P[j] ? P[j] : '0';
            }
            --ptr; char* ptr2 = P;
            while(ptr2 < ptr){
                const char c = *ptr; 
                *(ptr--) = *ptr2; *(ptr2++) = c;
            }
            for(int j1  = 0, j2 = 0; j1 < digit; ++j1, j2 += 8){
                S[i].str |= (long long int)(P[j1]) << j2; P[j1] = 0;
                T[i]     |= (long long int)(Q[j1]) << j2; Q[j1] = 0;
            }
        }
    }
};
constexpr NoName Da;
 
inline void writeBuffer(const int& n){
    if(n < MAX_D_SIZE){
        *(long long int*)(output) = Da.S[n].str;
        output += Da.S[n].dig;
    }
    else{
        const int s = n / MAX_D_SIZE, t = n % MAX_D_SIZE;
        *(long long int*)(output) = Da.S[s].str;
        output += Da.S[s].dig;
        *(long long int*)(output) = Da.T[t];
        output += digit;
    }    
    *(output++) = '\n';
}

constexpr unsigned int MAX_N = 200'000; //'
int A[MAX_N + 1];
int Lis[MAX_N + 1];

struct edge{
    int to; 
    edge* next;
};

edge Edge[2 * MAX_N + 1];
edge* begin[MAX_N + 1];
edge* e_ptr = Edge;
inline void append(const int& u, const int& v){
    e_ptr -> to = v;
    e_ptr -> next = begin[u];
    begin[u] = e_ptr++;
}

int Ans[MAX_N + 1];
bool visited[MAX_N + 1];

struct stack_type{
    int vertex;
    int val;
};
stack_type Stack[2 * MAX_N + 3];
stack_type * stack = Stack;
inline stack_type* pop(void){ return --stack; }
inline void push(const int& v, const int& value){ stack -> vertex = v, stack -> val = value; ++stack;}
inline bool empty(void){ return stack == Stack; }

struct Index{
    int index;
    int val;
};
Index Restore[MAX_N + 1];

int main(void){
    int n = Input.getint();
    for(int i = 1; i <= n; ++i) A[i] = Input.getint();
    Lis[0] = 0; std::memset(Lis + 1, 0x7f, sizeof(Lis + 1));
    for(int i = 1; i < n; ++i){
        int u = Input.getint(), v = Input.getint();
        append(u, v); append(v, u);
    }
    visited[1] = true; push(1, 0);
    while(!empty()){
        const stack_type* p = pop();
        const int v = p ->vertex, value = p -> val;
        if(value ^ (-1)){
            if(Lis[value] < A[v]){
                const int&& tmp = value + 1;
                Restore[v].index = tmp; Restore[v].val = INT32_MAX;
                Lis[tmp] = A[v]; Ans[v] = tmp;
            }
            else{
                int ok = 0, ng = value;
                while(ng - ok > 1){
                    const int mid = (ok + ng) >> 1;
                    if(Lis[mid] < A[v]) ok = mid; else ng = mid;
                }
                Restore[v].index = ng; Restore[v].val = Lis[ng];
                Lis[ng] = A[v]; Ans[v] = value;
            }
            push(v, -1);
            for(edge* itr = begin[v]; itr; itr = itr -> next) if(!visited[itr -> to]){ 
                visited[itr -> to] = true; push(itr -> to, Ans[v]);
            }
        }
        else{ Lis[Restore[v].index] = Restore[v].val; }
    }
    for(int i = 1; i <= n; ++i) writeBuffer(Ans[i]);
    fwrite_unlocked(Input.Input, sizeof(char), output - Input.Input, stdout);
    return 0;
}

Measured memory_bytes: 21248