import java.util.ArrayDeque

fun main() {
    val builder = StringBuilder()

    val n = readInputLine().toInt()

    val aArr = readInputLine().split(" ").map { it.toInt() }

    val edges = Array(n) { mutableListOf<Int>() }

    repeat(n - 1) {
        val (u, v) = readInputLine().split(" ").map { it.toInt() - 1 }
        edges[u].add(v)
        edges[v].add(u)
    }

    val ans = IntArray(n)
    val dp = IntArray(n) { Int.MAX_VALUE }

    // (親, ノード, 深さ)のstack
    val stack = ArrayDeque<Triple<Int, Int, Int>>()
    // 巻き戻し用(index, 値, 深さ)のstack
    val rollbackStack = ArrayDeque<Triple<Int, Int, Int>>()

    stack.addFirst(Triple(-1, 0, 0))

    while (stack.isNotEmpty()) {
        val (parent, node, depth) = stack.pollFirst()

        while (rollbackStack.isNotEmpty() && rollbackStack.peekFirst().third >= depth) {
            val (index, value, _) = rollbackStack.pollFirst()
            dp[index] = value
        }

        val writeIndex = lowerBound(dp, aArr[node])

        rollbackStack.addFirst(Triple(writeIndex, dp[writeIndex], depth))

        dp[writeIndex] = aArr[node]

        ans[node] = lowerBound(dp, Int.MAX_VALUE)

        for (e in edges[node]) {
            if (e != parent) {
                stack.addFirst(Triple(node, e, depth + 1))
            }
        }
    }

    for (a in ans) {
        builder.appendln(a)
    }

    print(builder.toString())
}

fun readInputLine(): String {
    return readLine()!!
}

fun lowerBound(arr: IntArray, value: Int): Int {
    var l = -1
    var r = arr.size

    while (r - l > 1) {
        val mid = (r + l) / 2
        if (arr[mid] >= value) {
            r = mid
        } else {
            l = mid
        }
    }

    return r
}
