[55 Lines] [challenge me] Possible shortest C++ solution
Python is always my envy to be able to write short code.\nAfter I picked up some more knolwedge about C++, I can also write some code comparable with python in 
Python is always my envy to be able to write short code.\nAfter I picked up some more knolwedge about C++, I can also write some code comparable with python in terms of length.\nIf you can help me make it shorter, I will highly apprecitate. \n\nActually, in terms of space cost, this solution is also competitive. But I am sure there are always lots of people can do much better than me.\nSo I will be waiting for the comments from you.\n```\nRuntime: 84 ms, faster than 59.21% of C++ online submissions for Minimum Moves to Move a Box to Their Target Location.\nMemory Usage: 8.5 MB, less than 100.00% of C++ online submissions for Minimum Moves to Move a Box to Their Target Location.\n```\n\n```\nstruct Node{\n    pair<int, int> b, p;\n    int key() const {return  ( (b.first*20 + b.second) << 16 ) | (p.first*20 + p.second); };\n};\n\nclass Solution {\npublic:\n    int minPushBox(vector<vector<char>>& grid) {        \n        const int m = grid.size(), n = grid[0].size();        \n        Node start, end;\n        for(int i = 0; i < m; i++)\n            for(int j = 0; j < n; j++)\n                if(grid[i][j] == \'B\') start.b = {i, j};\n                else if(grid[i][j] == \'S\') start.p = {i, j};\n                else if(grid[i][j] == \'T\') end.b = {i, j};            \n                         \n        auto hasPath = [&](const Node& cur, int p_i, int p_j){ // hasPath: can move behind box      \n            int seen[400]={};                    \n            function <bool(int, int)> dfs = [&](int i, int j){\n                if(i < 0 || i >= m || j < 0 || j >= n || grid[i][j] == \'#\') return false;\n                if(i== cur.b.first && j == cur.b.second ) return false;                \n                if(seen[i*m+j]++) return false;                \n                if(i== p_i && j == p_j ) return true;\n                return dfs(i-1, j) || dfs(i+1, j) || dfs(i, j-1) || dfs(i, j+1);\n            };\n            \n            return dfs(cur.p.first, cur.p.second);          \n        };       \n        //canMove is true means 2 things: front cell is valid & free; back cell is accessible from mover\'s current position\n        auto canMove= [&](const Node& cur, int delta_i, int delta_j, Node& nxt){                              \n            int i = cur.b.first + delta_i, j = cur.b.second + delta_j;\n            if(i < 0 || i >= m || j <0 || j >= n || grid[i][j] == \'#\') return false;            \n            if(!hasPath(cur, cur.b.first - delta_i,  cur.b.second - delta_j) ) return false;\n            nxt.b={i,j};\n            nxt.p = cur.b;\n            return true;           \n        };        \n        \n        queue<Node> q{{start}};                \n        unordered_set<int> seen{start.key()}; \n        int dirs[5]={0, -1, 0, 1, 0};\n        for(int step = 0; !q.empty(); ++step)\n            for(int sz = q.size(); sz > 0; sz--){\n                auto cur = q.front(); q.pop();\n                Node nxt;\n                for(int i = 0; i < 4; i++){                    \n                    if(!canMove(cur, dirs[i], dirs[i+1], nxt) || seen.count(nxt.key()) ) continue;                    \n                    if(nxt.b == end.b) return step+1;\n                    seen.insert(nxt.key());\n                    q.emplace(nxt);\n                }\n            }\n        return -1;\n    }\n};\n```
['Depth-First Search', 'Breadth-First Search', 'C']