

from __future__ import annotations

from sys import maxsize
from typing import Generic, TypeVar

lowerCAmelCase__		      =       TypeVar("""T""")



def     lowerCAmelCase__							(		SCREAMING_SNAKE_CASE_:							int					)	->					int:




				'''simple docstring'''





				return (position - 1) // 2



def     lowerCAmelCase__							(		SCREAMING_SNAKE_CASE_:							int					)	->					int:




				'''simple docstring'''





				return (2 * position) + 1



def     lowerCAmelCase__							(		SCREAMING_SNAKE_CASE_:							int					)	->					int:




				'''simple docstring'''





				return (2 * position) + 2

class     a__  (    Generic[T]	):
			"""simple docstring"""







			def __init__(			self				)     ->  None:
							'''simple docstring'''






							A__						=	[]
							A__						=	{}
							A__						=	0


			def __len__(			self				)     ->  int:
							'''simple docstring'''






							return self.elements


			def __repr__(			self				)     ->  str:
							'''simple docstring'''






							return str(self.heap				)


			def    UpperCamelCase						(			self				)     ->  bool:
							'''simple docstring'''






							return self.elements == 0


			def    UpperCamelCase						(			self					,					lowercase					,					lowercase				)     ->  None:
							'''simple docstring'''






							self.heap.append((elem, weight)				)
							A__						=	self.elements
							self.elements += 1
							self._bubble_up(SCREAMING_SNAKE_CASE__				)


			def    UpperCamelCase						(			self				)     ->  T:
							'''simple docstring'''






							if self.elements > 1:
											self._swap_nodes(0					,					self.elements - 1				)
							A__			, A__						=	self.heap.pop()
							del self.position_map[elem]
							self.elements -= 1
							if self.elements > 0:
											A__			, A__						=	self.heap[0]
											self._bubble_down(SCREAMING_SNAKE_CASE__				)
							return elem


			def    UpperCamelCase						(			self					,					lowercase					,					lowercase				)     ->  None:
							'''simple docstring'''






							A__						=	self.position_map[elem]
							A__						=	(elem, weight)
							if position > 0:
											A__						=	get_parent_position(SCREAMING_SNAKE_CASE__				)
											A__			, A__						=	self.heap[parent_position]
											if parent_weight > weight:
															self._bubble_up(SCREAMING_SNAKE_CASE__				)
											else:
															self._bubble_down(SCREAMING_SNAKE_CASE__				)
							else:
											self._bubble_down(SCREAMING_SNAKE_CASE__				)


			def    UpperCamelCase						(			self					,					lowercase				)     ->  None:
							'''simple docstring'''






							A__						=	self.position_map[elem]
							if curr_pos == 0:
											return None
							A__						=	get_parent_position(SCREAMING_SNAKE_CASE__				)
							A__			, A__						=	self.heap[curr_pos]
							A__			, A__						=	self.heap[parent_position]
							if parent_weight > weight:
											self._swap_nodes(SCREAMING_SNAKE_CASE__					,					SCREAMING_SNAKE_CASE__				)
											return self._bubble_up(SCREAMING_SNAKE_CASE__				)
							return None


			def    UpperCamelCase						(			self					,					lowercase				)     ->  None:
							'''simple docstring'''






							A__						=	self.position_map[elem]
							A__			, A__						=	self.heap[curr_pos]
							A__						=	get_child_left_position(SCREAMING_SNAKE_CASE__				)
							A__						=	get_child_right_position(SCREAMING_SNAKE_CASE__				)
							if child_left_position < self.elements and child_right_position < self.elements:
											A__			, A__						=	self.heap[child_left_position]
											A__			, A__						=	self.heap[child_right_position]
											if child_right_weight < child_left_weight and child_right_weight < weight:
															self._swap_nodes(SCREAMING_SNAKE_CASE__					,					SCREAMING_SNAKE_CASE__				)
															return self._bubble_down(SCREAMING_SNAKE_CASE__				)
							if child_left_position < self.elements:
											A__			, A__						=	self.heap[child_left_position]
											if child_left_weight < weight:
															self._swap_nodes(SCREAMING_SNAKE_CASE__					,					SCREAMING_SNAKE_CASE__				)
															return self._bubble_down(SCREAMING_SNAKE_CASE__				)
							else:
											return None
							if child_right_position < self.elements:
											A__			, A__						=	self.heap[child_right_position]
											if child_right_weight < weight:
															self._swap_nodes(SCREAMING_SNAKE_CASE__					,					SCREAMING_SNAKE_CASE__				)
															return self._bubble_down(SCREAMING_SNAKE_CASE__				)
							return None


			def    UpperCamelCase						(			self					,					lowercase					,					lowercase				)     ->  None:
							'''simple docstring'''






							A__						=	self.heap[nodea_pos][0]
							A__						=	self.heap[nodea_pos][0]
							A__			, A__						=	(
							    self.heap[nodea_pos],
							    self.heap[nodea_pos],
							)
							A__						=	nodea_pos
							A__						=	nodea_pos

class     a__  (    Generic[T]	):
			"""simple docstring"""







			def __init__(			self				)     ->  None:
							'''simple docstring'''






							A__						=	{}
							A__						=	0


			def __repr__(			self				)     ->  str:
							'''simple docstring'''






							return str(self.connections				)


			def __len__(			self				)     ->  int:
							'''simple docstring'''






							return self.nodes


			def    UpperCamelCase						(			self					,					lowercase				)     ->  None:
							'''simple docstring'''






							if node not in self.connections:
											A__						=	{}
											self.nodes += 1


			def    UpperCamelCase						(			self					,					lowercase					,					lowercase					,					lowercase				)     ->  None:
							'''simple docstring'''






							self.add_node(SCREAMING_SNAKE_CASE__				)
							self.add_node(SCREAMING_SNAKE_CASE__				)
							A__						=	weight
							A__						=	weight



def     lowerCAmelCase__							(		SCREAMING_SNAKE_CASE_:							GraphUndirectedWeighted[T]		,				)	->					tuple[dict[T, int], dict[T, T | None]]:




				'''simple docstring'''





				A__						=	{node: maxsize for node in graph.connections}
				A__						=	{node: None for node in graph.connections}

				A__						=	MinPriorityQueue()
				for node, weight in dist.items():
								priority_queue.push(__lowerCAmelCase		,				__lowerCAmelCase					)

				if priority_queue.is_empty():
								return dist, parent

				# initialization
				A__						=	priority_queue.extract_min()
				A__						=	0
				for neighbour in graph.connections[node]:
								if dist[neighbour] > dist[node] + graph.connections[node][neighbour]:
												A__						=	dist[node] + graph.connections[node][neighbour]
												priority_queue.update_key(__lowerCAmelCase		,				dist[neighbour]					)
												A__						=	node

    # running prim's algorithm
				while not priority_queue.is_empty():
								A__						=	priority_queue.extract_min()
								for neighbour in graph.connections[node]:
												if dist[neighbour] > dist[node] + graph.connections[node][neighbour]:
																A__						=	dist[node] + graph.connections[node][neighbour]
																priority_queue.update_key(__lowerCAmelCase		,				dist[neighbour]					)
																A__						=	node
				return dist, parent



from abc import ABC, abstractmethod
from argparse import ArgumentParser

class    lowerCAmelCase__     (	__lowercase			):






		@staticmethod
		@abstractmethod
		def  __A       (		SCREAMING_SNAKE_CASE__		:							ArgumentParser  )     ->							str:
						raise NotImplementedError()







		@abstractmethod
		def  __A       (		self		:							Optional[int]  )     ->							Union[str, Any]:
						raise NotImplementedError()



