old_contents: # https://en.wikipedia.org/wiki/Disjoint-set_data_structure
  
  import collections
  from typing import FrozenSet, Generic, Generator, Tuple, TypeVar
  
  T = TypeVar("T")
  
  
  class DisjointSet(Generic[T]):
      def __init__(self):
          self.parent = {}
          self.rank = {}
  
      def make_set(self, e: T):
          if e in self.parent:
              return
          self.parent[e] = e
          self.rank[e] = 0
  
      # find with path compression
      def find(self, e: T):
          self.make_set(e)
          prev = e
          while self.parent[e] != e:
              prev = e
              e = self.parent[e]
              self.parent[prev] = e
          return e
  
      # union by rank
      def union(self, x: T, y: T):
          x_root = self.find(x)
          y_root = self.find(y)
          if x_root == y_root:
              return  # already in the same set
          if self.rank[x] < self.rank[y]:
              tmp = x_root
              x_root = y_root
              y_root = tmp
  
          self.parent[y_root] = x_root
          if self.rank[x_root] == self.rank[y_root]:
              self.rank[x_root] = self.rank[x_root] + 1
  
      def sets(self) -> FrozenSet[FrozenSet[T]]:
          sets = collections.defaultdict(set)
          for e in self.parent:
              sets[self.find(e)].add(e)
          return frozenset(frozenset(s) for s in sets.values())
  
      def sorted(self) -> Tuple[Tuple[T, ...]]:
          """Sorted tuple of sorted tuples edition of sets()."""
          return tuple(sorted(tuple(sorted(s)) for s in self.sets()))
  
new_contents: # https://en.wikipedia.org/wiki/Disjoint-set_data_structure
  
  import collections
  from typing import FrozenSet, Generic, Generator, Tuple, TypeVar
  
  T = TypeVar("T")
  
  
  class DisjointSet(Generic[T]):
      def __init__(self):
          self.parent = {}
          self.rank = {}
  
      def make_set(self, e: T):
          if e in self.parent:
              return
          self.parent[e] = e
          self.rank[e] = 0
  
      # find with path compression
      def find(self, e: T):
          self.make_set(e)
          prev = e
          while self.parent[e] != e:
              prev = e
              e = self.parent[e]
              self.parent[prev] = e
          return e
  
      # union by rank
      def union(self, x: T, y: T):
          x_root = self.find(x)
          y_root = self.find(y)
          if x_root == y_root:
              return  # already in the same set
          if self.rank[x] < self.rank[y]:
              tmp = x_root
              x_root = y_root
              y_root = tmp
  
          self.parent[y_root] = x_root
          if self.rank[x_root] == self.rank[y_root]:
              self.rank[x_root] += 1
  
      def sets(self) -> FrozenSet[FrozenSet[T]]:
          sets = collections.defaultdict(set)
          for e in self.parent:
              sets[self.find(e)].add(e)
          return frozenset(frozenset(s) for s in sets.values())
  
      def sorted(self) -> Tuple[Tuple[T, ...]]:
          """Sorted tuple of sorted tuples edition of sets()."""
          return tuple(sorted(tuple(sorted(s)) for s in self.sets()))
  
subject: Update src/nanoemoji/disjoint_set.py