



'''simple docstring'''






import math
import sys



class 							lowercase :


 """simple docstring"""


 def __init__(							self							)	->     str:
        _UpperCAmelCase						:		Tuple      =				0
        _UpperCAmelCase						:		Union[str, Any]      =				[]
        _UpperCAmelCase						:		Dict      =				{}  # To store the pos of node in array







 def _snake_case				(							self							)	->     Union[str, Any]:
        return self.cur_size == 0







 def _snake_case				(							self						,a_							)	->     Dict:
        _UpperCAmelCase						:		List[Any]      =				self.left(a_							)
        _UpperCAmelCase						:		int      =				self.right(a_							)
        if lc < self.cur_size and self.array(a_							)[0] < self.array(a_							)[0]:
               _UpperCAmelCase						:		Union[str, Any]      =				lc
        else:
               _UpperCAmelCase						:		List[str]      =				idx
        if rc < self.cur_size and self.array(a_							)[0] < self.array(a_							)[0]:
               _UpperCAmelCase						:		int      =				rc
        if smallest != idx:
               self.swap(a_						,a_							)
               self.min_heapify(a_							)







 def _snake_case				(							self						,a_							)	->     Tuple:
        # Inserts a node into the Priority Queue
        _UpperCAmelCase						:		Optional[int]      =				self.cur_size
        self.cur_size += 1
        self.array.append((sys.maxsize, tup[1])							)
        self.decrease_key((sys.maxsize, tup[1])						,tup[0]							)







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







 def _snake_case				(							self						,a_							)	->     Any:
        # returns the index of left child
        return 2 * i + 1







 def _snake_case				(							self						,a_							)	->     Optional[Any]:
        # returns the index of right child
        return 2 * i + 2







 def _snake_case				(							self						,a_							)	->     Union[str, Any]:
        # returns the index of parent
        return math.floor(i / 2							)







 def _snake_case				(							self						,a_						,a_							)	->     Dict:
        # swaps array elements at indices i and j
        # update the pos{}
        _UpperCAmelCase						:		int      =				j
        _UpperCAmelCase						:		List[str]      =				i
        _UpperCAmelCase						:		Tuple      =				self.array[i]
        _UpperCAmelCase						:		Tuple      =				self.array[j]
        _UpperCAmelCase						:		Union[str, Any]      =				temp







 def _snake_case				(							self						,a_						,a_							)	->     int:
        _UpperCAmelCase						:		Optional[Any]      =				self.pos[tup[1]]
        # assuming the new_d is atmost old_d
        _UpperCAmelCase						:		Any      =				(new_d, tup[1])
        while idx > 0 and self.array[self.par(a_							)][0] > self.array[idx][0]:
               self.swap(a_						,self.par(a_							)							)
               _UpperCAmelCase						:		Dict      =				self.par(a_							)







class 							lowercase :


 """simple docstring"""


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







 def _snake_case				(							self						,a_						,a_						,a_							)	->     Any:
        #  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:
               _UpperCAmelCase						:		Any      =				[(v, w)]

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







 def _snake_case				(							self							)	->     str:
        # u -> v(w)
        for u in self.adjList:
               print(a_						,"""->"""						,""" -> """.join(str(f'''{v}({w})'''							) for v, w in self.adjList[u]							)							)







 def _snake_case				(							self						,a_							)	->     Union[str, Any]:
        # Flush old junk values in par[]
        _UpperCAmelCase						:		List[str]      =				[-1] * self.num_nodes
        # src is the source node
        _UpperCAmelCase						:		str      =				0
        _UpperCAmelCase						:		Any      =				PriorityQueue()
        q.insert((0, src)							)  # (dist from src, node)
        for u in self.adjList:
               if u != src:
                      _UpperCAmelCase						:		Tuple      =				sys.maxsize  # Infinity
                      _UpperCAmelCase						:		List[Any]      =				-1

        while not q.is_empty():
               _UpperCAmelCase						:		Dict      =				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]:
                      _UpperCAmelCase						:		Optional[Any]      =				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)						,a_							)
                             _UpperCAmelCase						:		Optional[int]      =				new_dist
                             _UpperCAmelCase						:		str      =				u

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







 def _snake_case				(							self						,a_							)	->     Tuple:
        print(f'''Distance from node: {src}'''							)
        for u in range(self.num_nodes							):
               print(f'''Node {u} has distance: {self.dist[u]}'''							)







 def _snake_case				(							self						,a_						,a_							)	->     Optional[Any]:
        # To show the shortest path from src to dest
        # WARNING: Use it *after* calling dijkstra
        _UpperCAmelCase						:		Optional[Any]      =				[]
        _UpperCAmelCase						:		Tuple      =				0
        _UpperCAmelCase						:		Optional[Any]      =				dest
        # Backtracking from dest to src
        while self.par[temp] != -1:
               path.append(a_							)
               if temp != src:
                      for v, w in self.adjList[temp]:
                             if v == self.par[temp]:
                                    cost += w
                                    break
               _UpperCAmelCase						:		Optional[int]      =				self.par[temp]
        path.append(a_							)
        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: """						,a_							)


if __name__ == "__main__":
   A_							:				Union[str, Any]						=			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, 1_1)
   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, 1_4)
   graph.add_edge(4, 5, 1_0)
   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 string import ascii_uppercase




def 					snake_case_      (  lowerCAmelCase_ ,     lowerCAmelCase_ ,     lowerCAmelCase_ = False ,     lowerCAmelCase_ = ascii_uppercase	)->	str:





       '''simple docstring'''


       _UpperCAmelCase						:		List[str]      =				keyword.upper()
       _UpperCAmelCase						:		Optional[int]      =				plaintext.upper()
       _UpperCAmelCase						:		Optional[int]      =				set(lowerCAmelCase_	)

       # create a list of unique characters in the keyword - their order matters
       # it determines how we will map plaintext characters to the ciphertext
       _UpperCAmelCase						:		str      =				[]
       for char in keyword:
              if char in alphabet_set and char not in unique_chars:
                     unique_chars.append(lowerCAmelCase_	)
    # the number of those unique characters will determine the number of rows
       _UpperCAmelCase						:		Optional[Any]      =				len(lowerCAmelCase_	)

       # create a shifted version of the alphabet
       _UpperCAmelCase						:		Optional[Any]      =				unique_chars + [
           char for char in alphabet if char not in unique_chars
       ]

       # create a modified alphabet by splitting the shifted alphabet into rows
       _UpperCAmelCase						:		List[str]      =				[
           shifted_alphabet[k : k + num_unique_chars_in_keyword]
           for k in range(0 ,     26 ,     lowerCAmelCase_	)
       ]

       # map the alphabet characters to the modified alphabet characters
       # going 'vertically' through the modified alphabet - consider columns first
       _UpperCAmelCase						:		int      =				{}
       _UpperCAmelCase						:		int      =				0
       for column in range(lowerCAmelCase_	):
              for row in modified_alphabet:
                     # if current row (the last one) is too short, break out of loop
                     if len(lowerCAmelCase_	) <= column:
                            break

                     # map current letter to letter in modified alphabet
                     _UpperCAmelCase						:		Optional[int]      =				row[column]
                     letter_index += 1

       if verbose:
              print(lowerCAmelCase_	)
       # create the encrypted text by mapping the plaintext to the modified alphabet
       return "".join(mapping[char] if char in mapping else char for char in plaintext	)


if __name__ == "__main__":
   # example use
   print(mixed_keyword("""college""", """UNIVERSITY"""))



