




# Author: OMKAR PATHAK, Nwachukwu Chidiebere

# Use a Python dictionary to construct the graph.
from __future__ import annotations

from pprint import pformat
from typing import Generic, TypeVar

a__		     =     TypeVar('''T''')


class    SCREAMING_SNAKE_CASE_				(       Generic[T]   ):



	"""simple docstring"""


	def __init__(					self		:						Tuple					,     lowerCAmelCase		:						bool = True	)	->       None:







						"""simple docstring"""







						__UpperCamelCase					:	dict[T, list[T]]             =      {}  # dictionary of lists
						__UpperCamelCase					:	int             =      directed






	def 					lowerCamelCase__     (					self		:						Any					,     lowerCAmelCase		:						T					,     lowerCAmelCase		:						T	)	->       GraphAdjacencyList[T]:







						"""simple docstring"""







						if not self.directed:  # For undirected graphs
											# if both source vertex and destination vertex are both present in the
											# adjacency list, add destination vertex to source vertex list of adjacent
											# vertices and add source vertex to destination vertex list of adjacent
											# vertices.
											if source_vertex in self.adj_list and destination_vertex in self.adj_list:
																self.adj_list[source_vertex].append(lowerCAmelCase	)
																self.adj_list[destination_vertex].append(lowerCAmelCase	)
											# if only source vertex is present in adjacency list, add destination vertex
											# to source vertex list of adjacent vertices, then create a new vertex with
											# destination vertex as key and assign a list containing the source vertex
											# as it's first adjacent vertex.
											elif source_vertex in self.adj_list:
																self.adj_list[source_vertex].append(lowerCAmelCase	)
																__UpperCamelCase					:	Union[str, Any]             =      [source_vertex]
											# if only destination vertex is present in adjacency list, add source vertex
											# to destination vertex list of adjacent vertices, then create a new vertex
											# with source vertex as key and assign a list containing the source vertex
											# as it's first adjacent vertex.
											elif destination_vertex in self.adj_list:
																self.adj_list[destination_vertex].append(lowerCAmelCase	)
																__UpperCamelCase					:	Union[str, Any]             =      [destination_vertex]
											# if both source vertex and destination vertex are not present in adjacency
											# list, create a new vertex with source vertex as key and assign a list
											# containing the destination vertex as it's first adjacent vertex also
											# create a new vertex with destination vertex as key and assign a list
											# containing the source vertex as it's first adjacent vertex.
											else:
																__UpperCamelCase					:	Optional[Any]             =      [destination_vertex]
																__UpperCamelCase					:	Optional[Any]             =      [source_vertex]
						else:  # For directed graphs
											# if both source vertex and destination vertex are present in adjacency
											# list, add destination vertex to source vertex list of adjacent vertices.
											if source_vertex in self.adj_list and destination_vertex in self.adj_list:
																self.adj_list[source_vertex].append(lowerCAmelCase	)
											# if only source vertex is present in adjacency list, add destination
											# vertex to source vertex list of adjacent vertices and create a new vertex
											# with destination vertex as key, which has no adjacent vertex
											elif source_vertex in self.adj_list:
																self.adj_list[source_vertex].append(lowerCAmelCase	)
																__UpperCamelCase					:	Union[str, Any]             =      []
											# if only destination vertex is present in adjacency list, create a new
											# vertex with source vertex as key and assign a list containing destination
											# vertex as first adjacent vertex
											elif destination_vertex in self.adj_list:
																__UpperCamelCase					:	Optional[int]             =      [destination_vertex]
											# if both source vertex and destination vertex are not present in adjacency
											# list, create a new vertex with source vertex as key and a list containing
											# destination vertex as it's first adjacent vertex. Then create a new vertex
											# with destination vertex as key, which has no adjacent vertex
											else:
																__UpperCamelCase					:	Union[str, Any]             =      [destination_vertex]
																__UpperCamelCase					:	int             =      []

						return self






	def __repr__(					self		:						Dict	)	->       str:







						"""simple docstring"""







						return pformat(self.adj_list	)












def 				A__ (snake_case   :		int				)     ->						bool:
					if number < 0:
										raise ValueError("""number must not be negative"""				)
					return number & (number - 1) == 0


if __name__ == "__main__":
	import doctest

	doctest.testmod()






