'''simple docstring'''




from __future__ import annotations

import math
import random
from typing import Any






class 		__A       :






       def __init__(      self      ):
              __UpperCAmelCase  :				list[Any]       				=		[]
              __UpperCAmelCase  :				int       				=		0
              __UpperCAmelCase  :				int       				=		0






       def 			_snake_case						(      self      ):
              return self.head == self.tail






       def 			_snake_case						(      self				,     UpperCamelCase_      ):
              self.data.append(UpperCamelCase_      )
              __UpperCAmelCase  :				str       				=		self.tail + 1






       def 			_snake_case						(      self      ):
              __UpperCAmelCase  :				str       				=		self.data[self.head]
              __UpperCAmelCase  :				Tuple       				=		self.head + 1
              return ret






       def 			_snake_case						(      self      ):
              return self.tail - self.head







       def 			_snake_case						(      self      ):
              print(self.data      )
              print("**************"      )
              print(self.data[self.head : self.tail]      )






class 		__A       :






       def __init__(      self				,     UpperCamelCase_      ):
              __UpperCAmelCase  :				int       				=		data
              __UpperCAmelCase  :				MyNode | None       				=		None
              __UpperCAmelCase  :				MyNode | None       				=		None
              __UpperCAmelCase  :				int       				=		1






       def 			_snake_case						(      self      ):
              return self.data






       def 			_snake_case						(      self      ):
              return self.left






       def 			_snake_case						(      self      ):
              return self.right






       def 			_snake_case						(      self      ):
              return self.height






       def 			_snake_case						(      self				,     UpperCamelCase_      ):
              __UpperCAmelCase  :				Tuple       				=		data






       def 			_snake_case						(      self				,     UpperCamelCase_      ):
              __UpperCAmelCase  :				List[Any]       				=		node






       def 			_snake_case						(      self				,     UpperCamelCase_      ):
              __UpperCAmelCase  :				int       				=		node







       def 			_snake_case						(      self				,     UpperCamelCase_      ):
              __UpperCAmelCase  :				int       				=		height





def _lowercase	(      lowerCamelCase__						)					->       int:





       """simple docstring"""


       if node is None:
              return 0
       return node.get_height()

def _lowercase	(      lowerCamelCase__							,    lowerCamelCase__						)					->       int:





       """simple docstring"""


       if a > b:
              return a
       return b

def _lowercase	(      lowerCamelCase__						)					->       MyNode:





       """simple docstring"""


       print("left rotation node:"							,    node.get_data()						)
       __UpperCAmelCase  :				Union[str, Any]       				=		node.get_left()
       assert ret is not None
       node.set_left(ret.get_right()						)
       ret.set_right(lowerCamelCase__						)
       __UpperCAmelCase  :				Optional[int]       				=		my_max(get_height(node.get_right()						)							,    get_height(node.get_left()						)						) + 1
       node.set_height(lowerCamelCase__						)
       __UpperCAmelCase  :				Optional[int]       				=		my_max(get_height(ret.get_right()						)							,    get_height(ret.get_left()						)						) + 1
       ret.set_height(lowerCamelCase__						)
       return ret

def _lowercase	(      lowerCamelCase__						)					->       MyNode:





       """simple docstring"""


       print("right rotation node:"							,    node.get_data()						)
       __UpperCAmelCase  :				Union[str, Any]       				=		node.get_right()
       assert ret is not None
       node.set_right(ret.get_left()						)
       ret.set_left(lowerCamelCase__						)
       __UpperCAmelCase  :				Tuple       				=		my_max(get_height(node.get_right()						)							,    get_height(node.get_left()						)						) + 1
       node.set_height(lowerCamelCase__						)
       __UpperCAmelCase  :				Optional[Any]       				=		my_max(get_height(ret.get_right()						)							,    get_height(ret.get_left()						)						) + 1
       ret.set_height(lowerCamelCase__						)
       return ret

def _lowercase	(      lowerCamelCase__						)					->       MyNode:





       """simple docstring"""


       __UpperCAmelCase  :				Dict       				=		node.get_left()
       assert left_child is not None
       node.set_left(left_rotation(lowerCamelCase__						)						)
       return right_rotation(lowerCamelCase__						)

def _lowercase	(      lowerCamelCase__						)					->       MyNode:





       """simple docstring"""


       __UpperCAmelCase  :				List[str]       				=		node.get_right()
       assert right_child is not None
       node.set_right(right_rotation(lowerCamelCase__						)						)
       return left_rotation(lowerCamelCase__						)

