


from heapq import heappop, heappush

import numpy as np

def 						_UpperCAmelCase				(			SCREAMING_SNAKE_CASE__			:					np.ndarray			,     SCREAMING_SNAKE_CASE__			:					tuple[int, int]			,     SCREAMING_SNAKE_CASE__			:					tuple[int, int]			,     SCREAMING_SNAKE_CASE__			:					bool			,     ):
     __UpperCamelCase							,      __UpperCamelCase    							=grid.shape
     __UpperCamelCase    							=[-1, 1, 0, 0]
     __UpperCamelCase    							=[0, 0, -1, 1]
     if allow_diagonal:
          dx += [-1, -1, 1, 1]
          dy += [-1, 1, -1, 1]

     __UpperCamelCase							,      __UpperCamelCase    							=[(0, source)], set()
     __UpperCamelCase    							=np.full((rows, cols)			,     np.inf				)
     __UpperCamelCase    							=0
     __UpperCamelCase    							=np.empty((rows, cols)			,     dtype=SCREAMING_SNAKE_CASE__				)
     __UpperCamelCase    							=None

     while queue:
          ((__UpperCamelCase)							,      (__UpperCamelCase))    							=heappop(SCREAMING_SNAKE_CASE__				)
          if (x, y) in visited:
               continue
          visited.add((x, y)				)

          if (x, y) == destination:
               __UpperCamelCase    							=[]
               while (x, y) != source:
                    path.append((x, y)				)
                    __UpperCamelCase							,      __UpperCamelCase    							=predecessors[x, y]
               path.append(SCREAMING_SNAKE_CASE__				)  # add the source manually
               path.reverse()
               return matrix[destination], path

          for i in range(len(SCREAMING_SNAKE_CASE__				)				):
               __UpperCamelCase							,      __UpperCamelCase    							=x + dx[i], y + dy[i]
               if 0 <= nx < rows and 0 <= ny < cols:
                    __UpperCamelCase    							=grid[nx][ny]
                    if next_node == 1 and matrix[nx, ny] > dist + 1:
                         heappush(SCREAMING_SNAKE_CASE__			,     (dist + 1, (nx, ny))				)
                         __UpperCamelCase    							=dist + 1
                         __UpperCamelCase    							=(x, y)

     return np.inf, []


if __name__ == "__main__":
   import doctest

   doctest.testmod()









_A		       =						{0: [2, 3], 1: [0], 2: [1], 3: [4], 4: []}

_A		       =						{0: [1, 2, 3], 1: [2], 2: [0], 3: [4], 4: [5], 5: [3]}

def 						_UpperCAmelCase				(			SCREAMING_SNAKE_CASE__			:					dict[int, list[int]]			,     SCREAMING_SNAKE_CASE__			:					int			,     SCREAMING_SNAKE_CASE__			:					list[bool]				):
     __UpperCamelCase    							=True
     __UpperCamelCase    							=[]

     for neighbour in graph[vert]:
          if not visited[neighbour]:
               order += topology_sort(SCREAMING_SNAKE_CASE__			,     SCREAMING_SNAKE_CASE__			,     SCREAMING_SNAKE_CASE__				)

     order.append(SCREAMING_SNAKE_CASE__				)

     return order

def 						_UpperCAmelCase				(			SCREAMING_SNAKE_CASE__			:					dict[int, list[int]]			,     SCREAMING_SNAKE_CASE__			:					int			,     SCREAMING_SNAKE_CASE__			:					list[bool]				):
     __UpperCamelCase    							=True
     __UpperCamelCase    							=[vert]

     for neighbour in reversed_graph[vert]:
          if not visited[neighbour]:
               component += find_components(SCREAMING_SNAKE_CASE__			,     SCREAMING_SNAKE_CASE__			,     SCREAMING_SNAKE_CASE__				)

     return component





def 						_UpperCAmelCase				(			SCREAMING_SNAKE_CASE__			:					dict[int, list[int]]				):
     __UpperCamelCase    							=len(SCREAMING_SNAKE_CASE__				) * [False]
     __UpperCamelCase    							={vert: [] for vert in range(len(SCREAMING_SNAKE_CASE__				)				)}

     for vert, neighbours in graph.items():
          for neighbour in neighbours:
               reversed_graph[neighbour].append(SCREAMING_SNAKE_CASE__				)

     __UpperCamelCase    							=[]
     for i, was_visited in enumerate(SCREAMING_SNAKE_CASE__				):
          if not was_visited:
               order += topology_sort(SCREAMING_SNAKE_CASE__			,     SCREAMING_SNAKE_CASE__			,     SCREAMING_SNAKE_CASE__				)

     __UpperCamelCase    							=[]
     __UpperCamelCase    							=len(SCREAMING_SNAKE_CASE__				) * [False]

     for i in range(len(SCREAMING_SNAKE_CASE__				)				):
          __UpperCamelCase    							=order[len(SCREAMING_SNAKE_CASE__				) - i - 1]
          if not visited[vert]:
               __UpperCamelCase    							=find_components(SCREAMING_SNAKE_CASE__			,     SCREAMING_SNAKE_CASE__			,     SCREAMING_SNAKE_CASE__				)
               components_list.append(SCREAMING_SNAKE_CASE__				)

     return components_list





