/* ****revpro**** */
// #pragma GCC target ("avx2")
// #pragma GCC optimization ("O3")
// #pragma GCC optimization ("unroll-loops")
#include<bits/stdc++.h>
#define ll          int
#define pb          push_back
#define endl     '\n'
#define pii         pair<ll,ll>
#define vi          vector<ll>
#define all(a)      (a).begin(),(a).end()
#define F           first
#define S           second
#define sz(x)       (ll)x.size()
#define hell        1000000007
#define rep(i,a,b)  for(ll i=a;i<b;i++)
#define repr(i,a,b) for(ll i=b-1;i>=a;i--)    
#define lbnd        lower_bound
#define ubnd        upper_bound
#define bs          binary_search
#define mp          make_pair
#define present(c,x) ((c).find(x) != (c).end())
#define cpresent(c,x) (find(all(c),x) != (c).end())
#define mii      map<ll,ll>
using namespace std;

#define TIME        cerr << "\nTime elapsed: " << setprecision(5) <<1000.0 * clock() / CLOCKS_PER_SEC << "ms\n";
#define FAST ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define N  200005
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;  
#define ordered_set tree<double, null_type,less<double>, rb_tree_tag,tree_order_statistics_node_update> 
ll a[N];
ll s[80*N],L[80*N],R[80*N];
ll NEXT_FREE_INDEX=1;
ll root[80*N],idx[N];
ll cur=0;
void build(ll id,ll l ,ll r ){
  if(r == l){
    s[id] = 0;
    return ;
  }
  ll mid = (l+r)/2;
  L[id] = NEXT_FREE_INDEX ++;
  R[id] = NEXT_FREE_INDEX ++;
  build(L[id], l, mid);
  build(R[id], mid+1, r);
  s[id] = 0;
}

ll upd(ll p, ll v,ll id,ll l ,ll r ){
  ll ID =  NEXT_FREE_INDEX ++; // index of the node in new version of segment tree
  if(r == l ){
    s[ID]=max(s[id],v);
    return ID;
  }
  ll mid = (l+r)/2;
  L[ID] = L[id], R[ID] = R[id]; // in case of not updating the llerval of left child or right child
  if(p <= mid)
    L[ID] = upd(p, v, L[ID], l, mid);
  else
    R[ID] = upd(p, v, R[ID], mid+1, r);
  s[ID]=max(s[L[ID]],s[R[ID]]);
  return ID;
}
int sum(int x,int y,int id,int l,int r){
  if(x > r or l > y)  return 0;
  if(x <= l && r <= y)  return s[id];
  int mid = (l+r)/2;
  return max(sum(x, y, L[id], l, mid),
         sum(x, y, R[id], mid+1, r));
}
ll ans[N];
vi adj[N];
ll vis[N];
ll n;
void dfs(ll node,ll p=0)
{
  vis[node]=1;
  root[cur+1]=upd(a[node],sum(0,a[node]-1,idx[p],0,n-1)+1,idx[p],0,n-1);
  cur++;
  idx[node]=root[cur];
  ans[node]=sum(0,n-1,idx[node],0,n-1);
  for(auto i:adj[node])
  if(!vis[i])
    dfs(i,node);
}
void solve()
{
  n;
  cin>>n;
  set <ll> s;
  map <ll,ll> tmp;
  ll cnt=0;
  rep(i,1,n+1) cin>>a[i],s.insert(a[i]);
  rep(i,0,n-1)
  {
    ll x,y;
    cin>>x>>y;
    adj[y].pb(x);
    adj[x].pb(y);
  }
  for(auto i:s) tmp[i]=cnt++;
  rep(i,1,n+1) a[i]=tmp[a[i]];
  build(0,0,n-1);
  dfs(1,0);
  rep(i,1,n+1) cout<<ans[i]<<'\n';
  cout<<endl;    
}
signed main()
{
  
    /***********************************/
    unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
    mt19937_64 generator (seed);
    /***********************************/
 #ifndef ONLINE_JUDGE
      // for getting input from input.txt
     freopen("input.txt", "r", stdin);
//     // for writing output to output.txt
//     freopen("output1.txt", "w", stdout);
 #endif
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int TESTS=1;
//  cin>>TESTS;
  while(TESTS--)
  {
    solve();
    
  }
  TIME
  return 0;
}

Measured memory_bytes: 91520