code: def _find_disjoint_sets(
      verts: Iterable[int], edges: Iterable[Tuple[int, int]]
  ) -> List[List[int]]:
      """Finds disjoint sets."""
      parents = {a: a for a in verts}
  
      def find(a: int):
          if parents[a] != a:
              parents[a] = find(parents[a])
          return parents[a]
  
      def union(a: int, b: int):
          x, y = find(a), find(b)
          if x != y:
              # Union in a direction that smaller number node becomes the parent node.
              # By result, the root node of each disjoint set will be the one with the
              # smallest number.
              parents[max(x, y)] = min(x, y)
  
      for a, b in edges:
          union(a, b)
  
      # Python dict "order is guaranteed to be insertion order" from python 3.7
      # (https://docs.python.org/3/library/stdtypes.html#dict).
      # As it loops over the sorted node number, and since the root node of each
      # disjoint set is the one with the smallest node number, both the inner and
      # the outer lists of the result would be sorted.
      disjoint_sets = {}
      for a in sorted(verts):
          disjoint_sets.setdefault(find(a), []).append(a)
      return list(disjoint_sets.values())
  
file_path: tfx/tfx/dsl/input_resolution/ops/group_by_lineage_op.py
imports: import collections
  from typing import List, Iterable, Tuple
  from tfx.dsl.input_resolution import resolver_op
  from tfx.orchestration.portable.input_resolution import exceptions
  from tfx.utils import typing_utils
  from ml_metadata.proto import metadata_store_pb2
label_desc: Use image node_id 2 for calling a global function with example usage: _find_disjoint_sets(verts, edges) and returns: list, parents