from __future__ import annotations

import unittest
from collections.abc import Iterator






class 				_SCREAMING_SNAKE_CASE:
   def __init__(     self				,  lowerCAmelCase_				,  lowerCAmelCase_     )						->None:
        a	:     Tuple						      =    label
        a	:     Optional[Any]						      =    parent
        a	:     Node | None						      =    None
        a	:     Node | None						      =    None






class 				_SCREAMING_SNAKE_CASE:
   def __init__(     self     )						->None:
        a	:     Node | None						      =    None
   def _lowercase(     self     )						->None:
        a	:     List[str]						      =    None
   def _lowercase(     self     )						->bool:
        return self.root is None
   def _lowercase(     self				,  lowerCAmelCase_     )						->None:
        a	:     List[str]						      =    self._put(self.root				,  lowerCAmelCase_     )
   def _lowercase(     self				,  lowerCAmelCase_				,  lowerCAmelCase_				,  lowerCAmelCase_ = None     )						->Node:
        if node is None:
             a	:     List[str]						      =    Node(lowerCAmelCase_				,  lowerCAmelCase_     )
        else:
             if label < node.label:
                  a	:     List[str]						      =    self._put(node.left				,  lowerCAmelCase_				,  lowerCAmelCase_     )
             elif label > node.label:
                  a	:     int						      =    self._put(node.right				,  lowerCAmelCase_				,  lowerCAmelCase_     )
             else:
                  a	:     Optional[Any]						      =    F"""Node with label {label} already exists"""
                  raise Exception(lowerCAmelCase_     )

        return node
   def _lowercase(     self				,  lowerCAmelCase_     )						->Node:
        return self._search(self.root				,  lowerCAmelCase_     )
   def _lowercase(     self				,  lowerCAmelCase_				,  lowerCAmelCase_     )						->Node:
        if node is None:
             a	:     List[Any]						      =    F"""Node with label {label} does not exist"""
             raise Exception(lowerCAmelCase_     )
        else:
             if label < node.label:
                  a	:     Dict						      =    self._search(node.left				,  lowerCAmelCase_     )
             elif label > node.label:
                  a	:     str						      =    self._search(node.right				,  lowerCAmelCase_     )

        return node
   def _lowercase(     self				,  lowerCAmelCase_     )						->None:
        a	:     int						      =    self.search(lowerCAmelCase_     )
        if node.right and node.left:
             a	:     Tuple						      =    self._get_lowest_node(node.right     )
             a	:     Union[str, Any]						      =    node.left
             a	:     int						      =    node.right
             a	:     List[str]						      =    lowest_node
             if node.right:
                  a	:     Union[str, Any]						      =    lowest_node
             self._reassign_nodes(lowerCAmelCase_				,  lowerCAmelCase_     )
        elif not node.right and node.left:
             self._reassign_nodes(lowerCAmelCase_				,  node.left     )
        elif node.right and not node.left:
             self._reassign_nodes(lowerCAmelCase_				,  node.right     )
        else:
             self._reassign_nodes(lowerCAmelCase_				,  lowerCAmelCase_     )
   def _lowercase(     self				,  lowerCAmelCase_				,  lowerCAmelCase_     )						->None:
        if new_children:
             a	:     Any						      =    node.parent

        if node.parent:
             if node.parent.right == node:
                  a	:     List[str]						      =    new_children
             else:
                  a	:     Any						      =    new_children
        else:
             a	:     Tuple						      =    new_children
   def _lowercase(     self				,  lowerCAmelCase_     )						->Node:
        if node.left:
             a	:     Any						      =    self._get_lowest_node(node.left     )
        else:
             a	:     Any						      =    node
             self._reassign_nodes(lowerCAmelCase_				,  node.right     )

        return lowest_node
   def _lowercase(     self				,  lowerCAmelCase_     )						->bool:
        try:
             self.search(lowerCAmelCase_     )
             return True
        except Exception:
             return False
   def _lowercase(     self     )						->int:
        if self.root is None:
             raise Exception('''Binary search tree is empty'''     )

        a	:     Tuple						      =    self.root
        while node.right is not None:
             a	:     Union[str, Any]						      =    node.right

        return node.label
   def _lowercase(     self     )						->int:
        if self.root is None:
             raise Exception('''Binary search tree is empty'''     )

        a	:     Union[str, Any]						      =    self.root
        while node.left is not None:
             a	:     List[Any]						      =    node.left

        return node.label
   def _lowercase(     self     )						->Iterator[Node]:
        return self._inorder_traversal(self.root     )
   def _lowercase(     self				,  lowerCAmelCase_     )						->Iterator[Node]:
        if node is not None:
             yield from self._inorder_traversal(node.left     )
             yield node
             yield from self._inorder_traversal(node.right     )
   def _lowercase(     self     )						->Iterator[Node]:
        return self._preorder_traversal(self.root     )


   def _lowercase(     self				,  lowerCAmelCase_     )						->Iterator[Node]:
        if node is not None:
             yield node
             yield from self._preorder_traversal(node.left     )
             yield from self._preorder_traversal(node.right     )