def _lowercase	(      lowerCamelCase__							,    lowerCamelCase__						)					->       MyNode | None:





       """simple docstring"""


       if node is None:
              return MyNode(lowerCamelCase__						)
       if data < node.get_data():
              node.set_left(insert_node(node.get_left()							,    lowerCamelCase__						)						)
              if (
                  get_height(node.get_left()						) - get_height(node.get_right()						) == 2
              ):  # an unbalance detected
                     __UpperCAmelCase  :				Optional[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
                            __UpperCAmelCase  :				Dict       				=		right_rotation(lowerCamelCase__						)
                     else:
                            __UpperCAmelCase  :				Union[str, Any]       				=		lr_rotation(lowerCamelCase__						)
       else:
              node.set_right(insert_node(node.get_right()							,    lowerCamelCase__						)						)
              if get_height(node.get_right()						) - get_height(node.get_left()						) == 2:
                     __UpperCAmelCase  :				Any       				=		node.get_right()
                     assert right_child is not None
                     if data < right_child.get_data():
                            __UpperCAmelCase  :				Union[str, Any]       				=		rl_rotation(lowerCamelCase__						)
                     else:
                            __UpperCAmelCase  :				Any       				=		left_rotation(lowerCamelCase__						)
       __UpperCAmelCase  :				int       				=		my_max(get_height(node.get_right()						)							,    get_height(node.get_left()						)						) + 1
       node.set_height(lowerCamelCase__						)
       return node

def _lowercase	(      lowerCamelCase__						)					->       Any:





       """simple docstring"""


       while True:
              __UpperCAmelCase  :				Tuple       				=		root.get_right()
              if right_child is None:
                     break
              __UpperCAmelCase  :				List[Any]       				=		right_child
       return root.get_data()

def _lowercase	(      lowerCamelCase__						)					->       Any:





       """simple docstring"""


       while True:
              __UpperCAmelCase  :				Optional[int]       				=		root.get_left()
              if left_child is None:
                     break
              __UpperCAmelCase  :				List[Any]       				=		left_child
       return root.get_data()

def _lowercase	(      lowerCamelCase__							,    lowerCamelCase__						)					->       MyNode | None:





       """simple docstring"""


       __UpperCAmelCase  :				int       				=		root.get_left()
       __UpperCAmelCase  :				Tuple       				=		root.get_right()
       if root.get_data() == data:
              if left_child is not None and right_child is not None:
                     __UpperCAmelCase  :				List[Any]       				=		get_left_most(lowerCamelCase__						)
                     root.set_data(lowerCamelCase__						)
                     root.set_right(del_node(lowerCamelCase__							,    lowerCamelCase__						)						)
              elif left_child is not None:
                     __UpperCAmelCase  :				Tuple       				=		left_child
              elif right_child is not None:
                     __UpperCAmelCase  :				Optional[int]       				=		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(lowerCamelCase__							,    lowerCamelCase__						)						)
       else:  # root.get_data() < data
              if right_child is None:
                     return root
              else:
                     root.set_right(del_node(lowerCamelCase__							,    lowerCamelCase__						)						)

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






class 		__A       :






       def __init__(      self      ):
              __UpperCAmelCase  :				MyNode | None       				=		None






       def 			_snake_case						(      self      ):
              return get_height(self.root      )






       def 			_snake_case						(      self				,     UpperCamelCase_      ):
              print("insert:" + str(UpperCamelCase_      )      )
              __UpperCAmelCase  :				List[Any]       				=		insert_node(self.root				,     UpperCamelCase_      )






       def 			_snake_case						(      self				,     UpperCamelCase_      ):
              print("delete:" + str(UpperCamelCase_      )      )
              if self.root is None:
                     print("Tree is empty!"      )
                     return
              __UpperCAmelCase  :				List[Any]       				=		del_node(self.root				,     UpperCamelCase_      )







       def __str__(      self				,     ):  # a level traversale, gives a more intuitive look on the tree
              __UpperCAmelCase  :				List[str]       				=		""
              __UpperCAmelCase  :				int       				=		MyQueue()
              q.push(self.root      )
              __UpperCAmelCase  :				Optional[Any]       				=		self.get_height()
              if layer == 0:
                     return output
              __UpperCAmelCase  :				Union[str, Any]       				=		0
              while not q.is_empty():
                     __UpperCAmelCase  :				List[Any]       				=		q.pop()
                     __UpperCAmelCase  :				Optional[Any]       				=		" " * int(math.pow(2				,     layer - 1      )      )
                     output += space
                     if node is None:
                            output += "*"
                            q.push(UpperCamelCase_      )
                            q.push(UpperCamelCase_      )
                     else:
                            output += str(node.get_data()      )
                            q.push(node.get_left()      )
                            q.push(node.get_right()      )
                     output += space
                     __UpperCAmelCase  :				List[Any]       				=		cnt + 1
                     for i in range(1_00      ):
                            if cnt == math.pow(2				,     UpperCamelCase_      ) - 1:
                                   __UpperCAmelCase  :				Dict       				=		layer - 1
                                   if layer == 0:
                                          output += "\n*************************************"
                                          return output
                                   output += "\n"
                                   break
              output += "\n*************************************"
              return output





def _lowercase	(      )					->       None:





       """simple docstring"""


       import doctest

       doctest.testmod()


if __name__ == "__main__":
   _test()
   _a   :	Dict 							=   AVLtree()
   _a   :	List[str] 							=   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))







'''simple docstring'''




def _lowercase	(      lowerCamelCase__							,    lowerCamelCase__						)					->       int:





       """simple docstring"""


       return number | (1 << position)

def _lowercase	(      lowerCamelCase__							,    lowerCamelCase__						)					->       int:





       """simple docstring"""


       return number & ~(1 << position)

def _lowercase	(      lowerCamelCase__							,    lowerCamelCase__						)					->       int:





       """simple docstring"""


       return number ^ (1 << position)

def _lowercase	(      lowerCamelCase__							,    lowerCamelCase__						)					->       bool:





       """simple docstring"""


       return ((number >> position) & 1) == 1

def _lowercase	(      lowerCamelCase__							,    lowerCamelCase__						)					->       int:





       """simple docstring"""


       return int((number & (1 << position)) != 0						)


if __name__ == "__main__":
   import doctest

   doctest.testmod()






