code: def find_matching(self) -> Dict[TLeft, TRight]:
          
          # The directed graph is represented as a dictionary of edges
          # The key is the tail of all edges which are represented by the value
          # The value is a set of heads for the all edges originating from the tail (key)
          # In addition, the graph stores which part of the bipartite graph a node originated from
          # to avoid problems when a value exists in both halfs.
          # Only one direction of the undirected edge is needed for the HopcroftKarp class
          directed_graph = {}  # type: Dict[Tuple[int, TLeft], Set[Tuple[int, TRight]]]
  
          for (left, right) in self._edges:
              tail = (LEFT, left)
              head = (RIGHT, right)
              if tail not in directed_graph:
                  directed_graph[tail] = {head}
              else:
                  directed_graph[tail].add(head)
  
          matching = HopcroftKarp(directed_graph).maximum_matching()
  
          # Filter out the partitions (LEFT and RIGHT) and only return the matching edges
          # that go from LEFT to RIGHT
          return dict((tail[1], head[1]) for tail, head in matching.items() if tail[0] == LEFT)
docs: Finds a matching in the bipartite graph.
  
          This is done using the Hopcroft-Karp algorithm with an implementation from the
          `hopcroftkarp` package.
  
          Returns:
              A dictionary where each edge of the matching is represented by a key-value pair
              with the key being from the left part of the graph and the value from te right part.