class 				_SCREAMING_SNAKE_CASE( unittest.TestCase						):
   @staticmethod
   def _lowercase(     )						->BinarySearchTree:
        a	:     str						      =    BinarySearchTree()
        t.put(8     )
        t.put(3     )
        t.put(6     )
        t.put(1     )
        t.put(10     )
        t.put(14     )
        t.put(13     )
        t.put(4     )
        t.put(7     )
        t.put(5     )

        return t
   def _lowercase(     self     )						->None:
        a	:     str						      =    BinarySearchTree()
        assert t.is_empty()

        t.put(8     )
        assert t.root is not None
        assert t.root.parent is None
        assert t.root.label == 8

        t.put(10     )
        assert t.root.right is not None
        assert t.root.right.parent == t.root
        assert t.root.right.label == 10

        t.put(3     )
        assert t.root.left is not None
        assert t.root.left.parent == t.root
        assert t.root.left.label == 3

        t.put(6     )
        assert t.root.left.right is not None
        assert t.root.left.right.parent == t.root.left
        assert t.root.left.right.label == 6

        t.put(1     )
        assert t.root.left.left is not None
        assert t.root.left.left.parent == t.root.left
        assert t.root.left.left.label == 1

        with self.assertRaises(lowerCAmelCase_     ):  # noqa: B017
             t.put(1     )
   def _lowercase(     self     )						->None:
        a	:     Union[str, Any]						      =    self._get_binary_search_tree()

        a	:     List[str]						      =    t.search(6     )
        assert node.label == 6

        a	:     Dict						      =    t.search(13     )
        assert node.label == 13

        with self.assertRaises(lowerCAmelCase_     ):  # noqa: B017
             t.search(2     )
   def _lowercase(     self     )						->None:
        a	:     Dict						      =    self._get_binary_search_tree()

        t.remove(13     )
        assert t.root is not None
        assert t.root.right is not None
        assert t.root.right.right is not None
        assert t.root.right.right.right is None
        assert t.root.right.right.left is None

        t.remove(7     )
        assert t.root.left is not None
        assert t.root.left.right is not None
        assert t.root.left.right.left is not None
        assert t.root.left.right.right is None
        assert t.root.left.right.left.label == 4

        t.remove(6     )
        assert t.root.left.left is not None
        assert t.root.left.right.right is not None
        assert t.root.left.left.label == 1
        assert t.root.left.right.label == 4
        assert t.root.left.right.right.label == 5
        assert t.root.left.right.left is None
        assert t.root.left.left.parent == t.root.left
        assert t.root.left.right.parent == t.root.left

        t.remove(3     )
        assert t.root is not None
        assert t.root.left.label == 4
        assert t.root.left.right.label == 5
        assert t.root.left.left.label == 1
        assert t.root.left.parent == t.root
        assert t.root.left.left.parent == t.root.left
        assert t.root.left.right.parent == t.root.left

        t.remove(4     )
        assert t.root.left is not None
        assert t.root.left.left is not None
        assert t.root.left.label == 5
        assert t.root.left.right is None
        assert t.root.left.left.label == 1
        assert t.root.left.parent == t.root
        assert t.root.left.left.parent == t.root.left
   def _lowercase(     self     )						->None:
        a	:     str						      =    self._get_binary_search_tree()

        t.remove(3     )
        assert t.root is not None
        assert t.root.left is not None
        assert t.root.left.left is not None
        assert t.root.left.right is not None
        assert t.root.left.right.left is not None
        assert t.root.left.right.right is not None
        assert t.root.left.label == 4
        assert t.root.left.right.label == 6
        assert t.root.left.left.label == 1
        assert t.root.left.right.right.label == 7
        assert t.root.left.right.left.label == 5
        assert t.root.left.parent == t.root
        assert t.root.left.right.parent == t.root.left
        assert t.root.left.left.parent == t.root.left
        assert t.root.left.right.left.parent == t.root.left.right
   def _lowercase(     self     )						->None:
        a	:     Any						      =    self._get_binary_search_tree()
        t.empty()
        assert t.root is None
   def _lowercase(     self     )						->None:
        a	:     Dict						      =    self._get_binary_search_tree()
        assert not t.is_empty()

        t.empty()
        assert t.is_empty()
   def _lowercase(     self     )						->None:
        a	:     Optional[Any]						      =    self._get_binary_search_tree()

        assert t.exists(6     )
        assert not t.exists(-1     )
   def _lowercase(     self     )						->None:
        a	:     Any						      =    self._get_binary_search_tree()

        assert t.get_max_label() == 14

        t.empty()
        with self.assertRaises(lowerCAmelCase_     ):  # noqa: B017
             t.get_max_label()
   def _lowercase(     self     )						->None:
        a	:     List[str]						      =    self._get_binary_search_tree()

        assert t.get_min_label() == 1

        t.empty()
        with self.assertRaises(lowerCAmelCase_     ):  # noqa: B017
             t.get_min_label()
   def _lowercase(     self     )						->None:
        a	:     List[str]						      =    self._get_binary_search_tree()

        a	:     List[Any]						      =    [i.label for i in t.inorder_traversal()]
        assert inorder_traversal_nodes == [1, 3, 4, 5, 6, 7, 8, 10, 13, 14]


   def _lowercase(     self     )						->None:
        a	:     int						      =    self._get_binary_search_tree()

        a	:     Optional[int]						      =    [i.label for i in t.preorder_traversal()]
        assert preorder_traversal_nodes == [8, 3, 1, 6, 4, 5, 7, 10, 14, 13]







