public static <Node> void performBfs(
    @NotNull OutboundSemiGraph<Node> graph,
    @NotNull Node root,
    @NotNull BiConsumer<? super Node, ? super Integer> visitor
  ) {
    final Set<Node> visited = new HashSet<>();
    final Queue<WithIndex<Node>> queue = new ArrayDeque<>();
    queue.add(new WithIndex<>(root, 0));

    while (!queue.isEmpty()) {
      final WithIndex<Node> curr = queue.poll();

      if (!visited.contains(curr)) {
        visitor.accept(curr.node, curr.index);
        visited.add(curr.node);
      }

      graph.getOut(curr.node).forEachRemaining(next -> {
        if (!visited.contains(next)) {
          queue.add(new WithIndex<>(next, curr.index + 1));
        }
      });
    }
  }
public static <Node> void performBfs(
    @NotNull OutboundSemiGraph<Node> graph,
    @NotNull Node root,
    @NotNull BiConsumer<? super Node, ? super Integer> visitor
  )