






"""simple docstring"""


class 						snake_case  :





    def __init__(							self	:					Optional[Any]				,		A	:					Optional[int]			):


      '''simple docstring'''




      a     :			Dict				=   val
      # Number of nodes in left subtree
      a     :			Tuple				=   0
      a     :			Tuple				=   None
      a     :			Dict				=   None
      a     :			List[Any]				=   None





    def 				lowerCamelCase__      (							self	:					Union[str, Any]				,		A	:					Union[str, Any]			):


      '''simple docstring'''




      assert self.left_tree_size == other.left_tree_size, "Unequal Sizes of Blocks"

      if self.val < other.val:
        a     :			Tuple				=   self.right
        a     :			Tuple				=   None
        if self.right:
          a     :			List[Any]				=   other
        a     :			Union[str, Any]				=   other
        a     :			Optional[Any]				=   self.left_tree_size * 2 + 1
        return self
      else:
        a     :			int				=   other.right
        a     :			Union[str, Any]				=   None
        if other.right:
          a     :			Optional[int]				=   self
        a     :			str				=   self
        a     :			List[str]				=   other.left_tree_size * 2 + 1
        return other






class 						snake_case  :





    def __init__(							self	:					Tuple				,		A	:					int=None				,		A	:					Optional[int]=None				,		A	:					Tuple=0			):


      '''simple docstring'''




      a     :			Dict				=   heap_size
      a     :			List[str]				=   bottom_root
      a     :			str				=   min_node





    def 				lowerCamelCase__      (							self	:					Any				,		A	:					Optional[int]			):


      '''simple docstring'''




      if other.size == 0:
        return None
      if self.size == 0:
        a     :			Dict				=   other.size
        a     :			Optional[int]				=   other.bottom_root
        a     :			Any				=   other.min_node
        return None
      # Update size
      a     :			str				=   self.size + other.size

      # Update min.node
      if self.min_node.val > other.min_node.val:
        a     :			List[Any]				=   other.min_node
      # Merge

      # Order roots by left_subtree_size
      a     :			Optional[Any]				=   []
      a,     a     :			Union[str, Any]				=   self.bottom_root, other.bottom_root
      while i or j:
        if i and ((not j) or i.left_tree_size < j.left_tree_size):
          combined_roots_list.append((i, True)			)
          a     :			List[Any]				=   i.parent
        else:
          combined_roots_list.append((j, False)			)
          a     :			str				=   j.parent
        # Insert links between them
      for i in range(len(__UpperCAmelCase			) - 1			):
        if combined_roots_list[i][1] != combined_roots_list[i + 1][1]:
          a     :			List[Any]				=   combined_roots_list[i + 1][0]
          a     :			str				=   combined_roots_list[i][0]
        # Consecutively merge roots with same left_tree_size
      a     :			Any				=   combined_roots_list[0][0]
      while i.parent:
        if (
            (i.left_tree_size == i.parent.left_tree_size) and (not i.parent.parent)
        ) or (
            i.left_tree_size == i.parent.left_tree_size
            and i.left_tree_size != i.parent.parent.left_tree_size
        ):
          # Neighbouring Nodes
          a     :			Optional[int]				=   i.left
          a     :			Dict				=   i.parent.parent

          # Merging trees
          a     :			Optional[Any]				=   i.merge_trees(i.parent			)

          # Updating links
          a     :			int				=   previous_node
          a     :			int				=   next_node
          if previous_node:
            a     :			Optional[int]				=   i
          if next_node:
            a     :			str				=   i
        else:
          a     :			Union[str, Any]				=   i.parent
        # Updating self.bottom_root
      while i.left:
        a     :			Union[str, Any]				=   i.left
      a     :			int				=   i

      # Update other
      a     :			Dict				=   self.size
      a     :			Optional[int]				=   self.bottom_root
      a     :			str				=   self.min_node

      # Return the merged heap
      return self





    def 				lowerCamelCase__      (							self	:					Any				,		A	:					int			):


      '''simple docstring'''




      if self.size == 0:
        a     :			Union[str, Any]				=   Node(__UpperCAmelCase			)
        a     :			Optional[int]				=   1
        a     :			List[str]				=   self.bottom_root
      else:
        # Create new node
        a     :			str				=   Node(__UpperCAmelCase			)

        # Update size
        self.size += 1

        # update min_node
        if val < self.min_node.val:
          a     :			Optional[int]				=   new_node
        # Put new_node as a bottom_root in heap
        a     :			Optional[Any]				=   new_node
        a     :			Optional[int]				=   self.bottom_root
        a     :			Optional[int]				=   new_node

        # Consecutively merge roots with same left_tree_size
        while (
            self.bottom_root.parent
            and self.bottom_root.left_tree_size
            == self.bottom_root.parent.left_tree_size
        ):
          # Next node
          a     :			Any				=   self.bottom_root.parent.parent

          # Merge
          a     :			List[str]				=   self.bottom_root.merge_trees(self.bottom_root.parent			)

          # Update Links
          a     :			Tuple				=   next_node
          a     :			List[str]				=   None
          if next_node:
            a     :			str				=   self.bottom_root





    def 				lowerCamelCase__      (							self	:					Optional[Any]			):


      '''simple docstring'''




      return self.min_node.val





    def 				lowerCamelCase__      (							self	:					int			):


      '''simple docstring'''




      return self.size == 0





    def 				lowerCamelCase__      (							self	:					int			):


      '''simple docstring'''




      a     :			int				=   self.min_node.val

      # Last element in heap corner case
      if self.size == 1:
        # Update size
        a     :			int				=   0

        # Update bottom root
        a     :			int				=   None

        # Update min_node
        a     :			Union[str, Any]				=   None

        return min_value
      # No right subtree corner case
      # The structure of the tree implies that this should be the bottom root
      # and there is at least one other root
      if self.min_node.right is None:
        # Update size
        self.size -= 1

        # Update bottom root
        a     :			Union[str, Any]				=   self.bottom_root.parent
        a     :			int				=   None

        # Update min_node
        a     :			Tuple				=   self.bottom_root
        a     :			str				=   self.bottom_root.parent
        while i:
          if i.val < self.min_node.val:
            a     :			Tuple				=   i
          a     :			Tuple				=   i.parent
        return min_value
      # General case
      # Find the BinomialHeap of the right subtree of min_node
      a     :			List[str]				=   self.min_node.right
      a     :			Dict				=   None
      a     :			str				=   bottom_of_new
      a     :			int				=   1

      # Size, min_node and bottom_root
      while bottom_of_new.left:
        a     :			Tuple				=   size_of_new * 2 + 1
        a     :			Any				=   bottom_of_new.left
        if bottom_of_new.val < min_of_new.val:
          a     :			Tuple				=   bottom_of_new
        # Corner case of single root on top left path
      if (not self.min_node.left) and (not self.min_node.parent):
        a     :			Union[str, Any]				=   size_of_new
        a     :			Optional[int]				=   bottom_of_new
        a     :			str				=   min_of_new
        # print("Single root, multiple nodes case")
        return min_value
      # Remaining cases
      # Construct heap of right subtree
      a     :			str				=   BinomialHeap(
          bottom_root=__UpperCAmelCase				,		min_node=__UpperCAmelCase				,		heap_size=__UpperCAmelCase			)

      # Update size
      a     :			Tuple				=   self.size - 1 - size_of_new

      # Neighbour nodes
      a     :			int				=   self.min_node.left
      a     :			Union[str, Any]				=   self.min_node.parent

      # Initialize new bottom_root and min_node
      a     :			Tuple				=   previous_node or next_node
      a     :			Optional[Any]				=   next_node

      # Update links of previous_node and search below for new min_node and
      # bottom_root
      if previous_node:
        a     :			Tuple				=   next_node

        # Update bottom_root and search for min_node below
        a     :			List[Any]				=   previous_node
        a     :			List[Any]				=   previous_node
        while self.bottom_root.left:
          a     :			Optional[int]				=   self.bottom_root.left
          if self.bottom_root.val < self.min_node.val:
            a     :			List[Any]				=   self.bottom_root
      if next_node:
        a     :			Tuple				=   previous_node

        # Search for new min_node above min_node
        a     :			Any				=   next_node
        while i:
          if i.val < self.min_node.val:
            a     :			str				=   i
          a     :			int				=   i.parent
        # Merge heaps
      self.merge_heaps(__UpperCAmelCase			)

      return min_value





    def 				lowerCamelCase__      (							self	:					Optional[int]			):


      '''simple docstring'''




      a     :			List[str]				=   self.bottom_root
      while top_root.parent:
        a     :			int				=   top_root.parent
      # preorder
      a     :			Optional[Any]				=   []
      self.__traversal(__UpperCAmelCase				,		__UpperCAmelCase			)
      return heap_pre_order





    def 				lowerCamelCase__      (							self	:					Optional[int]				,		A	:					Union[str, Any]				,		A	:					Tuple				,		A	:					Optional[Any]=0			):


      '''simple docstring'''




      if curr_node:
        preorder.append((curr_node.val, level)			)
        self.__traversal(curr_node.left				,		__UpperCAmelCase				,		level + 1			)
        self.__traversal(curr_node.right				,		__UpperCAmelCase				,		level + 1			)
      else:
        preorder.append(('#', level)			)





    def __str__(							self	:					Any			):


      '''simple docstring'''




      if self.is_empty():
        return ""
      a     :			Union[str, Any]				=   self.pre_order()

      return "\n".join(('-' * level + str(__UpperCAmelCase			)) for value, level in preorder_heap			)


# Unit Tests
if __name__ == "__main__":
   import doctest

   doctest.testmod()









from __future__ import annotations



def        __a     (    lowerCAmelCase_   :					int				)      -> int | None:






						'''simple docstring'''



						for r in range(1			,lowerCAmelCase_				):
												UpperCAmelCase_=   []
												for x in range(n - 1				):
																		UpperCAmelCase_=   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)




