Djikstra
Intuition\nThe Box Movement will follow the person movement, if the person movement to the left, box should move also to the left. this means, if our next move 
# Intuition\nThe Box Movement will follow the person movement, if the person movement to the left, box should move also to the left. this means, if our next move is a current box state, we need to push the box the same direction with us. for example, if we move 1 point to left, the box also need to move 1 point. but should check possibility if we move to those direction also with the box. \n\n# Approach\n<!-- Describe your approach to solving the problem. -->\nprioritize the movement with priority queue to get the minimum movement each steps\n\n# Complexity\n- Time complexity:\n<!-- Add your time complexity here, e.g. $$O(n)$$ -->\nO((m\xD7n)^2log(m\xD7n))\n\n\n# Code\n```\ntype PQ []State\n\nfunc (pq *PQ) Push(i interface{}) {(*pq) = append((*pq), i.(State))}\nfunc (pq *PQ) Pop() (val interface{}) {\n    val = (*pq)[pq.Len()-1]\n    (*pq) = (*pq)[:pq.Len()-1]\n    return \n}\nfunc (pq PQ) Less(i, j int) bool {return pq[i].Move < pq[j].Move}\nfunc (pq PQ) Swap(i, j int) {pq[i], pq[j] = pq[j], pq[i]}\nfunc (pq PQ) Len() int {return len(pq)}\n\ntype State struct {\n    Visit\n    Move int\n}\n\ntype Visit struct {\n    Box [2]int\n    Player [2]int\n}\n\nfunc minPushBox(grid [][]byte) int {\n    visit := make(map[Visit]bool)\n    var queue PQ\n    var player, target, box [2]int\n\n    heap.Init(&queue)\n\n    for y := range grid {\n        for x := range grid[y] {\n            if grid[y][x] == \'S\' {\n                player = [2]int{y, x}\n            } else if grid[y][x] == \'B\' {\n                box = [2]int{y, x}\n            } else if grid[y][x] == \'T\' {\n                target = [2]int{y, x}\n            }\n        } \n    }\n\n    queue = append(queue, State{Visit{Box: box, Player: player}, 0})\n    dirs := [][2]int{\n        [2]int{0, -1},\n        [2]int{0, 1},\n        [2]int{-1, 0},\n        [2]int{1, 0},\n    }\n\n    for queue.Len() > 0 {\n        curr := heap.Pop(&queue).(State)\n        if visit[curr.Visit] {continue}\n        visit[curr.Visit] = true\n        if curr.Box == target {return curr.Move}\n        for _, dir := range dirs {\n            next := [2]int{curr.Player[0]+dir[0], curr.Player[1]+dir[1]}\n            nextBox := [2]int{curr.Player[0]+2*dir[0], curr.Player[1]+2*dir[1]}\n            if !Allow(grid, next[0], next[1]) {continue}\n            if next == curr.Box && !Allow(grid, nextBox[0], nextBox[1]){continue}\n            if next == curr.Box {\n                queue = append(queue, State{\n                    Move: curr.Move+1,\n                    Visit: Visit{\n                        Box: nextBox,\n                        Player: next,\n                    },\n                })\n            } else {\n                queue = append(queue, State{\n                    Visit: Visit{\n                        Box: curr.Box,\n                        Player: next,\n                    },\n                    Move: curr.Move,\n                })\n            }\n        }\n    }\n\n    return 0-1\n}\n\nfunc Allow(grid [][]byte, y, x int) bool {\n    if y < 0 || x < 0 || y == len(grid) || x == len(grid[y]) || grid[y][x] == \'#\' {return false}\n    return true\n}\n```
['Go']