





'''simple docstring'''
class 					snake_case					:




 """simple docstring"""



 def __init__(	self	:							List[str]							,     __A	:							str     ):
        __UpperCamelCase	=  val
        # Number of nodes in left subtree
        __UpperCamelCase	=  0
        __UpperCamelCase	=  None
        __UpperCamelCase	=  None
        __UpperCamelCase	=  None






 def 	_lowerCamelCase (	self	:							Any							,     __A	:							Tuple     ):
        assert self.left_tree_size == other.left_tree_size, "Unequal Sizes of Blocks"

        if self.val < other.val:
               __UpperCamelCase	=  self.right
               __UpperCamelCase	=  None
               if self.right:
                      __UpperCamelCase	=  other
               __UpperCamelCase	=  other
               __UpperCamelCase	=  self.left_tree_size * 2 + 1
               return self
        else:
               __UpperCamelCase	=  other.right
               __UpperCamelCase	=  None
               if other.right:
                      __UpperCamelCase	=  self
               __UpperCamelCase	=  self
               __UpperCamelCase	=  other.left_tree_size * 2 + 1
               return other






class 					snake_case					:




 """simple docstring"""



 def __init__(	self	:							Tuple							,     __A	:							List[Any]=None							,     __A	:							Dict=None							,     __A	:							Union[str, Any]=0     ):
        __UpperCamelCase	=  heap_size
        __UpperCamelCase	=  bottom_root
        __UpperCamelCase	=  min_node






 def 	_lowerCamelCase (	self	:							Tuple							,     __A	:							Tuple     ):

        # Empty heaps corner cases
        if other.size == 0:
               return None
        if self.size == 0:
               __UpperCamelCase	=  other.size
               __UpperCamelCase	=  other.bottom_root
               __UpperCamelCase	=  other.min_node
               return None
        # Update size
        __UpperCamelCase	=  self.size + other.size

        # Update min.node
        if self.min_node.val > other.min_node.val:
               __UpperCamelCase	=  other.min_node
        # Merge

        # Order roots by left_subtree_size
        __UpperCamelCase	=  []
        __UpperCamelCase	,						__UpperCamelCase	=  self.bottom_root, other.bottom_root
        while i or j:
               if i and ((not j) or i.left_tree_size < j.left_tree_size):
                      combined_roots_list.append((i, True)     )
                      __UpperCamelCase	=  i.parent
               else:
                      combined_roots_list.append((j, False)     )
                      __UpperCamelCase	=  j.parent
        # Insert links between them
        for i in range(len(__A     ) - 1     ):
               if combined_roots_list[i][1] != combined_roots_list[i + 1][1]:
                      __UpperCamelCase	=  combined_roots_list[i + 1][0]
                      __UpperCamelCase	=  combined_roots_list[i][0]
        # Consecutively merge roots with same left_tree_size
        __UpperCamelCase	=  combined_roots_list[0][0]
        while i.parent:
               if (
                   (i.left_tree_size == i.parent.left_tree_size) and (not i.parent.parent)
               ) or (
                   i.left_tree_size == i.parent.left_tree_size
                   and i.left_tree_size != i.parent.parent.left_tree_size
               ):
                      # Neighbouring Nodes
                      __UpperCamelCase	=  i.left
                      __UpperCamelCase	=  i.parent.parent

                      # Merging trees
                      __UpperCamelCase	=  i.merge_trees(i.parent     )

                      # Updating links
                      __UpperCamelCase	=  previous_node
                      __UpperCamelCase	=  next_node
                      if previous_node:
                             __UpperCamelCase	=  i
                      if next_node:
                             __UpperCamelCase	=  i
               else:
                      __UpperCamelCase	=  i.parent
        # Updating self.bottom_root
        while i.left:
               __UpperCamelCase	=  i.left
        __UpperCamelCase	=  i

        # Update other
        __UpperCamelCase	=  self.size
        __UpperCamelCase	=  self.bottom_root
        __UpperCamelCase	=  self.min_node

        # Return the merged heap
        return self






 def 	_lowerCamelCase (	self	:							List[str]							,     __A	:							Optional[Any]     ):
        if self.size == 0:
               __UpperCamelCase	=  Node(__A     )
               __UpperCamelCase	=  1
               __UpperCamelCase	=  self.bottom_root
        else:
               # Create new node
               __UpperCamelCase	=  Node(__A     )

               # Update size
               self.size += 1

               # update min_node
               if val < self.min_node.val:
                      __UpperCamelCase	=  new_node
               # Put new_node as a bottom_root in heap
               __UpperCamelCase	=  new_node
               __UpperCamelCase	=  self.bottom_root
               __UpperCamelCase	=  new_node

               # Consecutively merge roots with same left_tree_size
               while (
                   self.bottom_root.parent
                   and self.bottom_root.left_tree_size
                   == self.bottom_root.parent.left_tree_size
               ):
                      # Next node
                      __UpperCamelCase	=  self.bottom_root.parent.parent

                      # Merge
                      __UpperCamelCase	=  self.bottom_root.merge_trees(self.bottom_root.parent     )

                      # Update Links
                      __UpperCamelCase	=  next_node
                      __UpperCamelCase	=  None
                      if next_node:
                             __UpperCamelCase	=  self.bottom_root






 def 	_lowerCamelCase (	self	:							List[Any]     ):
        return self.min_node.val






 def 	_lowerCamelCase (	self	:							Dict     ):
        return self.size == 0






 def 	_lowerCamelCase (	self	:							Optional[Any]     ):
        __UpperCamelCase	=  self.min_node.val

        # Last element in heap corner case
        if self.size == 1:
               # Update size
               __UpperCamelCase	=  0

               # Update bottom root
               __UpperCamelCase	=  None

               # Update min_node
               __UpperCamelCase	=  None

               return min_value
        # No right subtree corner case
        # The structure of the tree implies that this should be the bottom root
        # and there is at least one other root
        if self.min_node.right is None:
               # Update size
               self.size -= 1

               # Update bottom root
               __UpperCamelCase	=  self.bottom_root.parent
               __UpperCamelCase	=  None

               # Update min_node
               __UpperCamelCase	=  self.bottom_root
               __UpperCamelCase	=  self.bottom_root.parent
               while i:
                      if i.val < self.min_node.val:
                             __UpperCamelCase	=  i
                      __UpperCamelCase	=  i.parent
               return min_value
        # General case
        # Find the BinomialHeap of the right subtree of min_node
        __UpperCamelCase	=  self.min_node.right
        __UpperCamelCase	=  None
        __UpperCamelCase	=  bottom_of_new
        __UpperCamelCase	=  1

        # Size, min_node and bottom_root
        while bottom_of_new.left:
               __UpperCamelCase	=  size_of_new * 2 + 1
               __UpperCamelCase	=  bottom_of_new.left
               if bottom_of_new.val < min_of_new.val:
                      __UpperCamelCase	=  bottom_of_new
        # Corner case of single root on top left path
        if (not self.min_node.left) and (not self.min_node.parent):
               __UpperCamelCase	=  size_of_new
               __UpperCamelCase	=  bottom_of_new
               __UpperCamelCase	=  min_of_new
               # print("Single root, multiple nodes case")
               return min_value
        # Remaining cases
        # Construct heap of right subtree
        __UpperCamelCase	=  BinomialHeap(
            bottom_root=__A							,     min_node=__A							,     heap_size=__A     )

        # Update size
        __UpperCamelCase	=  self.size - 1 - size_of_new

        # Neighbour nodes
        __UpperCamelCase	=  self.min_node.left
        __UpperCamelCase	=  self.min_node.parent

        # Initialize new bottom_root and min_node
        __UpperCamelCase	=  previous_node or next_node
        __UpperCamelCase	=  next_node

        # Update links of previous_node and search below for new min_node and
        # bottom_root
        if previous_node:
               __UpperCamelCase	=  next_node

               # Update bottom_root and search for min_node below
               __UpperCamelCase	=  previous_node
               __UpperCamelCase	=  previous_node
               while self.bottom_root.left:
                      __UpperCamelCase	=  self.bottom_root.left
                      if self.bottom_root.val < self.min_node.val:
                             __UpperCamelCase	=  self.bottom_root
        if next_node:
               __UpperCamelCase	=  previous_node

               # Search for new min_node above min_node
               __UpperCamelCase	=  next_node
               while i:
                      if i.val < self.min_node.val:
                             __UpperCamelCase	=  i
                      __UpperCamelCase	=  i.parent
        # Merge heaps
        self.merge_heaps(__A     )

        return min_value






 def 	_lowerCamelCase (	self	:							Union[str, Any]     ):
        __UpperCamelCase	=  self.bottom_root
        while top_root.parent:
               __UpperCamelCase	=  top_root.parent
        # preorder
        __UpperCamelCase	=  []
        self.__traversal(__A							,     __A     )
        return heap_pre_order






 def 	_lowerCamelCase (	self	:							str							,     __A	:							str							,     __A	:							Optional[int]							,     __A	:							Union[str, Any]=0     ):
        if curr_node:
               preorder.append((curr_node.val, level)     )
               self.__traversal(curr_node.left							,     __A							,     level + 1     )
               self.__traversal(curr_node.right							,     __A							,     level + 1     )
        else:
               preorder.append(('#', level)     )






 def __str__(	self	:							List[str]     ):
        if self.is_empty():
               return ""
        __UpperCamelCase	=  self.pre_order()

        return "\n".join(('-' * level + str(__A     )) for value, level in preorder_heap     )


# Unit Tests
if __name__ == "__main__":
    import doctest

    doctest.testmod()







'''simple docstring'''
def     lowercase__       (       __lowercase						:  str    ,  __lowercase						:  Tuple					)			->				str:



       """simple docstring"""






       sequence.append(__lowercase					)

       __UpperCamelCase	=  0
       while sequence[index] != target:
              index += 1

       sequence.pop()

       if index == len(__lowercase					):
              return None

       return index


if __name__ == "__main__":
    a__							:							Any			=input('''Enter numbers separated by comma:\n''').strip()
    a__							:							Any			=[int(item) for item in user_input.split(''',''')]

    a__							:							Tuple			=input('''Enter a single number to be found in the list:\n''')
    a__							:							List[Any]			=int(target_input)
    a__							:							List[Any]			=sentinel_linear_search(sequence, target)
    if result is not None:
        print(f'{target} found at positions: {result}')
    else:
        print('''Not found''')
