Java program:
import java . util . * ; class GFG { static final int MAX = 1000 ; static final int log = 10 ; static int [ ] level = new int [ MAX ] ; static int [ ] [ ] lca = new int [ MAX ] [ log ] ; static int [ ] [ ] minWeight = new int [ MAX ] [ log ] ; static int [ ] [ ] maxWeight = new int [ MAX ] [ log ] ; static Vector < Integer > [ ] graph = new Vector [ MAX ] ; static int [ ] weight = new int [ MAX ] ; private static void swap ( int x , int y ) { int temp = x ; x = y ; y = temp ; } static void addEdge ( int u , int v ) { graph [ u ] . add ( v ) ; graph [ v ] . add ( u ) ; } static void dfs ( int node , int parent , int h ) { lca [ node ] [ 0 ] = parent ; level [ node ] = h ; if ( parent != - 1 ) { minWeight [ node ] [ 0 ] = Math . min ( weight [ node ] , weight [ parent ] ) ; maxWeight [ node ] [ 0 ] = Math . max ( weight [ node ] , weight [ parent ] ) ; } for ( int i = 1 ; i < log ; i ++ ) { if ( lca [ node ] [ i - 1 ] != - 1 ) { lca [ node ] [ i ] = lca [ lca [ node ] [ i - 1 ] ] [ i - 1 ] ; minWeight [ node ] [ i ] = Math . min ( minWeight [ node ] [ i - 1 ] , minWeight [ lca [ node ] [ i - 1 ] ] [ i - 1 ] ) ; maxWeight [ node ] [ i ] = Math . max ( maxWeight [ node ] [ i - 1 ] , maxWeight [ lca [ node ] [ i - 1 ] ] [ i - 1 ] ) ; } } for ( int i : graph [ node ] ) { if ( i == parent ) continue ; dfs ( i , node , h + 1 ) ; } } static void findMinMaxWeight ( int u , int v ) { int minWei = Integer . MAX_VALUE ; int maxWei = Integer . MIN_VALUE ; if ( level [ u ] > level [ v ] ) swap ( u , v ) ; for ( int i = log - 1 ; i >= 0 ; i -- ) { if ( lca [ v ] [ i ] != - 1 && level [ lca [ v ] [ i ] ] >= level [ u ] ) { minWei = Math . min ( minWei , minWeight [ v ] [ i ] ) ; maxWei = Math . max ( maxWei , maxWeight [ v ] [ i ] ) ; v = lca [ v ] [ i ] ; } } if ( v == u ) { System . out . print ( minWei + " ▁ " + maxWei + "NEW_LINE"); } else { for ( int i = log - 1 ; i >= 0 ; i -- ) { if ( v == - 1 ) v ++ ; if ( lca [ v ] [ i ] != lca [ u ] [ i ] ) { minWei = Math . min ( minWei , Math . min ( minWeight [ v ] [ i ] , minWeight [ u ] [ i ] ) ) ; maxWei = Math . max ( maxWei , Math . max ( maxWeight [ v ] [ i ] , maxWeight [ u ] [ i ] ) ) ; v = lca [ v ] [ i ] ; u = lca [ u ] [ i ] ; } } if ( u == - 1 ) u ++ ; minWei = Math . min ( minWei , Math . min ( minWeight [ v ] [ 0 ] , minWeight [ u ] [ 0 ] ) ) ; maxWei = Math . max ( maxWei , Math . max ( maxWeight [ v ] [ 0 ] , maxWeight [ u ] [ 0 ] ) ) ; System . out . print ( minWei + " ▁ " + maxWei + "NEW_LINE"); } } public static void main ( String [ ] args ) { int n = 5 ; for ( int i = 0 ; i < graph . length ; i ++ ) graph [ i ] = new Vector < Integer > ( ) ; addEdge ( 1 , 2 ) ; addEdge ( 1 , 5 ) ; addEdge ( 2 , 4 ) ; addEdge ( 2 , 3 ) ; weight [ 1 ] = - 1 ; weight [ 2 ] = 5 ; weight [ 3 ] = - 1 ; weight [ 4 ] = 3 ; weight [ 5 ] = - 2 ; for ( int i = 1 ; i <= n ; i ++ ) { for ( int j = 0 ; j < log ; j ++ ) { lca [ i ] [ j ] = - 1 ; minWeight [ i ] [ j ] = Integer . MAX_VALUE ; maxWeight [ i ] [ j ] = Integer . MIN_VALUE ; } } dfs ( 1 , - 1 , 0 ) ; findMinMaxWeight ( 1 , 3 ) ; findMinMaxWeight ( 2 , 4 ) ; findMinMaxWeight ( 3 , 5 ) ; } }

Index/key variables: MAX, i, j, log, node, parent, u, v
Accumulator variables: i, j, u, v
Iterator variables: i, j
Class/struct names: GFG