


from __future__ import annotations

import math
import random
from typing import Any





class   __a      :
 def __init__(       self			) ->    Optional[int]:




        '''simple docstring'''
        lowercase__:       Optional[int]        =       []
        lowercase__:       List[str]        =       0
        lowercase__:       Optional[Any]        =       0
 def 		SCREAMING_SNAKE_CASE__       (       self			) ->    List[Any]:




        '''simple docstring'''
        return self.head == self.tail
 def 		SCREAMING_SNAKE_CASE__       (       self    ,			lowerCAmelCase__			) ->    List[Any]:




        '''simple docstring'''
        self.data.append(a__			)
        lowercase__:       List[str]        =       self.tail + 1
 def 		SCREAMING_SNAKE_CASE__       (       self			) ->    List[Any]:




        '''simple docstring'''
        lowercase__:       List[Any]        =       self.data[self.head]
        lowercase__:       Optional[int]        =       self.head + 1
        return ret
 def 		SCREAMING_SNAKE_CASE__       (       self			) ->    Union[str, Any]:




        '''simple docstring'''
        return self.tail - self.head
 def 		SCREAMING_SNAKE_CASE__       (       self			) ->    Optional[Any]:




        '''simple docstring'''
        print(self.data			)
        print('**************'			)
        print(self.data[self.head : self.tail]			)





class   __a      :
 def __init__(       self    ,			lowerCAmelCase__			) ->    List[str]:




        '''simple docstring'''
        lowercase__:       Tuple        =       data
        lowercase__:       Dict        =       None
        lowercase__:       Union[str, Any]        =       None
        lowercase__:       List[Any]        =       1
 def 		SCREAMING_SNAKE_CASE__       (       self			) ->    int:




        '''simple docstring'''
        return self.data
 def 		SCREAMING_SNAKE_CASE__       (       self			) ->    Any:




        '''simple docstring'''
        return self.left
 def 		SCREAMING_SNAKE_CASE__       (       self			) ->    Optional[Any]:




        '''simple docstring'''
        return self.right
 def 		SCREAMING_SNAKE_CASE__       (       self			) ->    List[Any]:




        '''simple docstring'''
        return self.height
 def 		SCREAMING_SNAKE_CASE__       (       self    ,			lowerCAmelCase__			) ->    List[Any]:




        '''simple docstring'''
        lowercase__:       Tuple        =       data
 def 		SCREAMING_SNAKE_CASE__       (       self    ,			lowerCAmelCase__			) ->    Optional[int]:




        '''simple docstring'''
        lowercase__:       Optional[int]        =       node
 def 		SCREAMING_SNAKE_CASE__       (       self    ,			lowerCAmelCase__			) ->    Optional[Any]:




        '''simple docstring'''
        lowercase__:       str        =       node
 def 		SCREAMING_SNAKE_CASE__       (       self    ,			lowerCAmelCase__			) ->    int:




        '''simple docstring'''
        lowercase__:       Optional[int]        =       height





def        snake_case_					(  snake_case					)  ->    int:
       if node is None:
              return 0
       return node.get_height()




def        snake_case_					(  snake_case      ,							snake_case					)  ->    int:
       if a > b:
              return a
       return b




def        snake_case_					(  snake_case					)  ->    MyNode:
       print('left rotation node:'      ,							node.get_data()					)
       lowercase__:       str        =       node.get_left()
       assert ret is not None
       node.set_left(ret.get_right()					)
       ret.set_right(snake_case					)
       lowercase__:       str        =       my_max(get_height(node.get_right()					)      ,							get_height(node.get_left()					)					) + 1
       node.set_height(snake_case					)
       lowercase__:       Optional[Any]        =       my_max(get_height(ret.get_right()					)      ,							get_height(ret.get_left()					)					) + 1
       ret.set_height(snake_case					)
       return ret




def        snake_case_					(  snake_case					)  ->    MyNode:
       print('right rotation node:'      ,							node.get_data()					)
       lowercase__:       Tuple        =       node.get_right()
       assert ret is not None
       node.set_right(ret.get_left()					)
       ret.set_left(snake_case					)
       lowercase__:       List[str]        =       my_max(get_height(node.get_right()					)      ,							get_height(node.get_left()					)					) + 1
       node.set_height(snake_case					)
       lowercase__:       Dict        =       my_max(get_height(ret.get_right()					)      ,							get_height(ret.get_left()					)					) + 1
       ret.set_height(snake_case					)
       return ret




