input: 
  def solve_maze(n: int, m: int, grid: List[List[int]]) -> List[int]:
      """Given a maze represented as a 2D grid of dimensions n x m where 1 represents a valid path
      and 0 represents a wall, this function finds the path from the top-left corner (0,0) to the 
      bottom-right corner (n-1,m-1). The path is represented as a list of integers where each integer 
      indicates the number of steps taken to reach the end. If no path exists, it returns an empty list.
      The maze is assumed to be solvable, meaning there's always at least one valid path.
      
      Example:
      >>> solve_maze(3, 3, [[1, 0, 1], [1, 1, 1], [1, 0, 1]])
      [4]
      >>> solve_maze(4, 4, [[1, 1, 1, 1], [1, 0, 0, 1], [1, 1, 0, 1], [1, 1, 1, 1]])
      [6]
      >>> solve_maze(2, 2, [[1, 1], [1, 1]])
      [2]
      """
      maze = Maze(n, m)
      maze._grid = grid
      return maze.solve_maze()
  
output:     from collections import deque
  
      class Maze:
          def __init__(self, n, m):
              self.n = n
              self.m = m
              self.grid = [[0] * m for _ in range(n)]
          
          def solve_maze(self):
              queue = deque([(0, 0, 0)])
              directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
              visited = [[False] * self.m for _ in range(self.n)]
              visited[0][0] = True
              
              while queue:
                  x, y, steps = queue.popleft()
                  
                  if x == self.n - 1 and y == self.m - 1:
                      return [steps]
                  
                  for dx, dy in directions:
                      nx, ny = x + dx, y + dy
                      if 0 <= nx < self.n and 0 <= ny < self.m and not visited[nx][ny] and self.grid[nx][ny] == 1:
                          visited[nx][ny] = True
                          queue.append((nx, ny, steps + 1))
              
              return []