docs: def DFS(G):
      """
      Algorithm for depth-first searching the vertices of a graph.
      """
      if not G.vertices:
          raise GraphInsertError("This graph have no vertices.")
      color = {}
      pred = {}
      reach = {}
      finish = {}
  
      def DFSvisit(G, current, time):
          color[current] = 'grey'
          time += 1
          reach[current] = time
          for vertex in G.vertices[current]:
              if color[vertex] == 'white':
                  pred[vertex] = current
                  time = DFSvisit(G, vertex, time)
          color[current] = 'black'
          time += 1
          finish[current] = time
          return time
  
      for vertex in G.vertices:
          color[vertex] = 'white'
          pred[vertex] = None
          reach[vertex] = 0
          finish[vertex] = 0
      time = 0
      for vertex in G.vertices:
          if color[vertex] == 'white':
              time = DFSvisit(G, vertex, time)
      # Dictionary for vertex data after DFS
      # -> vertex_data = {vertex: (predecessor, reach, finish), }
      vertex_data = {}
      for vertex in G.vertices:
          vertex_data[vertex] = (pred[vertex], reach[vertex], finish[vertex])
      return vertex_data