



from queue import PriorityQueue
from typing import Any

import numpy as np


def A    (							__UpperCamelCase			,						__UpperCamelCase			,						__UpperCamelCase			,						__UpperCamelCase			,						__UpperCamelCase			,						__UpperCamelCase			,						__UpperCamelCase			,						__UpperCamelCase			,						__UpperCamelCase			,						)    ->   float | int:
			for nxt, d in graph[v]:
						if nxt in visited_forward:
									continue
						A__	  =     cst_fwd.get(__UpperCamelCase			,						np.inf       )
						A__	  =     cst_fwd[v] + d
						if new_cost_f < old_cost_f:
									queue.put((new_cost_f, nxt)       )
									A__	  =     new_cost_f
									A__	  =     v
						if nxt in visited_backward:
									if cst_fwd[v] + d + cst_bwd[nxt] < shortest_distance:
												A__	  =     cst_fwd[v] + d + cst_bwd[nxt]
			return shortest_distance


def A    (							__UpperCamelCase			,						__UpperCamelCase			,						__UpperCamelCase			,						__UpperCamelCase       )    ->   int:
			A__	  =     -1

			A__	  =     set()
			A__	  =     set()
			A__	  =     {source: 0}
			A__	  =     {destination: 0}
			A__	  =     {source: None}
			A__	  =     {destination: None}
			A__	  =     PriorityQueue()
			A__	  =     PriorityQueue()

			A__	  =     np.inf

			queue_forward.put((0, source)       )
			queue_backward.put((0, destination)       )

			if source == destination:
						return 0

			while not queue_forward.empty() and not queue_backward.empty():
						A__  ,			A__	  =     queue_forward.get()
						visited_forward.add(__UpperCamelCase       )

						A__  ,			A__	  =     queue_backward.get()
						visited_backward.add(__UpperCamelCase       )

						A__	  =     pass_and_relaxation(
						    __UpperCamelCase			,						__UpperCamelCase			,						__UpperCamelCase			,						__UpperCamelCase			,						__UpperCamelCase			,						__UpperCamelCase			,						__UpperCamelCase			,						__UpperCamelCase			,						__UpperCamelCase			,						)

						A__	  =     pass_and_relaxation(
						    __UpperCamelCase			,						__UpperCamelCase			,						__UpperCamelCase			,						__UpperCamelCase			,						__UpperCamelCase			,						__UpperCamelCase			,						__UpperCamelCase			,						__UpperCamelCase			,						__UpperCamelCase			,						)

						if cst_fwd[v_fwd] + cst_bwd[v_bwd] >= shortest_distance:
									break

			if shortest_distance != np.inf:
						A__	  =     shortest_distance
			return shortest_path_distance


SCREAMING_SNAKE_CASE__   			=   {
    '''B''': [['''C''', 1]],
    '''C''': [['''D''', 1]],
    '''D''': [['''F''', 1]],
    '''E''': [['''B''', 1], ['''G''', 2]],
    '''F''': [],
    '''G''': [['''F''', 1]],
}
SCREAMING_SNAKE_CASE__   			=   {
    '''B''': [['''E''', 1]],
    '''C''': [['''B''', 1]],
    '''D''': [['''C''', 1]],
    '''F''': [['''D''', 1], ['''G''', 1]],
    '''E''': [[None, np.inf]],
    '''G''': [['''E''', 2]],
}

if __name__ == "__main__":
							import doctest

							doctest.testmod()






"""simple docstring"""






class 			lowercase					:






			def __init__(self  :	Dict			)       ->	List[Any]:





				"""simple docstring"""


				lowerCAmelCase												=  {}






			def 					UpperCAmelCase							(self  :	Union[str, Any]			)       ->	None:





				"""simple docstring"""


				print(self.vertex			)
				for i in self.vertex:
					print(SCREAMING_SNAKE_CASE_      ,''' -> '''      ,''' -> '''.join([str(SCREAMING_SNAKE_CASE_			) for j in self.vertex[i]]			)			)






			def 					UpperCAmelCase							(self  :	Optional[Any]      ,SCREAMING_SNAKE_CASE_  :	int      ,SCREAMING_SNAKE_CASE_  :	int			)       ->	None:





				"""simple docstring"""


				if from_vertex in self.vertex:
					self.vertex[from_vertex].append(SCREAMING_SNAKE_CASE_			)
				else:
					# else make a new vertex
					lowerCAmelCase												=  [to_vertex]






			def 					UpperCAmelCase							(self  :	List[str]			)       ->	None:





				"""simple docstring"""


				lowerCAmelCase												=  [False] * len(self.vertex			)

				# call the recursive helper function
				for i in range(len(self.vertex			)			):
					if not visited[i]:
						self.dfs_recursive(SCREAMING_SNAKE_CASE_      ,SCREAMING_SNAKE_CASE_			)






			def 					UpperCAmelCase							(self  :	Optional[Any]      ,SCREAMING_SNAKE_CASE_  :	int      ,SCREAMING_SNAKE_CASE_  :	list			)       ->	None:





				"""simple docstring"""


				lowerCAmelCase												=  True

				print(SCREAMING_SNAKE_CASE_      ,end=''' '''			)

				# Recur for all the vertices that are adjacent to this node
				for i in self.vertex:
					if not visited[i]:
						self.dfs_recursive(SCREAMING_SNAKE_CASE_      ,SCREAMING_SNAKE_CASE_			)


if __name__ == "__main__":
					UpperCAmelCase        =				Graph()
					g.add_edge(0, 1)
					g.add_edge(0, 2)
					g.add_edge(1, 2)
					g.add_edge(2, 0)
					g.add_edge(2, 3)
					g.add_edge(3, 3)

					g.print_graph()
					print("""DFS:""")
					g.dfs()

					# OUTPUT:
					# 0  ->  1 -> 2
					# 1  ->  2
					# 2  ->  0 -> 3
					# 3  ->  3
					# DFS:
					#  0 1 2 3


