from __future__ import annotations

from abc import abstractmethod
from collections.abc import Iterable
from typing import Generic, Protocol, TypeVar







class 			__snake_case   (     lowerCamelCase__   ):
 @abstractmethod
 def __lt__(  self		,   snake_case__						)	->							bool:
       '''simple docstring'''





       pass
 @abstractmethod
 def __gt__(  self		,   snake_case__						)	->							bool:
       '''simple docstring'''





       pass






 @abstractmethod
 def __eq__(  self		,   snake_case__						)	->							bool:
       '''simple docstring'''





       pass



__snake_case			      =    TypeVar('''T''', bound=Comparable)







class 			__snake_case   (     Generic[T]   ):
 def __init__(  self						)	->							None:
       '''simple docstring'''





       UpperCAmelCase    : list[T]      =[]
       UpperCAmelCase    : int      =0
 def __repr__(  self						)	->							str:
       '''simple docstring'''





       return str(self.h						)
 def 	UpperCAmelCase__       (  self		,   snake_case__						)	->							int | None:
       '''simple docstring'''





       if child_idx > 0:
             return (child_idx - 1) // 2
       return None
 def 	UpperCAmelCase__       (  self		,   snake_case__						)	->							int | None:
       '''simple docstring'''





       UpperCAmelCase    : Union[str, Any]      =2 * parent_idx + 1
       if left_child_index < self.heap_size:
             return left_child_index
       return None
 def 	UpperCAmelCase__       (  self		,   snake_case__						)	->							int | None:
       '''simple docstring'''





       UpperCAmelCase    : List[str]      =2 * parent_idx + 2
       if right_child_index < self.heap_size:
             return right_child_index
       return None
 def 	UpperCAmelCase__       (  self		,   snake_case__						)	->							None:
       '''simple docstring'''





       if index < self.heap_size:
             UpperCAmelCase    : int      =index
             UpperCAmelCase    : Union[str, Any]      =self.left_child_idx(snake_case__						)
             UpperCAmelCase    : int      =self.right_child_idx(snake_case__						)
             # check which child is larger than its parent
             if left_child is not None and self.h[left_child] > self.h[violation]:
                   UpperCAmelCase    : Union[str, Any]      =left_child
             if right_child is not None and self.h[right_child] > self.h[violation]:
                   UpperCAmelCase    : str      =right_child
             # if violation indeed exists
             if violation != index:
                   # swap to fix the violation
                   UpperCAmelCase  ,						UpperCAmelCase    : int      =self.h[index], self.h[violation]
                   # fix the subsequent violation recursively if any
                   self.max_heapify(snake_case__						)
 def 	UpperCAmelCase__       (  self		,   snake_case__						)	->							None:
       '''simple docstring'''





       UpperCAmelCase    : Dict      =list(snake_case__						)
       UpperCAmelCase    : List[str]      =len(self.h						)
       if self.heap_size > 1:
             # max_heapify from right to left but exclude leaves (last level)
             for i in range(self.heap_size // 2 - 1		,   -1		,   -1						):
                   self.max_heapify(snake_case__						)
 def 	UpperCAmelCase__       (  self						)	->							T:
       '''simple docstring'''





       if self.heap_size >= 2:
             UpperCAmelCase    : Union[str, Any]      =self.h[0]
             UpperCAmelCase    : int      =self.h.pop(-1						)
             self.heap_size -= 1
             self.max_heapify(0						)
             return me
       elif self.heap_size == 1:
             self.heap_size -= 1
             return self.h.pop(-1						)
       else:
             raise Exception('''Empty heap'''						)
 def 	UpperCAmelCase__       (  self		,   snake_case__						)	->							None:
       '''simple docstring'''





       self.h.append(snake_case__						)
       UpperCAmelCase    : Any      =(self.heap_size - 1) // 2
       self.heap_size += 1
       while idx >= 0:
             self.max_heapify(snake_case__						)
             UpperCAmelCase    : int      =(idx - 1) // 2






 def 	UpperCAmelCase__       (  self						)	->							None:
       '''simple docstring'''





       UpperCAmelCase    : Optional[int]      =self.heap_size
       for j in range(size - 1		,   0		,   -1						):
             UpperCAmelCase  ,						UpperCAmelCase    : List[str]      =self.h[j], self.h[0]
             self.heap_size -= 1
             self.max_heapify(0						)
       UpperCAmelCase    : Tuple      =size


if __name__ == "__main__":
     import doctest

     # run doc test
     doctest.testmod()

     # demo
     for unsorted in [
         [0],
         [2],
         [3, 5],
         [5, 3],
         [5, 5],
         [0, 0, 0, 0],
         [1, 1, 1, 1],
         [2, 2, 3, 5],
         [0, 2, 2, 3, 5],
         [2, 5, 3, 0, 2, 3, 0, 3],
         [6, 1, 2, 7, 9, 3, 4, 5, 10, 8],
         [1_03, 9, 1, 7, 11, 15, 25, 2_01, 2_09, 1_07, 5],
         [-45, -2, -5],
     ]:
          print(f'unsorted array: {unsorted}')

          __snake_case			      =    Heap()
          heap.build_max_heap(unsorted)
          print(f'after build heap: {heap}')

          print(f'max value: {heap.extract_max()}')
          print(f'after max value removed: {heap}')

          heap.insert(1_00)
          print(f'after new value 100 inserted: {heap}')

          heap.heap_sort()
          print(f'heap-sorted array: {heap}\n')

import math





def   lowerCAmelCase_ (				__lowerCAmelCase						)->  list[int]:






      '''simple docstring'''





      if not isinstance(__lowerCAmelCase		,					__lowerCAmelCase						):
            UpperCAmelCase    : Union[str, Any]      =f'''Input value of [number={number}] must be an integer'''
            raise TypeError(__lowerCAmelCase						)
      if number < 1:
            UpperCAmelCase    : Dict      =f'''Input value of [number={number}] must be a positive integer'''
            raise ValueError(__lowerCAmelCase						)
      UpperCAmelCase    : Dict      =[number]
      while number != 1:
            if number % 2 == 0:
                  UpperCAmelCase    : Optional[Any]      =math.floor(math.sqrt(__lowerCAmelCase						)						)
            else:
                  UpperCAmelCase    : List[str]      =math.floor(
                      math.sqrt(__lowerCAmelCase						) * math.sqrt(__lowerCAmelCase						) * math.sqrt(__lowerCAmelCase						)						)
            sequence.append(__lowerCAmelCase						)
      return sequence


if __name__ == "__main__":
     import doctest

     doctest.testmod()
