__UpperCamelCase		:       Any									=     {
    'A': ['B', 'C', 'E'],
    'B': ['A', 'D', 'E'],
    'C': ['A', 'F', 'G'],
    'D': ['B'],
    'E': ['A', 'B', 'D'],
    'F': ['C'],
    'G': ['C'],
}
def       A	(    _lowercase		,  _lowercase		,  _lowercase						):
						SCREAMING_SNAKE_CASE							:    List[str]							=							set()
						# keep track of all the paths to be checked
						SCREAMING_SNAKE_CASE							:    str							=							[[start]]

						# return path if start is goal
						if start == goal:
												return [start]

						# keeps looping until all possible paths have been checked
						while queue:
												# pop the first path from the queue
												SCREAMING_SNAKE_CASE							:    Tuple							=							queue.pop(0						)
												# get the last node from the path
												SCREAMING_SNAKE_CASE							:    Any							=							path[-1]
												if node not in explored:
																		SCREAMING_SNAKE_CASE							:    Optional[int]							=							graph[node]
																		# go through all neighbour nodes, construct a new path and
																		# push it into the queue
																		for neighbour in neighbours:
																								SCREAMING_SNAKE_CASE							:    int							=							list(_lowercase						)
																								new_path.append(_lowercase						)
																								queue.append(_lowercase						)
																								# return path if neighbour is goal
																								if neighbour == goal:
																														return new_path

            # mark node as explored
																		explored.add(_lowercase						)

    # in case there's no path between the 2 nodes
						return []
def       A	(    _lowercase		,  _lowercase		,  _lowercase						):
						if not graph or start not in graph or target not in graph:
												return -1
						if start == target:
												return 0
						SCREAMING_SNAKE_CASE							:    Tuple							=							[start]
						SCREAMING_SNAKE_CASE							:    Any							=							set(_lowercase						)
						# Keep tab on distances from `start` node.
						SCREAMING_SNAKE_CASE							:    Optional[Any]							=							{start: 0, target: -1}
						while queue:
												SCREAMING_SNAKE_CASE							:    Optional[Any]							=							queue.pop(0						)
												if node == target:
																		SCREAMING_SNAKE_CASE							:    str							=							(
																		    dist[node] if dist[target] == -1 else min(dist[target]		,  dist[node]						)
																		)
												for adjacent in graph[node]:
																		if adjacent not in visited:
																								visited.add(_lowercase						)
																								queue.append(_lowercase						)
																								SCREAMING_SNAKE_CASE							:    Any							=							dist[node] + 1
						return dist[target]


if __name__ == "__main__":
					print(bfs_shortest_path(demo_graph, 'G', 'D'))  # returns ['G', 'C', 'A', 'B', 'D']
					print(bfs_shortest_path_distance(demo_graph, 'G', 'D'))  # returns 4












"""simple docstring"""
def 					A__				(			UpperCamelCase					,  UpperCamelCase = False       ):

							if not isinstance(UpperCamelCase					,  UpperCamelCase       ):
														A		=  F"Expected string as input, found {type(UpperCamelCase       )}"
														raise ValueError(UpperCamelCase       )
							if not isinstance(UpperCamelCase					,  UpperCamelCase       ):
														A		=  F"Expected boolean as use_pascal parameter, found {type(UpperCamelCase       )}"
														raise ValueError(UpperCamelCase       )

							A		=  input_str.split("_"       )

							A		=  0 if use_pascal else 1

							A		=  words[start_index:]

							A		=  [word[0].upper() + word[1:] for word in words_to_capitalize]

							A		=  "" if use_pascal else words[0]

							return "".join([initial_word, *capitalized_words]       )


if __name__ == "__main__":
		from doctest import testmod

		testmod()


