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 C# (.NET Core 3.1.201) (judge verdict: Accepted)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class TEST{
	static void Main(){
		Sol mySol =new Sol();
		mySol.Solve();
	}
}

class Sol{
	public void Solve(){
		
		List<int>[] E = new List<int>[N + 1];
		for(int i=0;i<=N;i++) E[i] = new List<int>();
		for(int i=0;i<N-1;i++){
			E[U[i]].Add(V[i]);
			E[V[i]].Add(U[i]);
		}
		
		var eul = Alg.EulerTourOrderIO(E, 0);
		int[] pos = new int[N];
		int[] prev = new int[N];
		int[] visit = new int[N];
		int[] len = new int[N];
		
		int[] dp = new int[N + 1];
		int Inf = (int) 1e9;
		for(int i=0;i<=N;i++) dp[i] = Inf;
		
		dp[0] = int.MinValue;
		int[] cnt = new int[N];
		foreach(var now in eul){
			cnt[now]++;
			if(cnt[now] == 1){
				// lis
				int l = 0, r = N + 1;
				while(r - l > 1){
					int c = (l + r) / 2;
					if(dp[c] < A[now]){
						l = c;
					} else {
						r = c;
					}
				}
				pos[now] = r;
				prev[now] = dp[r];
				dp[r] = A[now];
				
				l = 0;
				r = N + 1;
				while(r - l > 1){
					int c = (l + r) / 2;
					if(dp[c] < Inf){
						l = c;
					} else {
						r = c;
					}
				}
				len[now] = l;
				
			} else {
				// roll back;
				dp[pos[now]] = prev[now];
			}
		}
		
		Console.WriteLine(String.Join("\n", len));
		
	}
	int N;
	int[] A;
	int[] U,V;
	public Sol(){
		N = ri();
		A = ria();
		U = new int[N-1];
		V = new int[N-1];
		for(int i=0;i<N-1;i++){
			var d = ria();
			U[i] = d[0] - 1;
			V[i] = d[1] - 1;
		}
	}

	static String rs(){return Console.ReadLine();}
	static int ri(){return int.Parse(Console.ReadLine());}
	static long rl(){return long.Parse(Console.ReadLine());}
	static double rd(){return double.Parse(Console.ReadLine());}
	static String[] rsa(char sep=' '){return Console.ReadLine().Split(sep);}
	static int[] ria(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>int.Parse(e));}
	static long[] rla(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>long.Parse(e));}
	static double[] rda(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>double.Parse(e));}
}


static partial class Alg {
	
	public static List<int> EulerTourOrderIO(List<int>[] E, int root){
		// E: edge information (E[idx]: list of vertices from idx-node)
		// return: DFS order, list of index when in & out
		
		int n = E.Length;
		int[] cnt = new int[n];
		
		List<int> euler = new List<int>();
		
		var stk = new Stack<int>();
		stk.Push(root);
		while(stk.Count > 0){
			var now = stk.Pop();
			cnt[now]++;
			euler.Add(now);
			if(cnt[now] == 1){
				stk.Push(now);
				foreach(var nxt in E[now]){
					if(cnt[nxt] == 0){
						stk.Push(nxt);
					}
				}
			}
		}
		
		return euler;
	}
	
	public static List<int> EulerTourOrderWandering(List<int>[] E, int root){
		// E: edge information (E[idx]: list of vertices from idx-node)
		// return: DFS order, list of index when visited one by one
		// (possibly more frequent time than 2, only 1 time when node is leaf)
		
		int n = E.Length;
		int[] cnt = new int[n];
		int[] parent = new int[n];
		for(int i=0;i<n;i++) parent[i] = -1;
		
		List<int> euler = new List<int>();
		
		var stk = new Stack<int>();
		stk.Push(root);
		while(stk.Count > 0){
			var now = stk.Pop();
			cnt[now]++;
			euler.Add(now);
			if(cnt[now] == 1){
				if(parent[now] != -1) stk.Push(parent[now]);
				foreach(var nxt in E[now]){
					if(cnt[nxt] == 0){
						parent[nxt] = now;
						stk.Push(nxt);
					}
				}
			}
		}
		
		return euler;
	}
	
}