




'''simple docstring'''





# 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

_SCREAMING_SNAKE_CASE							:   List[str]      		= TypeVar("T")




class  _snake_case		(	Generic[T]							):




			def __init__(					self				,							a__ = True							)				->				None:

										'''simple docstring'''




										snake_case_						=      {}  # dictionary of lists
										snake_case_						=      directed




			def    lowerCAmelCase__				(					self				,							a__				,							a__							)				->				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(a__							)
																								self.adj_list[destination_vertex].append(a__							)
																	# 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(a__							)
																								snake_case_						=      [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(a__							)
																								snake_case_						=      [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:
																								snake_case_						=      [destination_vertex]
																								snake_case_						=      [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(a__							)
																	# 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(a__							)
																								snake_case_						=      []
																	# 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:
																								snake_case_						=      [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:
																								snake_case_						=      [destination_vertex]
																								snake_case_						=      []

										return self




			def __repr__(					self							)				->				str:

										'''simple docstring'''




										return pformat(self.adj_list							)











"""simple docstring"""
def      __lowerCamelCase   (							a_     :		int ,   a_     :		str							)			->      Optional[int]:
      __SCREAMING_SNAKE_CASE   :Optional[int]						=  [1]
      for i in range(2 ,   a_							):
            factorials.append(factorials[-1] * i							)
      assert 0 <= k < factorials[-1] * n, "k out of bounds"

      __SCREAMING_SNAKE_CASE   :List[str]						=  []
      __SCREAMING_SNAKE_CASE   :Optional[Any]						=  list(range(a_							)							)

      # Find permutation
      while factorials:
            __SCREAMING_SNAKE_CASE   :Optional[int]						=  factorials.pop()
            __SCREAMING_SNAKE_CASE				,__SCREAMING_SNAKE_CASE   :Dict						=  divmod(a_ ,   a_							)
            permutation.append(elements[number]							)
            elements.remove(elements[number]							)
      permutation.append(elements[0]							)

      return permutation


if __name__ == "__main__":
  import doctest

  doctest.testmod()