#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 200200;

template <typename type>
struct SegmentTreeWithoutLazyPropagation
{
    #define Miid ((L + R) >> 1)
    #define Leeft (Node << 1)
    #define Riight (Node << 1 | 1)

    private : const type E = 0;         /// identity element        /// Check this
    private : static const int Nax = 4 * N;                         /// Check this

    private : int n;    /// Array length
    private : type Tree[Nax];

    public : SegmentTreeWithoutLazyPropagation(int n = 0) : n(n)
    {
        for(int Node = 0; Node < Nax; Node++)
            Tree[Node] = E;
    }

    private : type Unite(type x, type y)    /// Check this
    {
        return max(x, y);
    }

    private : void Merge(int Node)
    {
        Tree[Node] = Unite(Tree[Leeft], Tree[Riight]);
    }

    public : void Build(const vector <type>& a)
    {
        Clear();
        n = a.size();
        Build(a, 1, 0, n - 1);
    }

    private : void Build(const vector <type>& a, int Node, int L, int R)
    {
        Tree[Node] = E;

        if(L == R)  return void(Tree[Node] = a[L]);

        Build(a, Leeft, L, Miid);
        Build(a, Riight, Miid + 1, R);

        Merge(Node);
    }

    public : void Update(int i, type x)
    {
        if(n <= 0)  return ;
        Update(i, x, 1, 0, n - 1);
    }

    private : void Update(int i, type x, int Node, int L, int R)
    {
        if(i < L || R < i)      return ;
        if(L == R)              return void(Tree[Node] = x);    /// Check This

        Update(i, x, Leeft, L, Miid);
        Update(i, x, Riight, Miid + 1, R);

        Merge(Node);
    }

    public : type Query(int i, int j)
    {
        if(n <= 0 || i > j) return E;
        return Query(i, j, 1, 0, n - 1);
    }

    private : type Query(int i, int j, int Node, int L, int R)
    {
        if(j < L || R < i)      return E;
        if(i <= L && R <= j)    return Tree[Node];

        return Unite(Query(i, j, Leeft, L, Miid), Query(i, j, Riight, Miid + 1, R));
    }

    public : void Clear()
    {
        for(int Node = 0; Node <= 4 * n; Node++)
            Tree[Node] = E;
        n = 0;
    }
};

SegmentTreeWithoutLazyPropagation <int> myTree;

int n, m;
int a[N];
int Ans[N];
vector <stack <int>> stk;
vector <vector <int>> Adj;

void DFS(int x = 1, int p = 0, int soFar = 1)
{
    Ans[x] = 1 + myTree.Query(0, a[x] - 1);

    stk[a[x]].push(max(stk[a[x]].top(), Ans[x]));
    myTree.Update(a[x], stk[a[x]].top());

    Ans[x] = max(Ans[x], soFar);
    soFar = max(soFar, Ans[x]);

    for(int y : Adj[x])
        if(y ^ p)
            DFS(y, x, soFar);

    stk[a[x]].pop();
    myTree.Update(a[x], stk[a[x]].top());
}

int main()
{
    cin >> n;
    for(int x = 1; x <= n; x++) scanf("%d", a + x);

    map <int,int> Hash;

    Hash[0];
    for(int x = 1; x <= n; x++) Hash[a[x]];
    for(pair <int,int> p : Hash)    Hash[p.first] = m++;
    for(int x = 1; x <= n; x++) a[x] = Hash[a[x]];

    myTree.Build(vector <int> (m));

    stk.assign(m, stack <int> ());
    for(int i = 0; i < m; i++)  stk[i].push(0);

    Adj.assign(n + 1, vector <int> ());

    for(int i = 1; i < n; i++)
    {
        int x, y;   scanf("%d%d", &x, &y);

        Adj[x].push_back(y);
        Adj[y].push_back(x);
    }

    DFS();

    for(int x = 1; x <= n; x++) printf("%d\n", Ans[x]);
}


Measured memory_bytes: 174052