docs: def candidate_pairs_iter(self):
          """Iterator over candidate pairs of nodes in G1 and G2."""
          # All computations are done using the current state!
          G2_nodes = self.G2_nodes
  
          # First we compute the inout-terminal sets.
          T1_inout = set(self.inout_1.keys()) - set(self.core_1.keys())
          T2_inout = set(self.inout_2.keys()) - set(self.core_2.keys())
  
          # If T1_inout and T2_inout are both nonempty.
          # P(s) = T1_inout x {min T2_inout}
          if T1_inout and T2_inout:
              for node in T1_inout:
                  yield node, min(T2_inout)
          else:
              # First we determine the candidate node for G2
              other_node = min(G2_nodes - set(self.core_2))
              host_nodes = self.valid_nodes if other_node == 0 else self.G1.nodes()
              for node in host_nodes:
                  if node not in self.core_1:
                      yield node, other_node