




'''simple docstring'''
class 							lowercase__			:






	class 							lowercase__			:
		lowercase__						       =    """_prev""", """_data""", """_next"""





		def __init__(				self      :       Any				,lowerCamelCase__      :       Any				,lowerCamelCase__      :       Tuple				,lowerCamelCase__      :       Union[str, Any]				):







								'''simple docstring'''
								_UpperCamelCase      :	int				       =     link_p
								_UpperCamelCase      :	Optional[Any]				       =     element
								_UpperCamelCase      :	str				       =     link_n





		def 			UpperCamelCase_						(				self      :       List[Any]				):







								'''simple docstring'''
								return (
								    F' Prev -> {self._prev is not None}, Next -> {self._next is not None}'
								)





	def __init__(				self      :       List[Any]				):







							'''simple docstring'''
							_UpperCamelCase      :	str				       =     self._Node(lowerCamelCase__				,lowerCamelCase__				,lowerCamelCase__				)
							_UpperCamelCase      :	Optional[Any]				       =     self._Node(lowerCamelCase__				,lowerCamelCase__				,lowerCamelCase__				)
							_UpperCamelCase      :	Dict				       =     self._trailer
							_UpperCamelCase      :	Optional[Any]				       =     self._header
							_UpperCamelCase      :	str				       =     0





	def __len__(				self      :       str				):







							'''simple docstring'''
							return self._size





	def 			UpperCamelCase_						(				self      :       Dict				):







							'''simple docstring'''
							return self.__len__() == 0





	def 			UpperCamelCase_						(				self      :       List[str]				,lowerCamelCase__      :       Optional[Any]				,lowerCamelCase__      :       int				,lowerCamelCase__      :       Optional[Any]				):







							'''simple docstring'''
							_UpperCamelCase      :	Optional[int]				       =     self._Node(lowerCamelCase__				,lowerCamelCase__				,lowerCamelCase__				)
							_UpperCamelCase      :	Tuple				       =     new_node
							_UpperCamelCase      :	Union[str, Any]				       =     new_node
							self._size += 1
							return self





	def 			UpperCamelCase_						(				self      :       List[Any]				,lowerCamelCase__      :       Optional[int]				):







							'''simple docstring'''
							_UpperCamelCase      :	Any				       =     node._prev
							_UpperCamelCase      :	List[str]				       =     node._next

							_UpperCamelCase      :	Union[str, Any]				       =     successor
							_UpperCamelCase      :	List[Any]				       =     predecessor
							self._size -= 1
							_UpperCamelCase      :	Optional[int]				       =     node._data
							_UpperCamelCase      :	Optional[Any]				       =     None
							del node
							return temp






class 							lowercase__			(							_DoublyLinkedBase     ):





	def 			UpperCamelCase_						(				self      :       Tuple				):







							'''simple docstring'''
							if self.is_empty():
													raise Exception('List is empty'				)
							return self._header._next._data





	def 			UpperCamelCase_						(				self      :       Dict				):







							'''simple docstring'''
							if self.is_empty():
													raise Exception('List is empty'				)
							return self._trailer._prev._data





	def 			UpperCamelCase_						(				self      :       Optional[Any]				,lowerCamelCase__      :       Dict				):







							'''simple docstring'''
							return self._insert(self._header				,lowerCamelCase__				,self._header._next				)





	def 			UpperCamelCase_						(				self      :       List[str]				,lowerCamelCase__      :       List[str]				):







							'''simple docstring'''
							return self._insert(self._trailer._prev				,lowerCamelCase__				,self._trailer				)





	def 			UpperCamelCase_						(				self      :       str				):







							'''simple docstring'''
							if self.is_empty():
													raise IndexError('remove_first from empty list'				)
							return self._delete(self._header._next				)





	def 			UpperCamelCase_						(				self      :       List[str]				):







							'''simple docstring'''
							if self.is_empty():
													raise IndexError('remove_first from empty list'				)
							return self._delete(self._trailer._prev				)







'''simple docstring'''
from __future__ import annotations

from queue import Queue






class 							lowercase__			:





	def __init__(				self      :       int				):







							'''simple docstring'''
							_UpperCamelCase      :	dict[int, list[int]]				       =     {}





	def 			UpperCamelCase_						(				self      :       int				):







							'''simple docstring'''
							for i in self.vertices:
													print(lowerCamelCase__				,' : '				,' -> '.join([str(lowerCamelCase__				) for j in self.vertices[i]]				)				)





	def 			UpperCamelCase_						(				self      :       Optional[Any]				,lowerCamelCase__      :       int				,lowerCamelCase__      :       int				):







							'''simple docstring'''
							if from_vertex in self.vertices:
													self.vertices[from_vertex].append(lowerCamelCase__				)
							else:
													_UpperCamelCase      :	Any				       =     [to_vertex]





	def 			UpperCamelCase_						(				self      :       int				,lowerCamelCase__      :       int				):







							'''simple docstring'''
							_UpperCamelCase      :	Dict				       =     set()

							# create a first in first out queue to store all the vertices for BFS
							_UpperCamelCase      :	Queue				       =     Queue()

							# mark the source node as visited and enqueue it
							visited.add(lowerCamelCase__				)
							queue.put(lowerCamelCase__				)

							while not queue.empty():
													_UpperCamelCase      :	Optional[Any]				       =     queue.get()

													# loop through all adjacent vertex and enqueue it if not yet visited
													for adjacent_vertex in self.vertices[vertex]:
																			if adjacent_vertex not in visited:
																									queue.put(lowerCamelCase__				)
																									visited.add(lowerCamelCase__				)
							return visited


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

					testmod(verbose=True)

					snake_case_				:			int						 =						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()
					# 0  :  1 -> 2
					# 1  :  2
					# 2  :  0 -> 3
					# 3  :  3

					assert sorted(g.bfs(2)) == [0, 1, 2, 3]


