'''simple docstring'''

import math
import sys





class 				lowercase    :


   def __init__( self					:						Dict)   ->       Optional[Any]:
         lowercase_     			=   0
         lowercase_     			=   []
         lowercase_     			=   {}  # To store the pos of node in array


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


   def __UpperCAmelCase							( self					:						Dict ,		__lowerCAmelCase					:						Optional[int])   ->       Dict:
         lowercase_     			=   self.left(__lowerCAmelCase)
         lowercase_     			=   self.right(__lowerCAmelCase)
         if lc < self.cur_size and self.array(__lowerCAmelCase)[0] < self.array(__lowerCAmelCase)[0]:
               lowercase_     			=   lc
         else:
               lowercase_     			=   idx
         if rc < self.cur_size and self.array(__lowerCAmelCase)[0] < self.array(__lowerCAmelCase)[0]:
               lowercase_     			=   rc
         if smallest != idx:
               self.swap(__lowerCAmelCase ,		__lowerCAmelCase)
               self.min_heapify(__lowerCAmelCase)


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


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


   def __UpperCAmelCase							( self					:						Union[str, Any] ,		__lowerCAmelCase					:						Optional[int])   ->       Dict:
         # returns the index of left child
         return 2 * i + 1


   def __UpperCAmelCase							( self					:						Optional[int] ,		__lowerCAmelCase					:						Union[str, Any])   ->       int:
         # returns the index of right child
         return 2 * i + 2


   def __UpperCAmelCase							( self					:						str ,		__lowerCAmelCase					:						Dict)   ->       Dict:
         # returns the index of parent
         return math.floor(i / 2)


   def __UpperCAmelCase							( self					:						Any ,		__lowerCAmelCase					:						Union[str, Any] ,		__lowerCAmelCase					:						Optional[Any])   ->       Dict:
         # swaps array elements at indices i and j
         # update the pos{}
         lowercase_     			=   j
         lowercase_     			=   i
         lowercase_     			=   self.array[i]
         lowercase_     			=   self.array[j]
         lowercase_     			=   temp


   def __UpperCAmelCase							( self					:						int ,		__lowerCAmelCase					:						Any ,		__lowerCAmelCase					:						Any)   ->       int:
         lowercase_     			=   self.pos[tup[1]]
         # assuming the new_d is atmost old_d
         lowercase_     			=   (new_d, tup[1])
         while idx > 0 and self.array[self.par(__lowerCAmelCase)][0] > self.array[idx][0]:
               self.swap(__lowerCAmelCase ,		self.par(__lowerCAmelCase))
               lowercase_     			=   self.par(__lowerCAmelCase)





class 				lowercase    :


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


   def __UpperCAmelCase							( self					:						List[Any] ,		__lowerCAmelCase					:						Union[str, Any] ,		__lowerCAmelCase					:						Optional[Any] ,		__lowerCAmelCase					:						int)   ->       int:
         #  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:
               lowercase_     			=   [(v, w)]

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


   def __UpperCAmelCase							( self					:						Union[str, Any])   ->       str:
         # u -> v(w)
         for u in self.adjList:
               print(__lowerCAmelCase ,		"->" ,		" -> ".join(str(F'{v}({w})') for v, w in self.adjList[u]))


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

         while not q.is_empty():
               lowercase_     			=   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]:
                     lowercase_     			=   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) ,		__lowerCAmelCase)
                           lowercase_     			=   new_dist
                           lowercase_     			=   u

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


   def __UpperCAmelCase							( self					:						Any ,		__lowerCAmelCase					:						Dict)   ->       List[str]:
         print(F'Distance from node: {src}')
         for u in range(self.num_nodes):
               print(F'Node {u} has distance: {self.dist[u]}')


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


if __name__ == "__main__":
       lowerCAmelCase_			:			Dict    	=   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 hashlib import mda, shaaaa

lowerCAmelCase_			:			Union[str, Any]    	=   (shaaaa, mda)





class 				lowercase    :


   def __init__( self					:						Optional[Any] ,		__lowerCAmelCase					:						int = 8)   ->       None:
         lowercase_     			=   0B0
         lowercase_     			=   size


   def __UpperCAmelCase							( self					:						Dict ,		__lowerCAmelCase					:						str)   ->       None:
         lowercase_     			=   self.hash_(__lowerCAmelCase)
         self.bitarray |= h


   def __UpperCAmelCase							( self					:						Union[str, Any] ,		__lowerCAmelCase					:						str)   ->       bool:
         lowercase_     			=   self.hash_(__lowerCAmelCase)
         return (h & self.bitarray) == h


   def __contains__( self					:						str ,		__lowerCAmelCase					:						str)   ->       bool:
         return self.exists(__lowerCAmelCase)


   def __UpperCAmelCase							( self					:						Union[str, Any] ,		__lowerCAmelCase					:						int)   ->       str:
         lowercase_     			=   bin(__lowerCAmelCase)[2:]
         return res.zfill(self.size)


   @property
   def __UpperCAmelCase							( self					:						Dict)   ->       str:
         return self.format_bin(self.bitarray)


   def __UpperCAmelCase							( self					:						Any ,		__lowerCAmelCase					:						str)   ->       int:
         lowercase_     			=   0B0
         for func in HASH_FUNCTIONS:
               lowercase_     			=   (
                   int.from_bytes(func(value.encode()).digest() ,		"little") % self.size
               )
               res |= 2**position
         return res


   def __UpperCAmelCase							( self					:						Union[str, Any] ,		__lowerCAmelCase					:						str)   ->       str:
         return self.format_bin(self.hash_(__lowerCAmelCase))


   @property
   def __UpperCAmelCase							( self					:						str)   ->       float:
         lowercase_     			=   bin(self.bitarray).count("1")
         return (n_ones / self.size) ** len(__lowerCAmelCase)






