code: def _isomorphism_rewrite_to_NECtree(q_s, qgraph):
      
      qadj = qgraph.adj
      adjsets = lambda x: set(chain.from_iterable(qadj[x].values()))
      t = ([q_s], [])  # (NEC_set, children)
      visited = {q_s}
      vcur, vnext = [t], []
      while vcur:
          for (nec, children) in vcur:
              c = defaultdict(list)
              for u in nec:
                  for sig, adjlist in qadj[u].items():
                      c[sig].extend(x for x, _, _ in adjlist if x not in visited)
              for sig, c_adjlist in c.items():
                  visited.update(c_adjlist)
                  # these are already grouped by label; now group by adjacents
                  for key, grp in groupby(c_adjlist, key=adjsets):
                      grp = list(grp)
                      if len(grp) > 1:
                          children.append((list(grp), []))
                      else:
                          # NOTE: the paper says to look for mergeable things,
                          # but I don't know what else to merge by.
                          children.append((list(grp), []))
              vnext.extend(children)
          vcur, vnext = vnext, []
      return t
docs: Neighborhood Equivalence Class tree (see Turbo_ISO paper)