this should all be familiar from our embedding a breadth-first search in a for loop when we computed the connected components of an undirected graph, and if we get to a vertex v of the graph that we haven't explored yet, then we just invoke dfs in the graph with that vertex as the starting point.