Python Double BFS
\nfrom collections import deque\n\nclass Solution:\n    def minPushBox(self, grid: List[List[str]]) -> int:\n        \n        in_bounds = lambda grid, i, j : 0
```\nfrom collections import deque\n\nclass Solution:\n    def minPushBox(self, grid: List[List[str]]) -> int:\n        \n        in_bounds = lambda grid, i, j : 0 <= i < len(grid) and 0 <= j < len(grid[0])\n        \n        dirs = [\n            (1, 0),\n            (-1, 0),\n            (0, 1),\n            (0, -1)\n        ]\n\n        def mover_bfs(grid, mover, behind_box, box):\n            \n            queue = deque([mover])\n            visited = set()\n            \n            while queue:\n                move_pos = queue.popleft()\n                \n                if move_pos in visited:\n                    continue\n                    \n                visited.add(move_pos)\n                \n                if move_pos == behind_box:\n                    return True\n                x, y = move_pos\n                for d in dirs:\n                    r, c = x + d[0], y + d[1]\n                    \n                    if not in_bounds(grid, r, c) or (r, c) == box or grid[r][c] == \'#\':\n                        continue\n                    \n                    queue.append((r, c))\n            return False\n\n        def box_bfs(grid, box, start, dest):\n            queue = deque([ (box, start, 0) ])\n            visited = set()\n            while queue:\n                box_pos, mover_pos, moves = queue.popleft()\n                if box_pos == dest:\n                    return moves\n                \n                if (box_pos, mover_pos) in visited:\n                    continue\n                \n                visited.add((box_pos, mover_pos))\n\n                x, y = box_pos\n                x1, y1 = mover_pos\n\n                for d in dirs:\n                    r, c = x + d[0], y + d[1]\n                    \n                    if not in_bounds(grid, r, c) or grid[r][c] == \'#\' or (r, c) in visited:\n                        continue\n                    \n                    next_mover_pos = x + (-1) * d[0], y + (-1) * d[1]\n                    if not mover_bfs(grid, mover_pos, next_mover_pos, box_pos):\n                        continue\n                    queue.append(((r, c), next_mover_pos, moves + 1))\n            return -1\n\n        start = None\n        box = None\n        target = None\n        \n        rows = len(grid)\n        cols = len(grid[0])\n        \n        for r in range(rows):\n            for c in range(cols):\n                if grid[r][c] == \'S\':\n                    start = (r, c)\n                elif grid[r][c] == \'T\':\n                    target = (r, c)\n                elif grid[r][c] == \'B\':\n                    box = (r, c)\n        \n        return box_bfs(grid, box, start, target)\n```
[]