C# program:
using System ; using System . Collections . Generic ; class GFG { static int MAX = 100001 ; public class Node { public int data ; public Node left , right ; public Node ( int data ) { this . data = data ; this . left = this . right = null ; } } class Pair < T , V > { public T first ; public V second ; public Pair ( ) { } public Pair ( T first , V second ) { this . first = first ; this . second = second ; } } static int [ ] level = new int [ MAX ] ; static void findLevels ( Node root ) { if ( root == null ) return ; List < Pair < Node , int > > q = new List < Pair < Node , int > > ( ) ; q . Add ( new Pair < Node , int > ( root , 0 ) ) ; Pair < Node , int > p = new Pair < Node , int > ( ) ; while ( q . Count != 0 ) { p = q [ 0 ] ; q . RemoveAt ( 0 ) ; level [ p . first . data ] = p . second ; if ( p . first . left != null ) q . Add ( new Pair < Node , int > ( p . first . left , p . second + 1 ) ) ; if ( p . first . right != null ) q . Add ( new Pair < Node , int > ( p . first . right , p . second + 1 ) ) ; } } static int [ ] Euler = new int [ MAX ] ; static int idx = 0 ; static void eulerTree ( Node root ) { Euler [ ++ idx ] = root . data ; if ( root . left != null ) { eulerTree ( root . left ) ; Euler [ ++ idx ] = root . data ; } if ( root . right != null ) { eulerTree ( root . right ) ; Euler [ ++ idx ] = root . data ; } } static int [ ] vis = new int [ MAX ] ; static int [ ] L = new int [ MAX ] ; static int [ ] H = new int [ MAX ] ; static void preprocessEuler ( int size ) { for ( int i = 1 ; i <= size ; i ++ ) { L [ i ] = level [ Euler [ i ] ] ; if ( vis [ Euler [ i ] ] == 0 ) { H [ Euler [ i ] ] = i ; vis [ Euler [ i ] ] = 1 ; } } } static Pair < int , int > [ ] seg = new Pair < int , int > [ 4 * MAX ] ; static Pair < int , int > min ( Pair < int , int > a , Pair < int , int > b ) { if ( a . first <= b . first ) return a ; return b ; } static Pair < int , int > buildSegTree ( int low , int high , int pos ) { if ( low == high ) { seg [ pos ] . first = L [ low ] ; seg [ pos ] . second = low ; return seg [ pos ] ; } int mid = low + ( high - low ) / 2 ; buildSegTree ( low , mid , 2 * pos ) ; buildSegTree ( mid + 1 , high , 2 * pos + 1 ) ; seg [ pos ] = min ( seg [ 2 * pos ] , seg [ 2 * pos + 1 ] ) ; return seg [ pos ] ; } static Pair < int , int > LCA ( int qlow , int qhigh , int low , int high , int pos ) { if ( qlow <= low && qhigh >= high ) return seg [ pos ] ; if ( qlow > high qhigh < low ) return new Pair < int , int > ( int . MaxValue , 0 ) ; int mid = low + ( high - low ) / 2 ; return min ( LCA ( qlow , qhigh , low , mid , 2 * pos ) , LCA ( qlow , qhigh , mid + 1 , high , 2 * pos + 1 ) ) ; } static int findDistance ( int n1 , int n2 , int size ) { int prevn1 = n1 , prevn2 = n2 ; n1 = H [ n1 ] ; n2 = H [ n2 ] ; if ( n2 < n1 ) { int temp = n1 ; n1 = n2 ; n2 = temp ; } int lca = LCA ( n1 , n2 , 1 , size , 1 ) . second ; lca = Euler [ lca ] ; return level [ prevn1 ] + level [ prevn2 ] - 2 * level [ lca ] ; } static void preProcessing ( Node root , int N ) { for ( int i = 0 ; i < 4 * MAX ; i ++ ) { seg [ i ] = new Pair < int , int > ( ) ; } eulerTree ( root ) ; findLevels ( root ) ; preprocessEuler ( 2 * N - 1 ) ; buildSegTree ( 1 , 2 * N - 1 , 1 ) ; } public static void Main ( String [ ] args ) { int N = 8 ; Node root = new Node ( 1 ) ; root . left = new Node ( 2 ) ; root . right = new Node ( 3 ) ; root . left . left = new Node ( 4 ) ; root . left . right = new Node ( 5 ) ; root . right . left = new Node ( 6 ) ; root . right . right = new Node ( 7 ) ; root . right . left . right = new Node ( 8 ) ; preProcessing ( root , N ) ; Console . WriteLine ( " Dist ( 4 , ▁ 5 ) ▁ = ▁ " + findDistance ( 4 , 5 , 2 * N - 1 ) ) ; Console . WriteLine ( " Dist ( 4 , ▁ 6 ) ▁ = ▁ " + findDistance ( 4 , 6 , 2 * N - 1 ) ) ; Console . WriteLine ( " Dist ( 3 , ▁ 4 ) ▁ = ▁ " + findDistance ( 3 , 4 , 2 * N - 1 ) ) ; Console . WriteLine ( " Dist ( 2 , ▁ 4 ) ▁ = ▁ " + findDistance ( 2 , 4 , 2 * N - 1 ) ) ; Console . WriteLine ( " Dist ( 8 , ▁ 5 ) ▁ = ▁ " + findDistance ( 8 , 5 , 2 * N - 1 ) ) ; } }

Index/key variables: MAX, i, lca, low, n1, n2, pos, prevn1, prevn2
Accumulator variables: i
Iterator variables: i
Class/struct names: GFG, Node, Pair