def        snake_case_					(  snake_case					)  ->    MyNode:
       lowercase__:       List[str]        =       node.get_left()
       assert left_child is not None
       node.set_left(left_rotation(snake_case					)					)
       return right_rotation(snake_case					)




def        snake_case_					(  snake_case					)  ->    MyNode:
       lowercase__:       List[str]        =       node.get_right()
       assert right_child is not None
       node.set_right(right_rotation(snake_case					)					)
       return left_rotation(snake_case					)




def        snake_case_					(  snake_case      ,							snake_case					)  ->    MyNode | None:
       if node is None:
              return MyNode(snake_case					)
       if data < node.get_data():
              node.set_left(insert_node(node.get_left()      ,							snake_case					)					)
              if (
                  get_height(node.get_left()					) - get_height(node.get_right()					) == 2
              ):  # an unbalance detected
                     lowercase__:       Union[str, Any]        =       node.get_left()
                     assert left_child is not None
                     if (
                         data < left_child.get_data()
                     ):  # new node is the left child of the left child
                            lowercase__:       Any        =       right_rotation(snake_case					)
                     else:
                            lowercase__:       Optional[int]        =       lr_rotation(snake_case					)
       else:
              node.set_right(insert_node(node.get_right()      ,							snake_case					)					)
              if get_height(node.get_right()					) - get_height(node.get_left()					) == 2:
                     lowercase__:       int        =       node.get_right()
                     assert right_child is not None
                     if data < right_child.get_data():
                            lowercase__:       Optional[int]        =       rl_rotation(snake_case					)
                     else:
                            lowercase__:       Union[str, Any]        =       left_rotation(snake_case					)
       lowercase__:       str        =       my_max(get_height(node.get_right()					)      ,							get_height(node.get_left()					)					) + 1
       node.set_height(snake_case					)
       return node




def        snake_case_					(  snake_case					)  ->    Any:
       while True:
              lowercase__:       int        =       root.get_right()
              if right_child is None:
                     break
              lowercase__:       List[str]        =       right_child
       return root.get_data()




def        snake_case_					(  snake_case					)  ->    Any:
       while True:
              lowercase__:       Tuple        =       root.get_left()
              if left_child is None:
                     break
              lowercase__:       Optional[int]        =       left_child
       return root.get_data()




def        snake_case_					(  snake_case      ,							snake_case					)  ->    MyNode | None:
       lowercase__:       Union[str, Any]        =       root.get_left()
       lowercase__:       Union[str, Any]        =       root.get_right()
       if root.get_data() == data:
              if left_child is not None and right_child is not None:
                     lowercase__:       Optional[int]        =       get_left_most(snake_case					)
                     root.set_data(snake_case					)
                     root.set_right(del_node(snake_case      ,							snake_case					)					)
              elif left_child is not None:
                     lowercase__:       Union[str, Any]        =       left_child
              elif right_child is not None:
                     lowercase__:       Dict        =       right_child
              else:
                     return None
       elif root.get_data() > data:
              if left_child is None:
                     print('No such data'					)
                     return root
              else:
                     root.set_left(del_node(snake_case      ,							snake_case					)					)
       else:  # root.get_data() < data
              if right_child is None:
                     return root
              else:
                     root.set_right(del_node(snake_case      ,							snake_case					)					)

       if get_height(snake_case					) - get_height(snake_case					) == 2:
              assert right_child is not None
              if get_height(right_child.get_right()					) > get_height(right_child.get_left()					):
                     lowercase__:       Dict        =       left_rotation(snake_case					)
              else:
                     lowercase__:       Any        =       rl_rotation(snake_case					)
       elif get_height(snake_case					) - get_height(snake_case					) == -2:
              assert left_child is not None
              if get_height(left_child.get_left()					) > get_height(left_child.get_right()					):
                     lowercase__:       List[Any]        =       right_rotation(snake_case					)
              else:
                     lowercase__:       Optional[int]        =       lr_rotation(snake_case					)
       lowercase__:       Optional[int]        =       my_max(get_height(root.get_right()					)      ,							get_height(root.get_left()					)					) + 1
       root.set_height(snake_case					)
       return root





