Problem:
Score : 600 points

Problem Statement

We have a tree with N vertices, whose i-th edge connects Vertex u_i and Vertex v_i.
Vertex i has an integer a_i written on it.
For every integer k from 1 through N, solve the following problem:

We will make a sequence by lining up the integers written on the vertices along the shortest path from Vertex 1 to Vertex k, in the order they appear. Find the length of the longest increasing subsequence of this sequence.

Here, the longest increasing subsequence of a sequence A of length L is the subsequence A_{i_1} , A_{i_2} , ... , A_{i_M} with the greatest possible value of M such that 1 \leq i_1 < i_2 < ... < i_M \leq L and A_{i_1} < A_{i_2} < ... < A_{i_M}.

Constraints

2 \leq N \leq 2 \times 10^5

1 \leq a_i \leq 10^9

1 \leq u_i , v_i \leq N

u_i \neq v_i

The given graph is a tree.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
a_1 a_2 ... a_N
u_1 v_1
u_2 v_2
:
u_{N-1} v_{N-1}

Output

Print N lines. The k-th line, print the length of the longest increasing subsequence of the sequence obtained from the shortest path from Vertex 1 to Vertex k.

Sample Input 1

10
1 2 5 3 4 6 7 3 2 4
1 2
2 3
3 4
4 5
3 6
6 7
1 8
8 9
9 10

Sample Output 1

1
2
3
3
4
4
5
2
2
3

For example, the sequence A obtained from the shortest path from Vertex 1 to Vertex 5 is 1,2,5,3,4. Its longest increasing subsequence is A_1, A_2, A_4, A_5, with the length of 4.

Solution in Java (OpenJDK 11.0.6) (judge verdict: Accepted)

import java.util.*;
import java.util.stream.*;
import java.io.*;

class Ele {
  int ori;
  int idx;

  Ele(int ori, int idx){
    this.ori = ori;
    this.idx = idx;
  }
}

class Graph {
  public ArrayList< ArrayList<Integer> > adjacency;

  Graph(int n){
    adjacency = new ArrayList< ArrayList<Integer> >();
    for(int i = 0; i < n; i++){
      adjacency.add(new ArrayList<Integer>());
    }
  }

  public void add_edge(int from, int to, boolean is_directed){
    adjacency.get(from).add(to);
    if(!is_directed){
      adjacency.get(to).add(from);
    }
  }
}


public class Main {
  
  static final int INF = 1000000001;

  static int n;
  static int[] a, lis, ans;
  static boolean[] seen;

  static Deque<Ele> st = new ArrayDeque<>();

  static Graph g;
  
  public static void main(String[] args) throws Exception {
    
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    String[] in = br.readLine().split(" ");
    n = Integer.parseInt(in[0]);

    g = new Graph(n);

    in = br.readLine().split(" ");
    a = Stream.of(in).mapToInt(Integer::parseInt).toArray();

    for(int i = 0; i < n-1; i++){
      in = br.readLine().split(" ");
      g.add_edge(Integer.parseInt(in[0]) - 1, Integer.parseInt(in[1]) - 1, false);
    }

    br.close();

    lis = new int[n+1];
    ans = new int[n];
    seen = new boolean[n];

    Arrays.fill(lis, INF);
    lis[0] = -INF;

    dfs(0, 0);

    PrintWriter out = new PrintWriter(System.out);

    for(int i = 0; i < n; i++){
      out.println(ans[i]);
    }
    out.flush();
  }

  static int binarySearch(int x, int maxIdx){
    int left = 0; int right = maxIdx + 1;
    while(right - left > 1){
      int mid = (right + left) / 2;
      if(lis[mid] < x) left = mid;
      else right = mid;
    }
    st.push(new Ele(lis[right], right));
    lis[right] = x;
    
    return right;
  }

  static void dfs(int now, int idx){
    
    idx = Math.max(idx, binarySearch(a[now], idx));

    ans[now] = idx;
    seen[now] = true;

    for(int nex : g.adjacency.get(now)){
      if(seen[nex]) continue;
      dfs(nex, idx);
    }

    Ele forRet = st.poll();
    lis[forRet.idx] = forRet.ori;
    
    return;
  }

}