class Solution {
private:
const int M = 100;
int dir[5][2] = {0, 0, 0, 1, 0, -1, 1, 0, -1, 0};
int n, m;
int vis[100][100];
void findAll(int curi, int curj, int cost, queue<pair<int, int>>& q, vector<vector<int>>& grid) {
while (curi >= 0 && curi < n && curj >= 0 && curj < m && !vis[curi][curj]) {
q.push(make_pair(curi * 100 + curj, cost));
vis[curi][curj] = 1;
int deltaI = dir[grid[curi][curj]][0];
int deltaJ = dir[grid[curi][curj]][1];
curi += deltaI;
curj += deltaJ;
}
}
public:
int minCost(vector<vector<int>>& grid) {
n = grid.size(), m = grid[0].size();
memset(vis, sizeof(vis), 0);
queue<pair<int, int>> q; // first is index, second is cost
findAll(0, 0, 0, q, grid);
while (!q.empty()) {
auto t = q.front(); q.pop();
int curi = t.first / 100, curj = t.first % 100;
if (curi == n - 1 && curj == m - 1) return t.second;
for (int i = 1; i <= 4; i++) {
if (grid[curi][curj] == i) continue;
findAll(curi + dir[i][0], curj + dir[i][1], t.second + 1, q, grid);
}
}
throw invalid_argument("bad solution");
}
};