input: Write a function to create an object-oriented structure in Python that solves a maze. Use a class `Maze` to represent the maze structure and a method `solve_maze` to find a path from the top-left corner (0, 0) to the bottom-right corner (n-1, m-1). The maze is represented as a 2D grid where `1` represents a traversable cell and `0` represents a blocked cell. If a path exists, the function should return a list of integers representing the path lengths from the start to each cell in the path; otherwise, it should return an empty list.
  
  
  assert Maze(3, 3)._grid == [[None, None, None], [None, None, None], [None, None, None]]
  assert Maze(2, 2).solve_maze() == []
  assert Maze(3, 3)._grid == [[None, None, None], [None, None, None], [None, None, None]]
  assert Maze(3, 3).solve_maze() == []
  
output: def solve_maze(self):
      n, m = len(self._grid), len(self._grid[0])
      if self._grid[0][0] == 0 or self._grid[n-1][m-1] == 0:
          return []
      
      queue = [(0, 0, 0)]
      directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
      path_lengths = [[-1] * m for _ in range(n)]
      path_lengths[0][0] = 0
      
      while queue:
          x, y, dist = queue.pop(0)
          
          if x == n-1 and y == m-1:
              path = []
              while x != 0 or y != 0:
                  path.append(path_lengths[x][y])
                  for dx, dy in directions:
                      nx, ny = x + dx, y + dy
                      if 0 <= nx < n and 0 <= ny < m and path_lengths[nx][ny] == dist - 1:
                          x, y, dist = nx, ny, dist - 1
                          break
              path.append(0)
              return path[::-1]
          
          for dx, dy in directions:
              nx, ny = x + dx, y + dy
              if 0 <= nx < n and 0 <= ny < m and self._grid[nx][ny] == 1 and path_lengths[nx][ny] == -1:
                  path_lengths[nx][ny] = dist + 1
                  queue.append((nx, ny, dist + 1))
      
      return []