


'''simple docstring'''



import sys

snake_case_    :Dict				       =     (
    "73167176531330624919225119674426574742355349194934"
    "96983520312774506326239578318016984801869478851843"
    "85861560789112949495459501737958331952853208805511"
    "12540698747158523863050715693290963295227443043557"
    "66896648950445244523161731856403098711121722383113"
    "62229893423380308135336276614282806444486645238749"
    "30358907296290491560440772390713810515859307960866"
    "70172427121883998797908792274921901699720888093776"
    "65727333001053367881220235421809751254540594752243"
    "52584907711670556013604839586446706324415722155397"
    "53697817977846174064955149290862569321978468622482"
    "83972241375657056057490261407972968652414535100474"
    "82166370484403199890008895243450658541227588666881"
    "16427171479924442928230863465674813919123162824586"
    "17866458359124566529476545682848912883142607690042"
    "24219022671055626321111109370544217506941658960408"
    "07198403850962455444362981230987879927244284909188"
    "84580156166097919133875499200524063689912560717606"
    "05886116467109405077541002256983155200055935729725"
    "71636269561882670428252483600823257530420752963450"
)




def 			_a			(		_lowercase      :			str						):





     '''simple docstring'''






     __UpperCAmelCase			:				Union[str, Any]													=    1
     for digit in s:
          product *= int(_lowercase						)
     return product




def 			_a			(		_lowercase      :			str = N						):





     '''simple docstring'''






     __UpperCAmelCase			:				List[str]													=    -sys.maxsize - 1
     __UpperCAmelCase			:				Dict													=    n[:13]
     __UpperCAmelCase			:				Tuple													=    13
     while cur_index < len(_lowercase						) - 13:
          if int(n[cur_index]						) >= int(substr[0]						):
               __UpperCAmelCase			:				Tuple													=    substr[1:] + n[cur_index]
               cur_index += 1
          else:
               __UpperCAmelCase			:				int													=    max(_lowercase    ,      str_eval(_lowercase						)						)
               __UpperCAmelCase			:				Tuple													=    n[cur_index : cur_index + 13]
               cur_index += 13
     return largest_product


if __name__ == "__main__":
      print(f"""{solution() = }""")



'''simple docstring'''



from collections.abc import Iterable
from typing import Any



class 			a       :


     """simple docstring"""






     def __init__(       self  :	Any							,				snake_case  :	int | None = None    )		->							int:
          __UpperCAmelCase			:				str													=    value
          __UpperCAmelCase			:				Node | None													=    None  # Added in order to delete a node easier
          __UpperCAmelCase			:				Node | None													=    None
          __UpperCAmelCase			:				Node | None													=    None






     def __repr__(       self  :	str    )		->							str:
          from pprint import pformat

          if self.left is None and self.right is None:
               return str(self.value    )
          return pformat({f'{self.value}': (self.left, self.right)}							,				indent=1    )



