'''simple docstring'''

import math
import sys




class 		SCREAMING_SNAKE_CASE_				:



			"""simple docstring"""






			def __init__(       self				):
									snake_case   :					Optional[int]							=						0
									snake_case   :					Union[str, Any]							=						[]
									snake_case   :					Dict							=						{}  # To store the pos of node in array



			def      lowerCamelCase   (       self				):
									return self.cur_size == 0



			def      lowerCamelCase   (       self							, snake_case_				):
									snake_case   :					Any							=						self.left(snake_case_				)
									snake_case   :					Optional[Any]							=						self.right(snake_case_				)
									if lc < self.cur_size and self.array(snake_case_				)[0] < self.array(snake_case_				)[0]:
															snake_case   :					Optional[int]							=						lc
									else:
															snake_case   :					Optional[Any]							=						idx
									if rc < self.cur_size and self.array(snake_case_				)[0] < self.array(snake_case_				)[0]:
															snake_case   :					Any							=						rc
									if smallest != idx:
															self.swap(snake_case_							, snake_case_				)
															self.min_heapify(snake_case_				)



			def      lowerCamelCase   (       self							, snake_case_				):
									# Inserts a node into the Priority Queue
									snake_case   :					List[str]							=						self.cur_size
									self.cur_size += 1
									self.array.append((sys.maxsize, tup[1])				)
									self.decrease_key((sys.maxsize, tup[1])							, tup[0]				)



			def      lowerCamelCase   (       self				):
									# Removes and returns the min element at top of priority queue
									snake_case   :					Optional[int]							=						self.array[0][1]
									snake_case   :					List[Any]							=						self.array[self.cur_size - 1]
									self.cur_size -= 1
									self.min_heapify(1				)
									del self.pos[min_node]
									return min_node



			def      lowerCamelCase   (       self							, snake_case_				):
									# returns the index of left child
									return 2 * i + 1



			def      lowerCamelCase   (       self							, snake_case_				):
									# returns the index of right child
									return 2 * i + 2



			def      lowerCamelCase   (       self							, snake_case_				):
									# returns the index of parent
									return math.floor(i / 2				)



			def      lowerCamelCase   (       self							, snake_case_							, snake_case_				):
									# swaps array elements at indices i and j
									# update the pos{}
									snake_case   :					Optional[Any]							=						j
									snake_case   :					str							=						i
									snake_case   :					Any							=						self.array[i]
									snake_case   :					Tuple							=						self.array[j]
									snake_case   :					List[str]							=						temp






			def      lowerCamelCase   (       self							, snake_case_							, snake_case_				):
									snake_case   :					Any							=						self.pos[tup[1]]
									# assuming the new_d is atmost old_d
									snake_case   :					List[str]							=						(new_d, tup[1])
									while idx > 0 and self.array[self.par(snake_case_				)][0] > self.array[idx][0]:
															self.swap(snake_case_							, self.par(snake_case_				)				)
															snake_case   :					List[Any]							=						self.par(snake_case_				)







class 		SCREAMING_SNAKE_CASE_				:



			"""simple docstring"""






			def __init__(       self							, snake_case_				):
									snake_case   :					Union[str, Any]							=						{}  # To store graph: u -> (v,w)
									snake_case   :					Dict							=						num  # Number of nodes in graph
									# To store the distance from source vertex
									snake_case   :					List[Any]							=						[0] * self.num_nodes
									snake_case   :					Optional[int]							=						[-1] * self.num_nodes  # To store the path



			def      lowerCamelCase   (       self							, snake_case_							, snake_case_							, snake_case_				):
									#  Edge going from node u to v and v to u with weight w
									# u (w)-> v, v (w) -> u
									# Check if u already in graph
									if u in self.adjList:
															self.adjList[u].append((v, w)				)
									else:
															snake_case   :					Union[str, Any]							=						[(v, w)]

									# Assuming undirected graph
									if v in self.adjList:
															self.adjList[v].append((u, w)				)
									else:
															snake_case   :					int							=						[(u, w)]



			def      lowerCamelCase   (       self				):
									# u -> v(w)
									for u in self.adjList:
															print(snake_case_							, "->"							, " -> ".join(str(F"""{v}({w})"""				) for v, w in self.adjList[u]				)				)



			def      lowerCamelCase   (       self							, snake_case_				):
									# Flush old junk values in par[]
									snake_case   :					int							=						[-1] * self.num_nodes
									# src is the source node
									snake_case   :					Dict							=						0
									snake_case   :					Optional[int]							=						PriorityQueue()
									q.insert((0, src)				)  # (dist from src, node)
									for u in self.adjList:
															if u != src:
																					snake_case   :					Any							=						sys.maxsize  # Infinity
																					snake_case   :					Tuple							=						-1

									while not q.is_empty():
															snake_case   :					str							=						q.extract_min()  # Returns node with the min dist from source
															# Update the distance of all the neighbours of u and
															# if their prev dist was INFINITY then push them in Q
															for v, w in self.adjList[u]:
																					snake_case   :					str							=						self.dist[u] + w
																					if self.dist[v] > new_dist:
																											if self.dist[v] == sys.maxsize:
																																	q.insert((new_dist, v)				)
																											else:
																																	q.decrease_key((self.dist[v], v)							, snake_case_				)
																											snake_case   :					int							=						new_dist
																											snake_case   :					List[str]							=						u

        # Show the shortest distances from src
									self.show_distances(snake_case_				)



			def      lowerCamelCase   (       self							, snake_case_				):
									print(F"""Distance from node: {src}"""				)
									for u in range(self.num_nodes				):
															print(F"""Node {u} has distance: {self.dist[u]}"""				)






			def      lowerCamelCase   (       self							, snake_case_							, snake_case_				):
									# To show the shortest path from src to dest
									# WARNING: Use it *after* calling dijkstra
									snake_case   :					List[str]							=						[]
									snake_case   :					Tuple							=						0
									snake_case   :					Optional[int]							=						dest
									# Backtracking from dest to src
									while self.par[temp] != -1:
															path.append(snake_case_				)
															if temp != src:
																					for v, w in self.adjList[temp]:
																											if v == self.par[temp]:
																																	cost += w
																																	break
															snake_case   :					Tuple							=						self.par[temp]
									path.append(snake_case_				)
									path.reverse()

									print(F"""----Path to reach {dest} from {src}----"""				)
									for u in path:
															print(F"""{u}"""							, end=" "				)
															if u != dest:
																					print("-> "							, end=""				)

									print("\nTotal cost of path: "							, snake_case_				)


