




from collections.abc import Iterable
from typing import Any


class 				UpperCamelCase_    :

    '''simple docstring'''






    def __init__(			self      :	Union[str, Any]					, UpperCAmelCase__      :	int | None = None)						->Union[str, Any]:





           '''simple docstring'''

           A__       =    value
           A__       =    None  # Added in order to delete a node easier
           A__       =    None
           A__       =    None





    def __repr__(			self      :	Optional[Any])						->str:





           '''simple docstring'''

           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 				UpperCamelCase_    :

    '''simple docstring'''






    def __init__(			self      :	Tuple					, UpperCAmelCase__      :	Node | None = None)						->Optional[Any]:





           '''simple docstring'''

           A__       =    root


    def __str__(			self      :	List[str])						->str:





           '''simple docstring'''

           return str(self.root)


    def        SCREAMING_SNAKE_CASE							(			self      :	str					, UpperCAmelCase__      :	Node					, UpperCAmelCase__      :	Node | None)						->None:





           '''simple docstring'''

           if new_children is not None:  # reset its kids
                  A__       =    node.parent
           if node.parent is not None:  # reset its parent
                  if self.is_right(UpperCAmelCase__):  # If it is the right children
                         A__       =    new_children
                  else:
                         A__       =    new_children
           else:
                  A__       =    new_children


    def        SCREAMING_SNAKE_CASE							(			self      :	List[Any]					, UpperCAmelCase__      :	Node)						->bool:





           '''simple docstring'''

           if node.parent and node.parent.right:
                  return node == node.parent.right
           return False


    def        SCREAMING_SNAKE_CASE							(			self      :	Optional[int])						->bool:





           '''simple docstring'''

           return self.root is None


    def        SCREAMING_SNAKE_CASE							(			self      :	Union[str, Any]					, UpperCAmelCase__      :	Tuple)						->None:





           '''simple docstring'''

           A__       =    Node(UpperCAmelCase__)  # create a new Node
           if self.empty():  # if Tree is empty
                  A__       =    new_node  # set its root
           else:  # Tree is not empty
                  A__       =    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:
                                       A__       =    new_node  # We insert the new node in a leaf
                                       break
                                else:
                                       A__       =    parent_node.left
                         else:
                                if parent_node.right is None:
                                       A__       =    new_node
                                       break
                                else:
                                       A__       =    parent_node.right
                  A__       =    parent_node


    def        SCREAMING_SNAKE_CASE							(			self      :	Optional[int]					, *UpperCAmelCase__      :	Optional[Any])						->None:





           '''simple docstring'''

           for value in values:
                  self.__insert(UpperCAmelCase__)


    def        SCREAMING_SNAKE_CASE							(			self      :	List[Any]					, UpperCAmelCase__      :	List[str])						->Node | None:





           '''simple docstring'''

           if self.empty():
                  raise IndexError('''Warning: Tree is empty! please use another.''')
           else:
                  A__       =    self.root
                  # use lazy evaluation here to avoid NoneType Attribute error
                  while node is not None and node.value is not value:
                         A__       =    node.left if value < node.value else node.right
                  return node


    def        SCREAMING_SNAKE_CASE							(			self      :	Union[str, Any]					, UpperCAmelCase__      :	Node | None = None)						->Node | None:





           '''simple docstring'''

           if node is None:
                  if self.root is None:
                         return None
                  A__       =    self.root

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


    def        SCREAMING_SNAKE_CASE							(			self      :	Union[str, Any]					, UpperCAmelCase__      :	Node | None = None)						->Node | None:





           '''simple docstring'''

           if node is None:
                  A__       =    self.root
           if self.root is None:
                  return None
           if not self.empty():
                  A__       =    self.root
                  while node.left is not None:
                         A__       =    node.left
           return node


    def        SCREAMING_SNAKE_CASE							(			self      :	Dict					, UpperCAmelCase__      :	int)						->None:





           '''simple docstring'''

           A__       =    self.search(UpperCAmelCase__)  # 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(UpperCAmelCase__					, UpperCAmelCase__)
                  elif node.left is None:  # Has only right children
                         self.__reassign_nodes(UpperCAmelCase__					, node.right)
                  elif node.right is None:  # Has only left children
                         self.__reassign_nodes(UpperCAmelCase__					, node.left)
                  else:
                         A__       =    self.get_max(
                             node.left)  # Gets the max value of the left branch
                         self.remove(tmp_node.value)  # type: ignore
                         A__       =    (
                             tmp_node.value  # type: ignore
                         )  # Assigns the value to the node to delete and keep tree structure


    def        SCREAMING_SNAKE_CASE							(			self      :	Tuple					, UpperCAmelCase__      :	Node | None)						->Iterable:





           '''simple docstring'''

           if node is not None:
                  yield node  # Preorder Traversal
                  yield from self.preorder_traverse(node.left)
                  yield from self.preorder_traverse(node.right)


    def        SCREAMING_SNAKE_CASE							(			self      :	Any					, UpperCAmelCase__      :	Any=None)						->Any:





           '''simple docstring'''

           if traversal_function is None:
                  return self.preorder_traverse(self.root)
           else:
                  return traversal_function(self.root)


    def        SCREAMING_SNAKE_CASE							(			self      :	Optional[int]					, UpperCAmelCase__      :	list					, UpperCAmelCase__      :	Node | None)						->None:





           '''simple docstring'''

           if node:
                  self.inorder(UpperCAmelCase__					, node.left)
                  arr.append(node.value)
                  self.inorder(UpperCAmelCase__					, node.right)





    def        SCREAMING_SNAKE_CASE							(			self      :	Any					, UpperCAmelCase__      :	int					, UpperCAmelCase__      :	Node)						->int:





           '''simple docstring'''

           A__       =    []
           self.inorder(UpperCAmelCase__					, UpperCAmelCase__)  # append all values to list using inorder traversal
           return arr[k - 1]







def SCREAMING_SNAKE_CASE				(       lowercase_						)   ->       list[Node]:



       """simple docstring"""

       A__       =    []
       if curr_node is not None:
              A__       =    postorder(curr_node.left						) + postorder(curr_node.right						) + [curr_node]
       return node_list







def SCREAMING_SNAKE_CASE				(       )   ->       None:



       """simple docstring"""

       A__       =    (8, 3, 6, 1, 10, 14, 13, 4, 7)
       A__       =    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)








def SCREAMING_SNAKE_CASE				(       lowercase_						)   ->       Any:



       """simple docstring"""

       A__       =    [0] * len(lowercase_						)
       A__       =    []
       A__       =    [1] * len(lowercase_						)

       for values in graph.values():
              for i in values:
                     indegree[i] += 1

       for i in range(len(lowercase_						)						):
              if indegree[i] == 0:
                     queue.append(lowercase_						)

       while queue:
              A__       =    queue.pop(0						)
              for x in graph[vertex]:
                     indegree[x] -= 1

                     if long_dist[vertex] + 1 > long_dist[x]:
                            A__       =    long_dist[vertex] + 1

                     if indegree[x] == 0:
                            queue.append(lowercase_						)

       print(max(lowercase_						)						)


# Adjacency list of Graph
_lowerCamelCase	:		Optional[int]							       =   {0: [2, 3, 4], 1: [2, 7], 2: [5], 3: [5, 7], 4: [7], 5: [6], 6: [7], 7: []}
longest_distance(graph)