def 						UpperCAmelCase							(		)						->						None:
     a	:     Tuple						      =    BinarySearchTree()
     t.put(8							)
     t.put(3							)
     t.put(6							)
     t.put(1							)
     t.put(1_0							)
     t.put(1_4							)
     t.put(1_3							)
     t.put(4							)
     t.put(7							)
     t.put(5							)

     print(
         '''
            8
           / \\
          3   10
         / \\    \\
        1   6    14
           / \\   /
          4   7 13
           \\
            5
        '''							)

     print('''Label 6 exists:'''    ,   t.exists(6							)							)
     print('''Label 13 exists:'''    ,   t.exists(1_3							)							)
     print('''Label -1 exists:'''    ,   t.exists(-1							)							)
     print('''Label 12 exists:'''    ,   t.exists(1_2							)							)

     # Prints all the elements of the list in inorder traversal
     a	:     Tuple						      =    [i.label for i in t.inorder_traversal()]
     print('''Inorder traversal:'''    ,   lowerCAmelCase_							)

     # Prints all the elements of the list in preorder traversal
     a	:     Optional[Any]						      =    [i.label for i in t.preorder_traversal()]
     print('''Preorder traversal:'''    ,   lowerCAmelCase_							)

     print('''Max. label:'''    ,   t.get_max_label()							)
     print('''Min. label:'''    ,   t.get_min_label()							)

     # Delete elements
     print('''\nDeleting elements 13, 10, 8, 3, 6, 14'''							)
     print(
         '''
          4
         / \\
        1   7
             \\
              5
        '''							)
     t.remove(1_3							)
     t.remove(1_0							)
     t.remove(8							)
     t.remove(3							)
     t.remove(6							)
     t.remove(1_4							)

     # Prints all the elements of the list in inorder traversal after delete
     a	:     List[Any]						      =    [i.label for i in t.inorder_traversal()]
     print('''Inorder traversal after delete:'''    ,   lowerCAmelCase_							)

     # Prints all the elements of the list in preorder traversal after delete
     a	:     Optional[Any]						      =    [i.label for i in t.preorder_traversal()]
     print('''Preorder traversal after delete:'''    ,   lowerCAmelCase_							)

     print('''Max. label:'''    ,   t.get_max_label()							)
     print('''Min. label:'''    ,   t.get_min_label()							)


if __name__ == "__main__":
  binary_search_tree_example()
UpperCAmelCase				 =   {
    0: """underwear""",
    1: """pants""",
    2: """belt""",
    3: """suit""",
    4: """shoe""",
    5: """socks""",
    6: """shirt""",
    7: """tie""",
    8: """watch""",
}

UpperCAmelCase				 =   [[1, 4], [2, 4], [3], [], [], [4], [2, 7], [3], []]

UpperCAmelCase				 =   [0 for x in range(len(graph))]
UpperCAmelCase				 =   []







def 						UpperCAmelCase							(		lowerCAmelCase_    ,   lowerCAmelCase_							)						->						List[Any]:
     a	:     Tuple						      =    1
     while stack:
          a	:     Optional[Any]						      =    stack.pop()
          print(lowerCAmelCase_    ,   clothes[current_clothing]							)
          order += 1







def 						UpperCAmelCase							(		lowerCAmelCase_    ,   lowerCAmelCase_    ,   lowerCAmelCase_							)						->						Any:
     a	:     Union[str, Any]						      =    1
     for v in graph[u]:
          if not visited[v]:
               depth_first_search(lowerCAmelCase_    ,   lowerCAmelCase_    ,   lowerCAmelCase_							)

     stack.append(lowerCAmelCase_							)







def 						UpperCAmelCase							(		lowerCAmelCase_    ,   lowerCAmelCase_							)						->						Optional[Any]:
     for v in range(len(lowerCAmelCase_							)							):
          if not visited[v]:
               depth_first_search(lowerCAmelCase_    ,   lowerCAmelCase_    ,   lowerCAmelCase_							)


if __name__ == "__main__":
  topological_sort(graph, visited)
  print(stack)
  print_stack(stack, clothes)