
SCREAMING_SNAKE_CASE__   :			Dict												=    {
    "A": ["B", "C", "E"],
    "B": ["A", "D", "E"],
    "C": ["A", "F", "G"],
    "D": ["B"],
    "E": ["A", "B", "D"],
    "F": ["C"],
    "G": ["C"],
}




def  __magic_name__ (   __lowerCAmelCase	:						dict		,  __lowerCAmelCase	:						List[str]		,  __lowerCAmelCase	:						int							)			->   list[str]:
				__lowerCamelCase    					=	set()
				# keep track of all the paths to be checked
				__lowerCamelCase    					=	[[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
								__lowerCamelCase    					=	queue.pop(0							)
								# get the last node from the path
								__lowerCamelCase    					=	path[-1]
								if node not in explored:
												__lowerCamelCase    					=	graph[node]
												# go through all neighbour nodes, construct a new path and
												# push it into the queue
												for neighbour in neighbours:
																__lowerCamelCase    					=	list(__lowerCAmelCase							)
																new_path.append(__lowerCAmelCase							)
																queue.append(__lowerCAmelCase							)
																# return path if neighbour is goal
																if neighbour == goal:
																				return new_path

            # mark node as explored
												explored.add(__lowerCAmelCase							)

    # in case there's no path between the 2 nodes
				return []




def  __magic_name__ (   __lowerCAmelCase	:						dict		,  __lowerCAmelCase	:						List[str]		,  __lowerCAmelCase	:						Optional[int]							)			->   int:
				if not graph or start not in graph or target not in graph:
								return -1
				if start == target:
								return 0
				__lowerCamelCase    					=	[start]
				__lowerCamelCase    					=	set(__lowerCAmelCase							)
				# Keep tab on distances from `start` node.
				__lowerCamelCase    					=	{start: 0, target: -1}
				while queue:
								__lowerCamelCase    					=	queue.pop(0							)
								if node == target:
												__lowerCamelCase    					=	(
												    dist[node] if dist[target] == -1 else min(dist[target]		,  dist[node]							)
												)
								for adjacent in graph[node]:
												if adjacent not in visited:
																visited.add(__lowerCAmelCase							)
																queue.append(__lowerCAmelCase							)
																__lowerCamelCase    					=	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





from abc import ABC, abstractmethod
from argparse import ArgumentParser

class    lowerCAmelCase__     (	__lowercase			):






		@staticmethod
		@abstractmethod
		def  __A       (		SCREAMING_SNAKE_CASE__		:							ArgumentParser  )     ->							str:
						raise NotImplementedError()







		@abstractmethod
		def  __A       (		self		:							Optional[int]  )     ->							Union[str, Any]:
						raise NotImplementedError()



