#include <algorithm>
#include <cstdint>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#include <cfloat>

using namespace std;

using lint=int64_t;
using uint=uint32_t;
using ulint=uint64_t;

template<class T>
using vector2d=vector<vector<T>>;

template<class T>
bool UpdateMax(T &a, const T &b){
  if(a<b){
    a=b;
    return true;
  }else{
    return false;
  }
}

template<class T>
bool UpdateMin(T &a, const T &b){
  if(a>b){
    a=b;
    return true;
  }else{
    return false;
  }
}

template <class T>
void OutVec(const vector<T>& vec){
  for(int i = 0; i < vec.size() - 1; ++i){
    cout<<vec[i]<<" ";
  }
  cout<<vec.back()<<endl;
}

template <class T>
void OutVec2d(const vector2d<T>& vec){
  for(auto v:vec){
    OutVec(v);
  }
}

template<typename CostType>
/// \brief 辺の情報
struct Edge{
  int      to;
  CostType cost;
  Edge(int t, CostType c): to(t), cost(c){
  }
};

template<typename CostType>
class Graph{
private:
  /// \brief adjacent_list_[n]=ノードnの隣接リストを表すvector<Edge>
  std::vector<std::vector<Edge<CostType>>> adjacent_list_;
public:
  /// \brief 頂点数
  const int NODE_SIZE_;
  /// \brief コンストラクタ
  /// \param node_size 頂点数
  explicit Graph(const int node_size): NODE_SIZE_(node_size),
                                       adjacent_list_(node_size){
  }
  /// \brief 有向グラフの辺を生やす
  /// \param from 辺の根本の頂点の番号
  /// \param to 辺の先の頂点の番号
  /// \param cost 辺のコスト
  void SetDirectedEdge(const int from, const int to, const CostType cost){
    adjacent_list_[from].push_back(Edge<CostType>(to, cost));
  }
  /// \brief 無向グラフの辺を生やす
  /// \param node_a 一方の頂点の番号
  /// \param node_b もう一方の頂点の番号
  /// \param cost 辺のコスト
  void
  SetUndirectedEdge(const int node_a, const int node_b, const CostType cost){
    SetDirectedEdge(node_a, node_b, cost);
    SetDirectedEdge(node_b, node_a, cost);
  }
  /// \brief ある頂点の隣接リストを取得
  /// \param node_num 頂点の番号
  /// \return 隣接リスト
  std::vector<Edge<CostType>> GetAdjacentList(int node_num) const{
    return adjacent_list_[node_num];
  }
};


struct RevInfo{
  lint node;
  lint prev_val;
};

const lint INF=INT64_MAX/2;

void DFS(vector<lint>& lis, vector<lint>& result, vector<lint>& a, Graph<lint>& graph, int curr, int prev, stack<RevInfo>& rev_info){
  auto itr=lower_bound(lis.begin(),lis.end(),a[curr]);

  RevInfo rev;
  rev.prev_val=*itr;
  rev.node=distance(lis.begin(),itr);
  rev_info.push(rev);

  *itr=a[curr];

  auto lis_len_itr=lower_bound(lis.begin(),lis.end(),INF);
  result[curr]=distance(lis.begin(),lis_len_itr);

  for(auto e:graph.GetAdjacentList(curr)){
    if(e.to!=prev){
      DFS(lis,result,a,graph,e.to,curr,rev_info);
    }
  }

  RevInfo rev_top=rev_info.top();
  rev_info.pop();
  lis[rev_top.node]=rev_top.prev_val;
}

int main(){
  cout << std::fixed << std::setprecision(16);
  cin.tie(nullptr);
  std::ios::sync_with_stdio(false);

  lint n;
  cin>>n;
  Graph<lint> graph(n+1);
  vector<lint> a(n+1);
  for(int i=1;i<=n;i++){
    cin>>a[i];
  }
  for(int i=0;i<n-1;i++){
    int u,v;
    cin>>u>>v;
    graph.SetUndirectedEdge(u,v,1);
  }
  stack<RevInfo> rev_info;


  vector<lint> lis(n,INF);



  vector<lint> result(n+1);

  DFS(lis,result,a,graph,1,0,rev_info);

  for(int i=1;i<=n;i++){
    cout<<result[i]<<endl;
  }



  return 0;
}




Measured memory_bytes: 59356