C# program:
using System ; class Node { public Node left , right ; public int data ; public Node ( int item ) { data = item ; left = right = null ; } } class St_class { public int st ; public int [ ] stt = new int [ 10000 ] ; } public class BinaryTree { Node root ; static int v = 9 ; int [ ] euler = new int [ 2 * v - 1 ] ; int [ ] level = new int [ 2 * v - 1 ] ; int [ ] f_occur = new int [ 2 * v - 1 ] ; int fill ; St_class sc = new St_class ( ) ; int Log2 ( int x ) { int ans = 0 ; int y = x >>= 1 ; while ( y -- != 0 ) ans ++ ; return ans ; } int swap ( int a , int b ) { return a ; } int RMQUtil ( int index , int ss , int se , int qs , int qe , St_class st ) { if ( qs <= ss && qe >= se ) return st . stt [ index ] ; else if ( se < qs ss > qe ) return - 1 ; int mid = ( ss + se ) / 2 ; int q1 = RMQUtil ( 2 * index + 1 , ss , mid , qs , qe , st ) ; int q2 = RMQUtil ( 2 * index + 2 , mid + 1 , se , qs , qe , st ) ; if ( q1 == - 1 ) return q2 ; else if ( q2 == - 1 ) return q1 ; return ( level [ q1 ] < level [ q2 ] ) ? q1 : q2 ; } int RMQ ( St_class st , int n , int qs , int qe ) { if ( qs < 0 qe > n - 1 qs > qe ) { Console . WriteLine ( " Invalid ▁ input " ) ; return - 1 ; } return RMQUtil ( 0 , 0 , n - 1 , qs , qe , st ) ; } void constructSTUtil ( int si , int ss , int se , int [ ] arr , St_class st ) { if ( ss == se ) st . stt [ si ] = ss ; else { int mid = ( ss + se ) / 2 ; constructSTUtil ( si * 2 + 1 , ss , mid , arr , st ) ; constructSTUtil ( si * 2 + 2 , mid + 1 , se , arr , st ) ; if ( arr [ st . stt [ 2 * si + 1 ] ] < arr [ st . stt [ 2 * si + 2 ] ] ) st . stt [ si ] = st . stt [ 2 * si + 1 ] ; else st . stt [ si ] = st . stt [ 2 * si + 2 ] ; } } int constructST ( int [ ] arr , int n ) { int x = Log2 ( n ) + 1 ; int max_size = 2 * ( 1 << x ) - 1 ; sc . stt = new int [ max_size ] ; constructSTUtil ( 0 , 0 , n - 1 , arr , sc ) ; return sc . st ; } void eulerTour ( Node node , int l ) { if ( node != null ) { euler [ fill ] = node . data ; level [ fill ] = l ; fill ++ ; if ( f_occur [ node . data ] == - 1 ) f_occur [ node . data ] = fill - 1 ; if ( node . left != null ) { eulerTour ( node . left , l + 1 ) ; euler [ fill ] = node . data ; level [ fill ] = l ; fill ++ ; } if ( node . right != null ) { eulerTour ( node . right , l + 1 ) ; euler [ fill ] = node . data ; level [ fill ] = l ; fill ++ ; } } } int findLCA ( Node node , int u , int v ) { for ( int i = 0 ; i < f_occur . Length ; i ++ ) f_occur [ i ] = - 1 ; fill = 0 ; eulerTour ( root , 0 ) ; sc . st = constructST ( level , 2 * v - 1 ) ; if ( f_occur [ u ] > f_occur [ v ] ) u = swap ( u , u = v ) ; int qs = f_occur [ u ] ; int qe = f_occur [ v ] ; int index = RMQ ( sc , 2 * v - 1 , qs , qe ) ; return euler [ index ] ; } public static void Main ( String [ ] args ) { BinaryTree tree = new BinaryTree ( ) ; tree . root = new Node ( 1 ) ; tree . root . left = new Node ( 2 ) ; tree . root . right = new Node ( 3 ) ; tree . root . left . left = new Node ( 4 ) ; tree . root . left . right = new Node ( 5 ) ; tree . root . right . left = new Node ( 6 ) ; tree . root . right . right = new Node ( 7 ) ; tree . root . left . right . left = new Node ( 8 ) ; tree . root . left . right . right = new Node ( 9 ) ; int u = 4 , v = 9 ; Console . WriteLine ( " The ▁ LCA ▁ of ▁ node ▁ " + u + " ▁ and ▁ " + v + " ▁ is ▁ " + tree . findLCA ( tree . root , u , v ) ) ; } }

Index/key variables: fill, i, index, max_size, q1, q2, si, u, v
Accumulator variables: ans, fill, i, y
Iterator variables: i
Class/struct names: BinaryTree, Node, St_class