input: 
  def shortestPath(grid, k):
      """
      Consider a grid with N rows and columns (N >= 2) and a positive integer k.
      Every cell in the grid contains a unique value from the set {1, 2, ..., N * N}.
  
      The goal is to identify the shortest path that visits exactly k cells. You
      can start from any cell, and in each move, proceed to an adjacent cell,
      meaning a cell sharing a side.
  
      It's important to note that you cannot leave the boundaries of the grid.
      A path P (of length k) is defined as smaller than another path Q (of length k)
      if turning the values of their traversed cells into ordered lists (P_list and Q_list),
      you will find that P_list is lexicographically smaller than Q_list. That means,
      there exists some position i (1 <= i <= k) where P_list[i] < Q_list[i] and
      for all indices j (1 <= j < i), we have P_list[j] = Q_list[j].
      
      You are assured there is a unique solution.
      The function should return the list of values that the optimal path navigates through.
  
      Examples:
  
          Input: grid = [ [1,2,3], [4,5,6], [7,8,9]], k = 3
          Output: [1, 2, 1]
  
          Input: grid = [ [5,9,3], [4,1,6], [7,8,2]], k = 1
          Output: [1]
      """
  
output:     
      import heapq
  
      def get_neighbors(x, y, N):
          for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
              nx, ny = x + dx, y + dy
              if 0 <= nx < N and 0 <= ny < N:
                  yield nx, ny
  
      N = len(grid)
      min_heap = []
      
      for i in range(N):
          for j in range(N):
              heapq.heappush(min_heap, (grid[i][j], i, j, [(i, j)]))
      
      while min_heap:
          val, x, y, path = heapq.heappop(min_heap)
          if len(path) == k:
              return [grid[i][j] for i, j in path]
          
          for nx, ny in get_neighbors(x, y, N):
              if (nx, ny) not in path:
                  new_path = path + [(nx, ny)]
                  heapq.heappush(min_heap, (grid[nx][ny], nx, ny, new_path))
  