Here's path maximum query:
function pathMax(u, v)
result := -infinity
while chainHead[u] ≠ chainHead[v]
if depth[chainHead[u]] < depth[chainHead[v]] then
swap(u, v)
// Query from u to its chain head
result := max(result, segmentTreeQuery(pos[chainHead[u]], pos[u]))
u := parent[chainHead[u]]
// Now u and v are in the same chain
if depth[u] > depth[v] then
swap(u, v)
result := max(result, segmentTreeQuery(pos[u], pos[v]))
return result
Time: . The outer while loop runs times, each iteration does an segment tree query.