def dfs(graph, source):
  """
  Given a directed graph (format described below), and a source vertex,
  returns a set of vertices reachable from source.
  The graph parameter is expected to be a dictionary mapping each vertex to a
  list of vertices indicating outgoing edges. For example if vertex v has
  outgoing edges to u and w we have graph[v] = [u, w].
  """
  visited = set()
  def _recurse(v):
    if v in visited:
      return
    visited.add(v)
    for w in graph[v]:
      _recurse(w)
  _recurse(source)
  return visited