class   __a      :
 def __init__(       self			) ->    Dict:




        '''simple docstring'''
        lowercase__:       List[Any]        =       None
 def 		SCREAMING_SNAKE_CASE__       (       self			) ->    Optional[Any]:




        '''simple docstring'''
        return get_height(self.root			)
 def 		SCREAMING_SNAKE_CASE__       (       self    ,			lowerCAmelCase__			) ->    Dict:




        '''simple docstring'''
        print('insert:' + str(a__			)			)
        lowercase__:       Union[str, Any]        =       insert_node(self.root    ,			a__			)
 def 		SCREAMING_SNAKE_CASE__       (       self    ,			lowerCAmelCase__			) ->    int:




        '''simple docstring'''
        print('delete:' + str(a__			)			)
        if self.root is None:
               print('Tree is empty!'			)
               return
        lowercase__:       List[Any]        =       del_node(self.root    ,			a__			)
 def __str__(       self    ,			) ->    int:  # a level traversale, gives a more intuitive look on the tree




        '''simple docstring'''
        lowercase__:       Optional[int]        =       ''
        lowercase__:       List[Any]        =       MyQueue()
        q.push(self.root			)
        lowercase__:       str        =       self.get_height()
        if layer == 0:
               return output
        lowercase__:       Any        =       0
        while not q.is_empty():
               lowercase__:       Tuple        =       q.pop()
               lowercase__:       str        =       ' ' * int(math.pow(2    ,			layer - 1			)			)
               output += space
               if node is None:
                      output += "*"
                      q.push(a__			)
                      q.push(a__			)
               else:
                      output += str(node.get_data()			)
                      q.push(node.get_left()			)
                      q.push(node.get_right()			)
               output += space
               lowercase__:       Dict        =       cnt + 1
               for i in range(100			):
                      if cnt == math.pow(2    ,			a__			) - 1:
                             lowercase__:       Optional[int]        =       layer - 1
                             if layer == 0:
                                    output += "\n*************************************"
                                    return output
                             output += "\n"
                             break
        output += "\n*************************************"
        return output





def        snake_case_					(  )  ->    None:
       import doctest

       doctest.testmod()


if __name__ == "__main__":
 _test()
 __lowerCAmelCase			=							AVLtree()
 __lowerCAmelCase			=							list(range(10))
 random.shuffle(lst)
 for i in lst:
  t.insert(i)
  print(str(t))
 random.shuffle(lst)
 for i in lst:
  t.del_node(i)
  print(str(t))



from math import pow




def        snake_case_					(  snake_case      ,							snake_case      ,							snake_case      ,							snake_case      ,							snake_case      ,							)  ->    tuple[int, int]:
       if current_sum == needed_sum:
              # If the sum of the powers is equal to needed_sum, then we have a solution.
              solutions_count += 1
              return current_sum, solutions_count

       lowercase__:       int        =       int(pow(snake_case      ,							snake_case					)					)
       if current_sum + i_to_n <= needed_sum:
              # If the sum of the powers is less than needed_sum, then continue adding powers.
              current_sum += i_to_n
              lowercase__      ,						lowercase__:       Any        =       backtrack(
                  snake_case      ,							snake_case      ,							current_number + 1      ,							snake_case      ,							snake_case					)
              current_sum -= i_to_n
       if i_to_n < needed_sum:
              # If the power of i is less than needed_sum, then try with the next power.
              lowercase__      ,						lowercase__:       Optional[int]        =       backtrack(
                  snake_case      ,							snake_case      ,							current_number + 1      ,							snake_case      ,							snake_case					)
       return current_sum, solutions_count




def        snake_case_					(  snake_case      ,							snake_case					)  ->    int:
       if not (1 <= needed_sum <= 10_00 and 2 <= power <= 10):
              raise ValueError(
                  'Invalid input\n'
                  'needed_sum must be between 1 and 1000, power between 2 and 10.'					)

       return backtrack(snake_case      ,							snake_case      ,							1      ,							0      ,							0					)[1]  # Return the solutions_count


if __name__ == "__main__":
 import doctest

 doctest.testmod()


