





# 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

_lowercase		:  Any			       =TypeVar("""T""")






class 						UpperCamelCase_  (  Generic[T]							):



					def __init__(		self     :     List[Any]       ,      lowerCamelCase     :     bool = True						):
							lowerCamelCase_	:     dict[T, list[T]] 						=      {}  # dictionary of lists
							lowerCamelCase_	:     int 						=      directed



					def   __a     (		self     :     Union[str, Any]       ,      lowerCamelCase     :     T       ,      lowerCamelCase     :     T						):

							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						)
											lowerCamelCase_	:     Optional[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						)
											lowerCamelCase_	:     Tuple 						=      [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:
											lowerCamelCase_	:     Any 						=      [destination_vertex]
											lowerCamelCase_	:     str 						=      [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						)
											lowerCamelCase_	:     Optional[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:
											lowerCamelCase_	:     Dict 						=      [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:
											lowerCamelCase_	:     Any 						=      [destination_vertex]
											lowerCamelCase_	:     Any 						=      []

							return self





					def __repr__(		self     :     Optional[Any]						):
							return pformat(self.adj_list						)







def 		_SCREAMING_SNAKE_CASE     ( lowerCAmelCase__							,lowerCAmelCase__						):
		if number < 0 or shift_amount < 0:
				raise ValueError('both inputs must be positive integers'						)

		lowerCamelCase_	:     int 						=      str(bin(lowerCAmelCase__						)						)
		binary_number += "0" * shift_amount
		return binary_number


def 		_SCREAMING_SNAKE_CASE     ( lowerCAmelCase__							,lowerCAmelCase__						):
		if number < 0 or shift_amount < 0:
				raise ValueError('both inputs must be positive integers'						)

		lowerCamelCase_	:     Union[str, Any] 						=      str(bin(lowerCAmelCase__						)						)[2:]
		if shift_amount >= len(lowerCAmelCase__						):
				return "0b0"
		lowerCamelCase_	:     List[str] 						=      binary_number[: len(lowerCAmelCase__						) - shift_amount]
		return "0b" + shifted_binary_number


def 		_SCREAMING_SNAKE_CASE     ( lowerCAmelCase__							,lowerCAmelCase__						):
		if number >= 0:  # Get binary representation of positive number
				lowerCamelCase_	:     List[Any] 						=      '0' + str(bin(lowerCAmelCase__						)						).strip('-'						)[2:]
		else:  # Get binary (2's complement) representation of negative number
				lowerCamelCase_	:     Any 						=      len(bin(lowerCAmelCase__						)[3:]						)  # Find 2's complement of number
				lowerCamelCase_	:     List[str] 						=      bin(abs(lowerCAmelCase__						) - (1 << binary_number_length)						)[3:]
				lowerCamelCase_	:     List[str] 						=      (
				    '1' + '0' * (binary_number_length - len(lowerCAmelCase__						)) + binary_number
				)

		if shift_amount >= len(lowerCAmelCase__						):
				return "0b" + binary_number[0] * len(lowerCAmelCase__						)
		return (
		    "0b"
		    + binary_number[0] * shift_amount
		    + binary_number[: len(lowerCAmelCase__						) - shift_amount]
		)


if __name__ == "__main__":
		import doctest

		doctest.testmod()
