Java
\nimport java.util.*;\n\nclass Solution {\n    int m, n;\n    char[][] grid;\n    private static final int[][] DIRECTIONS = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};\
```\nimport java.util.*;\n\nclass Solution {\n    int m, n;\n    char[][] grid;\n    private static final int[][] DIRECTIONS = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};\n\n    public int minPushBox(char[][] grid) {\n        Queue<int[]> q1 = new ArrayDeque<>();\n        int[] man = null, box = null, destination = null;\n        m = grid.length;\n        n = grid[0].length;\n        this.grid = grid;\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < n; j++) {\n                if (grid[i][j] == \'T\') {\n                    grid[i][j] = \'.\';\n                    destination = new int[]{i, j};\n                } else if (grid[i][j] == \'S\') {\n                    man = new int[]{i, j};\n                    grid[i][j] = \'.\';\n                } else if (grid[i][j] == \'B\') {\n                    box = new int[]{i, j};\n                    grid[i][j] = \'.\';\n                }\n            }\n        }\n        Set<String> set = new HashSet<>();\n        if (goUp(man, box)) {\n            set.add(box[0] - 1 + " " + box[1] + " " + box[0] + " " + box[1]);\n            q1.add(new int[]{box[0] - 1, box[1], box[0], box[1]});\n        }\n        if (goDown(man, box)) {\n            set.add(box[0] + 1 + " " + box[1] + " " + box[0] + " " + box[1]);\n            q1.add(new int[]{box[0] + 1, box[1], box[0], box[1]});\n        }\n        if (goLeft(man, box)) {\n            set.add(box[0] + " " + (box[1] - 1) + " " + box[0] + " " + box[1]);\n            q1.add(new int[]{box[0], box[1] - 1, box[0], box[1]});\n        }\n        if (goRight(man, box)) {\n            set.add(box[0] + " " + (box[1] + 1) + " " + box[0] + " " + box[1]);\n            q1.add(new int[]{box[0], box[1] + 1, box[0], box[1]});\n        }\n        if (q1.isEmpty()) return -1;\n        int step = 0;\n        while (!q1.isEmpty()) {\n            int size = q1.size();\n            for (int z = 0; z < size; z++) {\n                int[] node = q1.poll();\n                box = new int[]{node[2], node[3]};\n                man = new int[]{node[0], node[1]};\n                if (node[2] == destination[0] && node[3] == destination[1]) {\n                    return step;\n                }\n                if (goRight(man, box)) {\n                    goFromRight(box, set, q1);\n                }\n                if (goUp(man, box)) {\n                    goFromUp(box, set, q1);\n                }\n                if (goDown(man, box)) {\n                    goFromDown(box, set, q1);\n                }\n                if (goLeft(man, box)) {\n                    goFromLeft(box, set, q1);\n                }\n            }\n            step++;\n        }\n        return -1;\n    }\n\n    private void goFromRight(int[] box, Set<String> set, Queue<int[]> q1) {\n        String next = box[0] + " " + box[1] + " " + box[0] + " " + (box[1] - 1);\n        if (box[1] - 1 >= 0 && !set.contains(next) && grid[box[0]][box[1] - 1] == \'.\') {\n            set.add(next);\n            q1.add(new int[]{box[0], box[1], box[0], box[1] - 1});\n        }\n    }\n\n    private void goFromLeft(int[] box, Set<String> set, Queue<int[]> q1) {\n        String next = box[0] + " " + box[1] + " " + box[0] + " " + box[1] + 1;\n        if (box[1] + 1 < n && !set.contains(next) && grid[box[0]][box[1] + 1] == \'.\') {\n            set.add(next);\n            q1.add(new int[]{box[0], box[1], box[0], box[1] + 1});\n        }\n    }\n\n    private void goFromDown(int[] box, Set<String> set, Queue<int[]> q1) {\n        String next = box[0] + " " + box[1] + " " + (box[0] - 1) + " " + box[1];\n        if (box[0] - 1 >= 0 && !set.contains(next) && grid[box[0] - 1][box[1]] == \'.\') {\n            set.add(next);\n            q1.add(new int[]{box[0], box[1], box[0] - 1, box[1]});\n        }\n    }\n\n    private void goFromUp(int[] box, Set<String> set, Queue<int[]> q1) {\n        String next = box[0] + " " + box[1] + " " + (box[0] + 1) + " " + box[1];\n        if (box[0] + 1 < m && !set.contains(next) && grid[box[0] + 1][box[1]] == \'.\') {\n            set.add(next);\n            q1.add(new int[]{box[0], box[1], box[0] + 1, box[1]});\n        }\n    }\n\n    private boolean goUp(int[] man, int[] box) {\n        return bfs(man, box[0] - 1, box[1], box);\n    }\n\n    private boolean goDown(int[] man, int[] box) {\n        return bfs(man, box[0] + 1, box[1], box);\n    }\n\n    private boolean goLeft(int[] man, int[] box) {\n        return bfs(man, box[0], box[1] - 1, box);\n    }\n\n    private boolean goRight(int[] man, int[] box) {\n        return bfs(man, box[0], box[1] + 1, box);\n    }\n\n    private boolean bfs(int[] man, int iEnd, int jEnd, int[] box) {\n        if (iEnd < 0 || iEnd >= m || jEnd < 0 || jEnd >= n) {\n            return false;\n        }\n        Queue<int[]> q = new ArrayDeque<>();\n        q.add(man);\n        boolean[][] visited = new boolean[m][n];\n        visited[man[0]][man[1]] = true;\n        while (!q.isEmpty()) {\n            int[] node = q.poll();\n            if (node[0] == iEnd && node[1] == jEnd) {\n                return true;\n            }\n            for (int[] dir : DIRECTIONS) {\n                int x = dir[0] + node[0];\n                int y = dir[1] + node[1];\n                if (Arrays.equals(new int[]{x, y}, box)) continue;\n                if (x >= 0 && y >= 0 && x < m && y < n && grid[x][y] == \'.\' && !visited[x][y]) {\n                    q.add(new int[]{x, y});\n                    visited[x][y] = true;\n                }\n            }\n        }\n        return false;\n    }\n}\n```
[]