
'''simple docstring'''





from heapq import heappop, heappush

import numpy as np







def snake_case_     (					lowercase__   ,       lowercase__   ,       lowercase__   ,       lowercase__   ,       ):
  UpperCAmelCase__       ,			UpperCAmelCase__      :					Optional[Any]				       =							grid.shape
  UpperCAmelCase__      :					Tuple				       =							[-1, 1, 0, 0]
  UpperCAmelCase__      :					Optional[int]				       =							[0, 0, -1, 1]
  if allow_diagonal:
    dx += [-1, -1, 1, 1]
    dy += [-1, 1, -1, 1]

  UpperCAmelCase__       ,			UpperCAmelCase__      :					List[str]				       =							[(0, source)], set()
  UpperCAmelCase__      :					Dict				       =							np.full((rows, cols)   ,       np.inf		)
  UpperCAmelCase__      :					Tuple				       =							0
  UpperCAmelCase__      :					List[str]				       =							np.empty((rows, cols)   ,       dtype=lowercase__		)
  UpperCAmelCase__      :					Tuple				       =							None

  while queue:
    ((UpperCAmelCase__)       ,			(UpperCAmelCase__))      :					Union[str, Any]				       =							heappop(lowercase__		)
    if (x, y) in visited:
      continue
    visited.add((x, y)		)

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

    for i in range(len(lowercase__		)		):
      UpperCAmelCase__       ,			UpperCAmelCase__      :					List[str]				       =							x + dx[i], y + dy[i]
      if 0 <= nx < rows and 0 <= ny < cols:
        UpperCAmelCase__      :					Optional[Any]				       =							grid[nx][ny]
        if next_node == 1 and matrix[nx, ny] > dist + 1:
          heappush(lowercase__   ,       (dist + 1, (nx, ny))		)
          UpperCAmelCase__      :					Union[str, Any]				       =							dist + 1
          UpperCAmelCase__      :					Optional[Any]				       =							(x, y)

  return np.inf, []


if __name__ == "__main__":
      import doctest

      doctest.testmod()




import functools
from typing import Any


def 	lowerCamelCase					(	UpperCamelCase     :				str			,       UpperCamelCase     :				list[str]							)   ->    bool:

		# Validation
		if not isinstance(UpperCamelCase			,       UpperCamelCase							) or len(UpperCamelCase							) == 0:
				raise ValueError('the string should be not empty string'							)

		if not isinstance(UpperCamelCase			,       UpperCamelCase							) or not all(
		    isinstance(UpperCamelCase			,       UpperCamelCase							) and len(UpperCamelCase							) > 0 for item in words							):
				raise ValueError('the words should be a list of non-empty strings'							)

		# Build trie
		_lowerCamelCase				   =  {}
		_lowerCamelCase				   =  'WORD_KEEPER'

		for word in words:
				_lowerCamelCase				   =  trie
				for c in word:
						if c not in trie_node:
								_lowerCamelCase				   =  {}

						_lowerCamelCase				   =  trie_node[c]

				_lowerCamelCase				   =  True

		_lowerCamelCase				   =  len(UpperCamelCase							)

		# Dynamic programming method
		@functools.cache
		def is_breakable(UpperCamelCase     :				int							) -> bool:
				if index == len_string:
						return True

				_lowerCamelCase				   =  trie
				for i in range(UpperCamelCase			,       UpperCamelCase							):
						_lowerCamelCase				   =  trie_node.get(string[i]			,       UpperCamelCase							)

						if trie_node is None:
								return False

						if trie_node.get(UpperCamelCase			,       UpperCamelCase							) and is_breakable(i + 1							):
								return True

				return False

		return is_breakable(0							)


if __name__ == "__main__":
				import doctest

				doctest.testmod()