#include using namespace std; //高速化 struct ponjuice{ponjuice(){cin.tie(0);ios::sync_with_stdio(0);cout<using vc = vector; templateusing vvc = vc>; templateusing vvvc = vvc>; using vi = vc; using vvi = vvc; using vvvi = vvvc; using vl = vc; using vvl = vvc; using vvvl = vvvc; using pi = pair; using pl = pair; using ull = unsigned ll; templateusing priq = priority_queue; templateusing priqg = priority_queue, greater>; // for文 #define overload4(a, b, c, d, e, ...) e #define rep1(n) for(ll i = 0; i < n; i++) #define rep2(i, n) for(ll i = 0; i < n; i++) #define rep3(i, a, b) for(ll i = a; i < b; i++) #define rep4(i, a, b, step) for(ll i = a; i < b; i+= step) #define rep(...) overload4(__VA_ARGS__, rep4, rep3, rep2, rep1)(__VA_ARGS__) #define per1(n) for(ll i = n-1; i >= 0; i--) #define per2(i, n) for(ll i = n-1; i >= 0; i--) #define per3(i, a, b) for(ll i = b-1; i >= a; i--) #define per4(i, a, b, step) for(ll i = b-1; i >= a; i-= step) #define per(...) overload4(__VA_ARGS__, per4, per3, per2, per1)(__VA_ARGS__) //関数 #define all(x) (x).begin(), (x).end() #define rall(x) (x).rbegin(), (x).rend() #define si(x) (ll)(x).size() templateinline bool chmax(S& a, T b){return a < b && ( a = b , true);} templateinline bool chmin(S& a, T b){return a > b && ( a = b , true);} inline void yes(){cout << "Yes\n";} inline void no(){cout << "No\n";} inline void yesno(bool y = true){if(y)yes();else no();} //定数 constexpr ll mod = 998244353; constexpr ll minf=-(1<<29); constexpr ll inf=(1<<29); constexpr ll MINF=-(1LL<<60); constexpr ll INF=(1LL<<60); const int dx[4] ={-1, 0, 1, 0}; const int dy[4] ={ 0, 1, 0,-1}; const int dx8[8] ={-1,-1,-1, 0, 1, 1, 1, 0}; const int dy8[8] ={-1, 0, 1, 1, 1, 0,-1,-1}; void solve(); int main() { int t = 1; // cin >>t; while(t--)solve(); } /* せっかくなので、PPC は全てコメント書きます S から G までは H+W手で確実に行ける(超能力を2回使用することで) 超能力を使用しない場合の計算は楽でBFSでもすればいい 問題は超能力を一度だけ使用するケースで、これで下か右への移動のみでGに行ける場合はH+W-1になる これの計算は縦向きに超能力を使うか、どうかでそれぞれ累積和的なので行けるはず */ bool check(const vector& s) { // 横に切ってあげる また、超能力を使ったかどうかも持ってあげる // 0 が到達不可能 // 1 が能力を使った場合にのみ到達可能 // 2 が能力なしで到達可能 int h = s.size(), w = s[0].size(); vector> dist(h, vector(w, 0)); dist[0][0] = 2; rep(i,0,h) { bool can = false; rep(j,0,w) { if(i != 0) { chmax(dist[i][j], dist[i-1][j]); if(dist[i-1][j] == 2) can = true; } if(j != 0) { chmax(dist[i][j], dist[i][j-1]); } if(can) chmax(dist[i][j], 1); } } return dist[h-1][w-1]; } void solve(){ int h,w; cin >> h >> w; vector s(h); rep(i,0,h) cin >> s[i]; // bfsでの最短手 vector> dist(h,vector(w, h+w)); dist[0][0] = 0; queue> q; q.push({0, 0}); while(q.size()) { auto[x,y] = q.front(); q.pop(); rep(dir, 0, 4) { int nx = x + dx[dir], ny = y + dy[dir]; if(nx < 0 || nx >= h || ny < 0 || ny >= w) continue; if(s[nx][ny] == '#') continue; if(chmin(dist[nx][ny], dist[x][y]+1)) { q.push({nx, ny}); } } } ll ans = dist[h-1][w-1]; vector ss(w, string(h,'?')); rep(i,0,h) rep(j,0,w) ss[j][i] = s[i][j]; if(check(s)) chmin(ans, h+w-1); if(check(ss)) chmin(ans, h+w-1); cout << ans << endl; }