class 			a       :


     """simple docstring"""






     def __init__(       self  :	Optional[int]							,				snake_case  :	Node | None = None    )		->							str:
          __UpperCAmelCase			:				Optional[Any]													=    root

     def __str__(       self  :	str    )		->							str:
          return str(self.root    )

     def 				lowerCamelCase__				(       self  :	Union[str, Any]							,				snake_case  :	Node							,				snake_case  :	Node | None    )		->							None:
          if new_children is not None:  # reset its kids
               __UpperCAmelCase			:				List[str]													=    node.parent
          if node.parent is not None:  # reset its parent
               if self.is_right(snake_case    ):  # If it is the right children
                    __UpperCAmelCase			:				int													=    new_children
               else:
                    __UpperCAmelCase			:				Tuple													=    new_children
          else:
               __UpperCAmelCase			:				List[Any]													=    new_children

     def 				lowerCamelCase__				(       self  :	Optional[int]							,				snake_case  :	Node    )		->							bool:
          if node.parent and node.parent.right:
               return node == node.parent.right
          return False

     def 				lowerCamelCase__				(       self  :	int    )		->							bool:
          return self.root is None

     def 				lowerCamelCase__				(       self  :	Optional[int]							,				snake_case  :	Optional[Any]    )		->							None:
          __UpperCAmelCase			:				int													=    Node(snake_case    )  # create a new Node
          if self.empty():  # if Tree is empty
               __UpperCAmelCase			:				List[Any]													=    new_node  # set its root
          else:  # Tree is not empty
               __UpperCAmelCase			:				Tuple													=    self.root  # from root
               if parent_node is None:
                    return
               while True:  # While we don't get to a leaf
                    if value < parent_node.value:  # We go left
                         if parent_node.left is None:
                              __UpperCAmelCase			:				Optional[int]													=    new_node  # We insert the new node in a leaf
                              break
                         else:
                              __UpperCAmelCase			:				List[Any]													=    parent_node.left
                    else:
                         if parent_node.right is None:
                              __UpperCAmelCase			:				Optional[int]													=    new_node
                              break
                         else:
                              __UpperCAmelCase			:				List[str]													=    parent_node.right
               __UpperCAmelCase			:				int													=    parent_node

     def 				lowerCamelCase__				(       self  :	Optional[int]							,				*snake_case  :	List[Any]    )		->							None:
          for value in values:
               self.__insert(snake_case    )

     def 				lowerCamelCase__				(       self  :	Optional[int]							,				snake_case  :	Dict    )		->							Node | None:
          if self.empty():
               raise IndexError('''Warning: Tree is empty! please use another.'''    )
          else:
               __UpperCAmelCase			:				List[Any]													=    self.root
               # use lazy evaluation here to avoid NoneType Attribute error
               while node is not None and node.value is not value:
                    __UpperCAmelCase			:				Union[str, Any]													=    node.left if value < node.value else node.right
               return node

     def 				lowerCamelCase__				(       self  :	str							,				snake_case  :	Node | None = None    )		->							Node | None:
          if node is None:
               if self.root is None:
                    return None
               __UpperCAmelCase			:				Optional[Any]													=    self.root

          if not self.empty():
               while node.right is not None:
                    __UpperCAmelCase			:				str													=    node.right
          return node

     def 				lowerCamelCase__				(       self  :	int							,				snake_case  :	Node | None = None    )		->							Node | None:
          if node is None:
               __UpperCAmelCase			:				str													=    self.root
          if self.root is None:
               return None
          if not self.empty():
               __UpperCAmelCase			:				List[str]													=    self.root
               while node.left is not None:
                    __UpperCAmelCase			:				str													=    node.left
          return node

     def 				lowerCamelCase__				(       self  :	Union[str, Any]							,				snake_case  :	int    )		->							None:
          __UpperCAmelCase			:				List[str]													=    self.search(snake_case    )  # Look for the node with that label
          if node is not None:
               if node.left is None and node.right is None:  # If it has no children
                    self.__reassign_nodes(snake_case							,				snake_case    )
               elif node.left is None:  # Has only right children
                    self.__reassign_nodes(snake_case							,				node.right    )
               elif node.right is None:  # Has only left children
                    self.__reassign_nodes(snake_case							,				node.left    )
               else:
                    __UpperCAmelCase			:				Optional[int]													=    self.get_max(
                        node.left    )  # Gets the max value of the left branch
                    self.remove(tmp_node.value    )  # type: ignore
                    __UpperCAmelCase			:				List[str]													=    (
                        tmp_node.value  # type: ignore
                    )  # Assigns the value to the node to delete and keep tree structure

     def 				lowerCamelCase__				(       self  :	List[str]							,				snake_case  :	Node | None    )		->							Iterable:
          if node is not None:
               yield node  # Preorder Traversal
               yield from self.preorder_traverse(node.left    )
               yield from self.preorder_traverse(node.right    )

     def 				lowerCamelCase__				(       self  :	Union[str, Any]							,				snake_case  :	int=None    )		->							Any:
          if traversal_function is None:
               return self.preorder_traverse(self.root    )
          else:
               return traversal_function(self.root    )

     def 				lowerCamelCase__				(       self  :	str							,				snake_case  :	list							,				snake_case  :	Node | None    )		->							None:
          if node:
               self.inorder(snake_case							,				node.left    )
               arr.append(node.value    )
               self.inorder(snake_case							,				node.right    )






     def 				lowerCamelCase__				(       self  :	Optional[int]							,				snake_case  :	int							,				snake_case  :	Node    )		->							int:
          __UpperCAmelCase			:				list[int]													=    []
          self.inorder(snake_case							,				snake_case    )  # append all values to list using inorder traversal
          return arr[k - 1]




def 			_a			(		_lowercase      :			Node | None						):





     '''simple docstring'''






     __UpperCAmelCase			:				List[str]													=    []
     if curr_node is not None:
          __UpperCAmelCase			:				Union[str, Any]													=    postorder(curr_node.left						) + postorder(curr_node.right						) + [curr_node]
     return node_list




def 			_a			(		):





     '''simple docstring'''






     __UpperCAmelCase			:				Optional[Any]													=    (8, 3, 6, 1, 10, 14, 13, 4, 7)
     __UpperCAmelCase			:				Union[str, Any]													=    BinarySearchTree()
     for i in testlist:
          t.insert(_lowercase						)

     # Prints all the elements of the list in order traversal
     print(_lowercase						)

     if t.search(6						) is not None:
          print('''The value 6 exists'''						)
     else:
          print('''The value 6 doesn\'t exist'''						)

     if t.search(-1						) is not None:
          print('''The value -1 exists'''						)
     else:
          print('''The value -1 doesn\'t exist'''						)

     if not t.empty():
          print('''Max Value: '''    ,      t.get_max().value						)  # type: ignore
          print('''Min Value: '''    ,      t.get_min().value						)  # type: ignore

     for i in testlist:
          t.remove(_lowercase						)
          print(_lowercase						)


if __name__ == "__main__":
      import doctest

      doctest.testmod(verbose=True)