if __name__ == "__main__":
						A_        =   Graph(9)
						graph.add_edge(0, 1, 4)
						graph.add_edge(0, 7, 8)
						graph.add_edge(1, 2, 8)
						graph.add_edge(1, 7, 11)
						graph.add_edge(2, 3, 7)
						graph.add_edge(2, 8, 2)
						graph.add_edge(2, 5, 4)
						graph.add_edge(3, 4, 9)
						graph.add_edge(3, 5, 14)
						graph.add_edge(4, 5, 10)
						graph.add_edge(5, 6, 2)
						graph.add_edge(6, 7, 1)
						graph.add_edge(6, 8, 6)
						graph.add_edge(7, 8, 7)
						graph.show_graph()
						graph.dijkstra(0)
						graph.show_path(0, 4)

# OUTPUT
# 0 -> 1(4) -> 7(8)
# 1 -> 0(4) -> 2(8) -> 7(11)
# 7 -> 0(8) -> 1(11) -> 6(1) -> 8(7)
# 2 -> 1(8) -> 3(7) -> 8(2) -> 5(4)
# 3 -> 2(7) -> 4(9) -> 5(14)
# 8 -> 2(2) -> 6(6) -> 7(7)
# 5 -> 2(4) -> 3(14) -> 4(10) -> 6(2)
# 4 -> 3(9) -> 5(10)
# 6 -> 5(2) -> 7(1) -> 8(6)
# Distance from node: 0
# Node 0 has distance: 0
# Node 1 has distance: 4
# Node 2 has distance: 12
# Node 3 has distance: 19
# Node 4 has distance: 21
# Node 5 has distance: 11
# Node 6 has distance: 9
# Node 7 has distance: 8
# Node 8 has distance: 14
# ----Path to reach 4 from 0----
# 0 -> 7 -> 6 -> 5 -> 4
# Total cost of path:  21






'''simple docstring'''

from __future__ import annotations


def 					UpperCAmelCase__      (							_lowerCAmelCase						: int)						->		int | None:



						"""simple docstring"""

						for r in range(1,			_lowerCAmelCase):
												snake_case   :					Optional[Any]							=						[]
												for x in range(n - 1):
																		snake_case   :					int							=						pow(_lowerCAmelCase,			_lowerCAmelCase,			_lowerCAmelCase)
																		if val in li:
																								break
																		li.append(_lowerCAmelCase)
												else:
																		return r
						return None


if __name__ == "__main__":
						A_        =   int(input("Enter a prime number q: "))
						A_        =   find_primitive(q)
						if a is None:
												print(f"Cannot find the primitive for the value: {a!r}")
						else:
												A_        =   int(input("Enter private key of A: "))
												A_        =   pow(a, a_private, q)
												A_        =   int(input("Enter private key of B: "))
												A_        =   pow(a, b_private, q)

												A_        =   pow(b_public, a_private, q)
												A_        =   pow(a_public, b_private, q)

												print("The key value generated by A is: ", a_secret)
												print("The key value generated by B is: ", b_secret)





