#include #include namespace cho { struct linear_index { int bg, ed; linear_index() {}; linear_index(int x, int y) : bg(x), ed(y) {}; int operator()(int i) const { assert(bg <= i && i < ed); return i - bg; } int inverse(int i) const { assert(0 <= i && i < ed - bg); return i + bg; } int size() const { return ed - bg; } }; template struct md_index { std::array ar; template md_index(Args... args) { static_assert(sizeof...(args) == dim * 2, "Args mismatch"); const std::array lr = {(int)args...}; for (int i = 0; i < dim; i++) { ar[i] = linear_index(lr[i * 2], lr[i * 2 + 1]); } } template int operator()(Args... args) const { static_assert(sizeof...(args) == dim, "Args mismatch"); const std::array ind = {(int)args...}; int res = 0; for (int i = 0; i < dim; i++) { res *= ar[i].size(); res += ar[i](ind[i]); } return res; } std::array inverse(int x) const { std::array res; for (int i = dim - 1; i >= 0; i--) { res[i] = ar[i].inverse(x % ar[i].size()); x /= ar[i].size(); } return res; } int size() const { int res = 1; for (int i = 0; i < dim; i++) res *= ar[i].size(); return res; } }; } // namespace cho using namespace std; using ll = long long; #define rep(i, s, t) for (ll i = s; i < (ll)(t); i++) #define all(x) begin(x), end(x) template bool chmin(T& x, T y) { return x > y ? (x = y, true) : false; } template bool chmax(T& x, T y) { return x < y ? (x = y, true) : false; } using mint = atcoder::modint998244353; void solve() { int h, w; cin >> h >> w; vector s(h); rep(i, 0, h) cin >> s[i]; cho::md_index<3> ind(0, h, 0, w, 0, 2); cho::md_index<2> id_h(0, h, 0, w - 1), id_w(0, h - 1, 0, w); int sz = ind.size(), szh = id_h.size(), szw = id_w.size(); auto isin = [&](int x, int y) { return 0 <= x && x < h && 0 <= y && y < w; }; vector dd = {0, 1, 0, -1, 0}; ll ans = h + w; vector dist(sz + szh + szw, 1e18); dist[0] = 0; queue q; q.push(0); while (!q.empty()) { int nw = q.front(); q.pop(); if (nw < sz) { auto [x, y, f] = ind.inverse(nw); rep(k, 0, 4) { int nx = x + dd[k], ny = y + dd[k + 1]; if (!isin(nx, ny) || s[nx][ny] == '#') continue; int nn = ind(nx, ny, f); if (chmin(dist[nn], dist[nw] + 1)) q.push(nn); } if (f == 0) { if (y < w - 1) { int nn = id_h(x, y) + sz; if (chmin(dist[nn], dist[nw] + 1)) q.push(nn); } if (y > 0) { int nn = id_h(x, y - 1) + sz; if (chmin(dist[nn], dist[nw] + 1)) q.push(nn); } if (x < h - 1) { int nn = id_w(x, y) + sz + szh; if (chmin(dist[nn], dist[nw] + 1)) q.push(nn); } if (x > 0) { int nn = id_w(x - 1, y) + sz + szh; if (chmin(dist[nn], dist[nw] + 1)) q.push(nn); } } } else if (nw < sz + szh) { auto [x, y] = id_h.inverse(nw - sz); if (x > 0) { int nn = id_h(x - 1, y) + sz; if (chmin(dist[nn], dist[nw] + 1)) q.push(nn); } if (x < h - 1) { int nn = id_h(x + 1, y) + sz; if (chmin(dist[nn], dist[nw] + 1)) q.push(nn); } { int nn = ind(x, y, 1); if (chmin(dist[nn], dist[nw] + 1)) q.push(nn); } { int nn = ind(x, y + 1, 1); if (chmin(dist[nn], dist[nw] + 1)) q.push(nn); } } else { auto [x, y] = id_w.inverse(nw - sz - szh); if (y > 0) { int nn = id_w(x, y - 1) + sz + szh; if (chmin(dist[nn], dist[nw] + 1)) q.push(nn); } if (y < w - 1) { int nn = id_w(x, y + 1) + sz + szh; if (chmin(dist[nn], dist[nw] + 1)) q.push(nn); } { int nn = ind(x, y, 1); if (chmin(dist[nn], dist[nw] + 1)) q.push(nn); } { int nn = ind(x + 1, y, 1); if (chmin(dist[nn], dist[nw] + 1)) q.push(nn); } } } rep(f, 0, 2) chmin(ans, dist[ind(h - 1, w - 1, f)]); cout << ans << '\n'; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout << fixed << setprecision(15); int t = 1; // cin >> t; while (t--) solve(); }