Problem:
Problem D: Blaster
Problem
なんと、あなたは洞窟の中に閉じ込められてしまいました！
壁が崩れたりでもしたのでしょうか、1つしかない出口にたどり着くまでには沢山の岩が邪魔をしています。
しかしなんと、あなたのすぐ隣に爆弾の自動販売機があることに気がつきました。
さらに、洞窟にはいくつかの「ブラスター」も落ちているようです。
この2つの道具を活用すれば、出口まで脱出できそうです。
アイテムの説明
洞窟内で使用できるアイテムとして、「爆弾」「ブラスター」の2種類があります。
爆弾は、使用することで1マス分の岩を破壊できるアイテムです。
ブラスターは、使用することで自身の正面一直線にある岩を全て破壊することのできるアイテムです。
対象となる岩を破壊すると、岩は砕け散り「床」となります。
爆弾、ブラスターは使い切りで、各アイテムごとに使用できる回数はそれぞれ1回のみです。
また、ブラスターを使用することで、他のブラスターを破壊することはありません。
洞窟のフィールド
偶然手持ちにあったドローンを飛ばして、洞窟の様子を知ることが出来ました。
洞窟のフィールドが与えられます。
フィールドは以下のようなアスキーアートで与えらます。
_###
##B#
B##_
フィールドは、上下に $H$ マス、左右に $W$ マスの幅を持つ $H \times W$ のマスからなる長方形です。
$i$ 行 $j$ 列目のマスを $(i,j)$ と表します。
各マスには、床、壁、ブラスターのいずれかがあります。
ブラスターのマスには、床の上にちょうど1つのブラスターが落ちていることを示します。
なお、フィールドの外側は爆弾やブラスターでも破壊できない壁で囲まれています。
フィールドの外側に出ることは出来ません。
脱出までの行動
あなたは、以下の行動を任意の回数取ることが出来ます。
隣接するマスの、任意の床へ進む。
隣接するマスにある任意のブラスターを取得する。取得後、ブラスターを取得したマスは床となる。
隣接するマスにある岩を、爆弾を1つ消費して破壊する。
現在のマスから、上下左右好きな方向を向いて、所持しているブラスターを1つ使用する。
ここで、マス $(i,j)$ と $(k,l)$ が隣接するとは、 $|i-k|+|j-l|=1$ であることをいいます。
ブラスターは十分に軽いため、行動中いくつでも取得することが出来ます。
但し、アイテムの説明に記載してあるとおり、取得した個数分の回数しかブラスターを使用することは出来ないので、注意してください。
最初、マス $(1,1)$ にいます。
脱出とは、マス $(H,W)$ に到達することを言います。
ミッション
あなたは、爆弾の自動販売機から大量の爆弾を買えば問題なく脱出できることに気づきました。
幸い、爆弾の自動販売機には $10^{100}$ 個の在庫があり脱出するには十分そうです。
しかし、爆弾は非常に高価であるためあまり沢山買いたくありません。
手に入れた洞窟の様子から、脱出するには最小でいくつの爆弾を買う必要があるか、知りたくなりました。
Input
入力は以下の形式で与えられる。
$H$ $W$
$c_{1,1}$$\cdots$$c_{1,W}$
$\vdots$
$c_{H,1}$$\cdots$$c_{H,W}$
1行目に $H,W$ が空白区切りに与えられます。
2行目から、続く $H$ 行にフィールドの情報がアスキーアートで与えられます。
フィールドの情報は、それぞれの文字ごとに以下の意味を持ちます。
$c_{i,j}$ が '#' のとき、 $(i,j)$ に岩があることを示す。
$c_{i,j}$ が '_' のとき、 $(i,j)$ に床があることを示す。
$c_{i,j}$ が 'B' のとき、 $(i,j)$ にブラスターがちょうど1つあることを示す。
Constraints
入力は以下の条件を満たす。
$2 \leq H,W \leq 1000 $
$H,W$ は整数である
$c_{1,1},c_{H,W}$ は、必ず'_'である。
Output
1行に脱出に必要な爆弾の数を出力せよ。
Sample Input 1
8 5
_###_
_#_B#
_####
____#
###_#
#####
###_#
####_
Sample Output 1
1
この場合の脱出方法は、
マス $(3,4)$ にある岩を爆弾で破壊する
マス $(2,4)$ にあるブラスターを取得する
マス $(2,4)$ で下方向にブラスターを使用する
脱出！
このように、爆弾 $1$ つで脱出することが出来ます。
なお、ブラスターを使用した直後のフィールドは、以下のようになっています。
_###_
_#__#
_##_#
____#
###_#
###_#
###_#
###__
Sample Input 2
5 5
_____
_____
_____
_____
_____
Sample Output 2
0
邪魔する岩もブラスターもありません。目の錯覚だったのでしょうか。
爆弾を一つも買うことなく、脱出できる場合もあります。
Sample Input 3
4 5
_####
##B##
_####
_###_
Sample Output 3
2
マス $(2,1),(2,2)$ にある岩を破壊すれば、爆弾 $2$ つだけで脱出可能です。
Sample Input 4
4 5
_#B##
#####
##B##
####_
Sample Output 4
1

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}

struct FastIO{
  FastIO(){
    cin.tie(0);
    ios::sync_with_stdio(0);
  }
}fastio_beet;

using P = pair<int, int>;
vector< vector<int> > bfs(vector<string> &s,vector<P> &vp,char wall,int dir){
  int h=s.size(),w=s.front().size();
  vector< vector<int> > dp(h,vector<int>(w,-1));
  deque<P> q;

  for(int i=0;i<(int)vp.size();i++){
    int sy=vp[i].first,sx=vp[i].second;
    dp[sy][sx]=0;
    q.emplace_back(sy,sx);
  }

  int dy[]={1,-1,0,0,1,1,-1,-1};
  int dx[]={0,0,1,-1,1,-1,1,-1};
  auto in=[&](int y,int x){return 0<=y&&y<h&&0<=x&&x<w;};

  while(!q.empty()){
    int y,x;
    tie(y,x)=q.front();q.pop_front();
    for(int k=0;k<dir;k++){
      int ny=y+dy[k],nx=x+dx[k];
      if(!in(ny,nx)) continue;
      int nd=dp[y][x]+(s[ny][nx]==wall);
      if(~dp[ny][nx]&&dp[ny][nx]<=nd) continue;
      dp[ny][nx]=nd;
      if(s[ny][nx]=='#'){
        q.emplace_back(ny,nx);
      }else{
        q.emplace_front(ny,nx);
      }
    }
  }
  return dp;
}

vector< vector<int> > bfs(vector<string> &s,int sy,int sx,char wall,int dir){
  vector<P> vp;
  vp.emplace_back(sy,sx);
  return bfs(s,vp,wall,dir);
}


//INSERT ABOVE HERE

signed main(){
  int h,w;
  cin>>h>>w;
  vector<string> st(h);
  for(int i=0;i<h;i++) cin>>st[i];

  auto d1=bfs(st,0,0,'#',4);
  int ans=d1[h-1][w-1];

  // find B2
  vector< vector<int> > ex(h,vector<int>(w));
  {
    int flg=0;
    for(int i=0;i<h;i++){
      for(int j=0;j<w;j++) if(st[i][j]=='B') ex[i][j]|=flg;
      for(int j=0;j<w;j++) if(st[i][j]=='B') flg=1;
    }
  }
  {
    int flg=0;
    for(int j=0;j<w;j++){
      for(int i=0;i<h;i++) if(st[i][j]=='B') ex[i][j]|=flg;
      for(int i=0;i<h;i++) if(st[i][j]=='B') flg=1;
    }
  }

  // use B2
  for(int i=0;i<h;i++)
    for(int j=0;j<w;j++)
      if(ex[i][j]) chmin(ans,d1[i][j]);

  // find B1
  int by=-1,bx=-1;
  for(int i=0;i<h;i++)
    for(int j=0;j<w;j++)
      if(st[i][j]=='B'&&!ex[i][j]) by=i,bx=j;

  if(~by){
    // dist from B1
    auto d2=bfs(st,by,bx,'#',4);

    // dist to (i, j) with B1
    vector< vector<int> > d3(h,vector<int>(w));
    for(int i=0;i<h;i++)
      for(int j=0;j<w;j++)
        d3[i][j]=d1[i][j]+d2[i][j]-(st[i][j]=='#');

    vector< queue<P> > qs((h+w)*2);
    for(int i=0;i<h;i++)
      for(int j=0;j<w;j++)
        qs[d3[i][j]].emplace(i,j);

    int dy[]={1,-1,0,0,1,1,-1,-1};
    int dx[]={0,0,1,-1,1,-1,1,-1};
    auto in=[&](int y,int x){return 0<=y&&y<h&&0<=x&&x<w;};
    for(int d=0;d+1<(int)qs.size();d++){
      while(!qs[d].empty()){
        int y,x;
        tie(y,x)=qs[d].front();qs[d].pop();
        if(d3[y][x]!=d) continue;
        for(int k=0;k<4;k++){
          int ny=y+dy[k],nx=x+dx[k];
          if(!in(ny,nx)) continue;
          int nd=d3[y][x]+(st[ny][nx]=='#');
          if(d3[ny][nx]<=nd) continue;
          d3[ny][nx]=nd;
          qs[nd].emplace(ny,nx);
        }
      }
    }

    // dist from B2 and goal
    vector<P> vp;
    for(int i=0;i<h;i++)
      for(int j=0;j<w;j++)
        if(ex[i][j]) vp.emplace_back(i,j);
    vp.emplace_back(h-1,w-1);
    auto d4=bfs(st,vp,'#',4);

    // use B1
    vector< vector<int> > d5(d3),d6(d3);
    for(int i=0;i<h;i++){
      for(int j=0;j<w;j++){
        if(i) chmin(d5[i][j],d5[i-1][j]);
        if(j) chmin(d6[i][j],d6[i][j-1]);
      }
    }

    // take B2 and use
    for(int i=0;i<h;i++)
      for(int j=0;j<w;j++)
        chmin(ans,(d4[i][j]-(st[i][j]=='#'))+min(d5[i][j],d6[i][j]));
  }

  cout<<ans<<endl;
  return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 37468
final_rank: 1

code_snippet: #include <bits/stdc++.h>
#define GET_MACRO(_1,_2,_3,_4,_5,_6,_7,_8,NAME,...) NAME
#define pr(...) cerr<< GET_MACRO(__VA_ARGS__,pr8,pr7,pr6,pr5,pr4,pr3,pr2,pr1)(__VA_ARGS__) <<endl
#define pr1(a) (#a)<<"="<<(a)<<" "
#define pr2(a,b) pr1(a)<<pr1(b)
#define pr3(a,b,c) pr1(a)<<pr2(b,c)
#define pr4(a,b,c,d) pr1(a)<<pr3(b,c,d)
#define pr5(a,b,c,d,e) pr1(a)<<pr4(b,c,d,e)
#define pr6(a,b,c,d,e,f) pr1(a)<<pr5(b,c,d,e,f)
#define pr7(a,b,c,d,e,f,g) pr1(a)<<pr6(b,c,d,e,f,g)
#define pr8(a,b,c,d,e,f,g,h) pr1(a)<<pr7(b,c,d,e,f,g,h)
#define prArr(a) {cerr<<(#a)<<"={";int i=0;for(auto t:(a))cerr<<(i++?", ":"")<<t;cerr<<"}"<<endl;}
using namespace std;
using Int = long long;
using _int = int;
using ll = long long;
using Double = long double;
const Int INF = (1LL<<60)+1e9; // ~ 1.15 * 1e18
const Int mod = (1e9)+7;
const Double EPS = 1e-8;
const Double PI = 6.0 * asin((Double)0.5);
using P = pair<Int,Int>;
template<class T> T Max(T &a,T b){return a=max(a,b);}
template<class T> T Min(T &a,T b){return a=min(a,b);}
template<class T1, class T2> ostream& operator<<(ostream& o,pair<T1,T2> p){return o<<"("<<p.first<<","<<p.second<<")";}
template<class T1, class T2, class T3> ostream& operator<<(ostream& o,tuple<T1,T2,T3> t){
  return o<<"("<<get<0>(t)<<","<<get<1>(t)<<","<<get<2>(t)<<")";}
template<class T1, class T2> istream& operator>>(istream& i,pair<T1,T2> &p){return i>>p.first>>p.second;}
template<class T> ostream& operator<<(ostream& o,vector<T> a){Int i=0;for(T t:a)o<<(i++?" ":"")<<t;return o;}
template<class T> istream& operator>>(istream& i,vector<T> &a){for(T &t:a)i>>t;return i;}
//INSERT ABOVE HERE

const Int dx[] = {0, 1, 0, -1};
const Int dy[] = {-1, 0, 1, 0};

vector<vector<Int> > bfs(Int h, Int w, vector<P> start, vector<string> mp){
  using T = tuple<Int,Int>;
  vector<vector<Int> > D(h, vector<Int> (w, INF));
  deque<T> Q;
  for(auto p:start){
    Int sy, sx; tie(sy, sx) = p;
    Q.emplace_back(sy, sx);
    D[sy][sx] = 0;
  }
  while(!Q.empty()){
    Int y, x;
    tie(y, x) = Q.front(); Q.pop_front();
    Int cost = D[y][x];

    for(Int i=0;i<4;i++){
      Int ny = y + dy[i];
      Int nx = x + dx[i];
      if(ny < 0 || ny >= h || nx < 0 || nx >= w) continue;
      Int ncost = cost + (mp[ny][nx] == '#');
      if(D[ny][nx] <= ncost) continue;
      D[ny][nx] = ncost;
      if(cost == ncost) Q.emplace_front(ny, nx);
      else Q.emplace_back(ny, nx);
    }
  }
  return D;
}

vector<vector<Int> > dijkstra(Int h, Int w, vector<string> mp, vector<vector<Int> > D){
  using T = tuple<Int,Int, Int>;
  priority_queue<T, vector<T>, greater<T> > Q;
  for(Int i=0;i<h;i++)
    for(Int j=0;j<w;j++){
      Int sy, sx; tie(sy, sx) = P(i, j);
      Q.emplace(D[sy][sx], sy, sx);
    }

  vector<vector<Int> > visited(h, vector<Int>(w));

  while(!Q.empty()){
    Int cost, y, x;
    tie(cost, y, x) = Q.top(); Q.pop();

    if(visited[y][x]) continue;

    for(Int i=0;i<4;i++){
      Int ny = y + dy[i];
      Int nx = x + dx[i];
      if(ny < 0 || ny >= h || nx < 0 || nx >= w) continue;
      Int ncost = cost + (mp[ny][nx] == '#');
      if(D[ny][nx] <= ncost) continue;
      D[ny][nx] = ncost;
      Q.emplace(ncost, ny, nx);
    }
  }
  return D;
}

//Blasterを0個使う
Int solve0(Int h, Int w, vector<string> mp){
  vector<P> start = {P(0, 0)};
  return bfs(h, w, start, mp)[h-1][w-1];
}


//Blasterを2個使うB2を取ってからB1をとる
Int solve2_1(Int h, Int w, vector<string> mp){
  P B1 = P(-1, -1);
  for(Int i=0;i<h;i++)
    for(Int j=0;j<w;j++){
      if(mp[i][j] != 'B') continue;
      if(B1 == P(-1, -1) || B1.first + B1.second >= i + j) B1 = P(i, j);
    }

  if(B1 == P(-1, -1)) return INF;
  mp[B1.first][B1.second] = '_';
  auto SD = bfs(h, w, {P(0, 0)}, mp);
  Int res = INF;
  for(Int i=0;i<h;i++)
    for(Int j=0;j<w;j++)
      if(mp[i][j] == 'B') Min(res, SD[i][j]);
  return res;
}

//Blasterを2個使うB1を取ってからB2をとる
Int solve2_2(Int h, Int w, vector<string> mp){
  P B1 = P(-1, -1);
  for(Int i=0;i<h;i++)
    for(Int j=0;j<w;j++){
      if(mp[i][j] != 'B') continue;
      if(B1 == P(-1, -1) || B1.first + B1.second >= i + j) B1 = P(i, j);
    }
  if(B1 == P(-1, -1)) return INF;
  mp[B1.first][B1.second] = '_';
  mp[h-1][w-1] = 'B'; //Blasterを1個しか使わないケース用にゴールをBlasterにしておく

  vector<vector<Int> > minH, minW, minHW;
  {
    vector<P> start;
    for(Int i=0;i<h;i++)
      for(Int j=0;j<w;j++)
        if(mp[i][j] == 'B') start.emplace_back(i, j);

    minH = minW =  bfs(h, w, start, mp);

    for(int i=0;i<h;i++)
      for(int j=0;j<w;j++)
        if(mp[i][j] == '#'){
          minH[i][j] = max(0LL, minH[i][j]-1);
          minW[i][j] = max(0LL, minW[i][j]-1);
        }

    for(Int i=0;i<h;i++)
      for(Int j=w-2;j>=0;j--) Min(minW[i][j], minW[i][j+1]);

    for(Int j=0;j<w;j++)
      for(Int i=h-2;i>=0;i--) Min(minH[i][j], minH[i+1][j]);

    minHW = vector<vector<Int> >(h, vector<Int>(w));
    for(int i=0;i<h;i++)
      for(int j=0;j<w;j++) minHW[i][j] = min(minH[i][j], minW[i][j]) + (mp[i][j] == '#');
  }

  auto SD = bfs(h, w, {P(0, 0)}, mp);
  auto B1D = bfs(h, w, {B1}, mp);
  auto HWD = dijkstra(h, w, mp, minHW);

  Int res = INF;
  for(Int i=0;i<h;i++)
    for(Int j=0;j<w;j++){
      Int a = SD[i][j];
      Int b = B1D[i][j];
      Int c = HWD[i][j];
      Int cost = a + b + c - (mp[i][j] == '#') * 2;
      Min(res, cost);
    }
  return res;
}

signed main(){
  srand((unsigned)time(NULL));
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  Int h, w;
  cin>>h>>w;
  vector<string> mp(h);
  cin>>mp;
  Int a = solve0(h, w, mp);
  Int b = solve2_1(h, w, mp);
  Int c = solve2_2(h, w, mp);
  Int ans = min({a, b, c});
  cout<<ans<<endl;
  return 0;
}
accuracy: 1
time_ms: 530
memory_kb: 109868
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;

const int INF = 1e9;
const int dx[4] = {0, 1, 0, -1}, dy[4] = {-1, 0, 1, 0};

int H, W;
vector<string> grid;

struct State {
  int x, y, cost, b;
  State(int x, int y, int cost, int b): x(x), y(y), cost(cost), b(b) {}
  bool operator<(const State &e) const {
    return cost < e.cost;
  };

  bool operator>(const State &e) const {
    return cost > e.cost;
  };
};

int calc0() {
  bool used[H][W];
  fill_n(*used, H*W, false);
  deque<State> Q;  
  Q.push_front(State(0, 0, 0, 0));
  while ( !Q.empty()) {
    State s = Q.front(); Q.pop_front();    
    int x = s.x, y = s.y, cost = s.cost, b = s.b;      

    if ( x == W-1 && y == H-1 ) return cost;      
      
    if ( used[y][x] ) continue;
    used[y][x] = true;
      
    for ( int i = 0; i < 4; i++ ) {
      int nx = x+dx[i], ny = y+dy[i];
      if ( nx < 0 || nx >= W || ny < 0 || ny >= H ) continue;      
      if ( grid[ny][nx] == '#' ) {
	Q.push_back(State(nx, ny, cost+1, b));	
      } else {
	Q.push_front(State(nx, ny, cost, b));	
      }
    }
  }

  return INF;
}

int calc1() {
  int dist[H][W];
  {        
    fill_n(*dist, H*W, INF);    
    deque<State> Q;  
    for ( int i = 0; i < H; i++ ) {
      for ( int j = 0; j < W; j++ ) {
	if ( grid[i][j] == 'B' ) Q.push_front(State(j, i, 0, 0));
      }
    }
    while ( !Q.empty()) {
      State s = Q.front(); Q.pop_front();    
      int x = s.x, y = s.y, cost = s.cost, b = s.b;    
      
      if ( dist[y][x] != INF ) continue;
      dist[y][x] = cost;
      
      for ( int i = 0; i < 4; i++ ) {
	int nx = x+dx[i], ny = y+dy[i];
	if ( nx < 0 || nx >= W || ny < 0 || ny >= H ) continue;      
	if ( grid[y][x] == '#' ) {
	  Q.push_back(State(nx, ny, cost+1, b));	
	} else {
	  Q.push_front(State(nx, ny, cost, b));	
	}
      }
    }  
  }
  // cout << dist[0][0] << endl;
  vector<int> distR(H, INF), distC(W, INF);
  {
    bool used[H][W][2];
    fill_n(**used, H*W*2, false);
    priority_queue<State, vector<State>, greater<State> > Q;  
    Q.push(State(0, 0, 0, 0));
    while ( !Q.empty()) {
      State s = Q.top(); Q.pop();    
      int x = s.x, y = s.y, cost = s.cost, b = s.b;
      
      if ( b ) {
	distR[y] = min(distR[y], cost);
	distC[x] = min(distC[x], cost);
      }
      else {
	distR[y] = min(distR[y], cost+dist[y][x]);	
	distC[x] = min(distC[x], cost+dist[y][x]);
      } 
      
      if ( used[y][x][b] ) continue;
      used[y][x][b] = true;

      Q.push(State(x, y, cost+dist[y][x], 1));      
      
      for ( int i = 0; i < 4; i++ ) {
	int nx = x+dx[i], ny = y+dy[i];
	if ( nx < 0 || nx >= W || ny < 0 || ny >= H ) continue;      
	if ( grid[ny][nx] == '#' ) {
	  Q.push(State(nx, ny, cost+1, b));	
	} else {
	  int nb = b;
	  if ( grid[ny][nx] == 'B' ) nb = 1;
	  Q.push(State(nx, ny, cost, nb));	
	}
      }
    }
  }

  int ans = INF;  
  bool used[H][W];
  fill_n(*used, H*W, false);
  deque<State> Q;  
  Q.push_front(State(W-1, H-1, 0, 0));  
  while ( !Q.empty()) {
    State s = Q.front(); Q.pop_front();    
    int x = s.x, y = s.y, cost = s.cost, b = s.b;      
    
    ans = min(ans, min(cost+distR[y], cost+distC[x]));   
      
    if ( used[y][x] ) continue;
    used[y][x] = true;
      
    for ( int i = 0; i < 4; i++ ) {
      int nx = x+dx[i], ny = y+dy[i];
      if ( nx < 0 || nx >= W || ny < 0 || ny >= H ) continue;      
      if ( grid[y][x] == '#' ) {
	Q.push_back(State(nx, ny, cost+1, b));	
      } else {
	Q.push_front(State(nx, ny, cost, b));	
      }
    }
  }

  return ans;  
}

int calc2() {
  int ans = INF;
  using P = pair<int, int>;  
  P dist[H][W];
  {        
    fill_n(*dist, H*W, P(INF, INF));    
    deque<State> Q;  
    for ( int i = 0; i < H; i++ ) {
      for ( int j = 0; j < W; j++ ) {
	if ( grid[i][j] == 'B' ) Q.push_front(State(j, i, 0, i*W+j));
      }
    }
    while ( !Q.empty()) {
      State s = Q.front(); Q.pop_front();    
      int x = s.x, y = s.y, cost = s.cost, b = s.b;    
      
      if ( dist[y][x].first != INF ) continue;
      dist[y][x] = P(cost, b);      
      
      for ( int i = 0; i < 4; i++ ) {
	int nx = x+dx[i], ny = y+dy[i];
	if ( nx < 0 || nx >= W || ny < 0 || ny >= H ) continue;      
	if ( grid[y][x] == '#' ) {
	  if ( dist[ny][nx].first == INF ) Q.push_back(State(nx, ny, cost+1, b));	
	} else {
	  if ( dist[ny][nx].first == INF ) Q.push_front(State(nx, ny, cost, b));	
	}
      }
    }  
  }

  vector<vector<State> > distR(H), distC(W);  
  {
    bool used[H][W][2];
    fill_n(**used, H*W*2, false);
    priority_queue<State, vector<State>, greater<State> > Q;  
    Q.push(State(0, 0, 0, 0));
    while ( !Q.empty()) {
      State s = Q.top(); Q.pop();    
      int x = s.x, y = s.y, cost = s.cost, b = s.b;      
      if ( used[y][x][(bool)b] ) continue;
      used[y][x][(bool)b] = true;      
      
      if ( b > 0 ) {
	if ( distR[y].size() < 2 ) {
	  if ( distR[y].size() == 0 ) distR[y].push_back(s);
	  else if ( distR[y][0].b != b ) distR[y].push_back(s);
	}
	if ( distC[x].size() < 2 ) {
	  if ( distC[x].size() == 0 ) distC[x].push_back(s);
	  else if ( distC[x][0].b != b ) distC[x].push_back(s);
	}
      }      
      /* if ( b == 2 ) {
	ans = min(ans, cost);	
	} */      

      if ( dist[y][x].first != INF ) {
	if ( !used[y][x][(bool)dist[y][x].second] )
	  Q.push(State(x, y, cost+dist[y][x].first, dist[y][x].second));
      }
      
      for ( int i = 0; i < 4; i++ ) {
	int nx = x+dx[i], ny = y+dy[i];
	if ( b == ny*W+nx ) continue;	
	if ( nx < 0 || nx >= W || ny < 0 || ny >= H ) continue;      
	if ( grid[ny][nx] == '#' ) {
	  if ( !used[ny][nx][(bool)b] ) Q.push(State(nx, ny, cost+1, b));	
	} else {
	  int nb = b;
	  if ( grid[ny][nx] == 'B' ) nb = ny*W+nx;
	  if ( !used[ny][nx][(bool)nb] ) Q.push(State(nx, ny, cost, nb));	
	}
      }
    }
  }

  vector<vector<State> > distR2(H), distC2(W);
  {
    bool used[H][W];
    fill_n(*used, H*W, false);
    deque<State> Q;  
    for ( int i = 0; i < H; i++ ) {
      for ( int j = 0; j < W; j++ ) {
	if ( grid[i][j] == 'B' ) Q.push_front(State(j, i, 0, i*W+j));
      }
    }
    while ( !Q.empty()) {
      State s = Q.front(); Q.pop_front();    
      int x = s.x, y = s.y, cost = s.cost, b = s.b;
      
      if ( distR2[y].size() < 2 ) {
	if ( distR2[y].size() == 0 ) distR2[y].push_back(s);
	else if ( distR2[y][0].b != b ) distR2[y].push_back(s);
      }
      if ( distC2[x].size() < 2 ) {
	if ( distC2[x].size() == 0 ) distC2[x].push_back(s);
	else if ( distC2[x][0].b != b ) distC2[x].push_back(s);
      }
      
      if ( used[y][x] ) continue;
      used[y][x] = true;
      
      for ( int i = 0; i < 4; i++ ) {
	int nx = x+dx[i], ny = y+dy[i];
	if ( nx < 0 || nx >= W || ny < 0 || ny >= H ) continue;      
	if ( grid[y][x] == '#' ) {
	  Q.push_back(State(nx, ny, cost+1, b));	
	} else {
	  Q.push_front(State(nx, ny, cost, b));	
	}
      }
    }
  }
  
  for ( int i = 0; i < H; i++ ) {
    for ( State j : distR[i] ) {
      for ( State k : distR2[i] ) {
	if ( j.b == k.b ) continue;
	// if ( j.cost+k.cost == 5 ) cout << "R" << i <<  " " << j.b << ":" << j.cost << " " << k.b << ":" << k.cost << endl;	
	ans = min(ans, j.cost+k.cost);	
      }
    }
  }

  for ( int i = 0; i < W; i++ ) {
    for ( State j : distC[i] ) {
      for ( State k : distC2[i] ) {
	if ( j.b == k.b ) continue;
	// if ( j.cost+k.cost == 5 ) cout << "W" << i <<  " " << j.b << ":" << j.cost << " " << k.b << ":" << k.cost << endl;	
	ans = min(ans, j.cost+k.cost);	
      }
    }
  }

  return ans;  
}

signed main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  cin >> H >> W;

  grid = vector<string>(H);
  int cntB = 0;  
  for ( int i = 0; i < H; i++ ) {
    cin >> grid[i];
    for ( int j = 0; j < W; j++ ) cntB += (grid[i][j] == 'B');    
  }

  int ans = calc0();
  if ( cntB ) {
    grid[H-1][W-1] = 'B';    
    ans = min(ans, calc2());
  }
  // if ( cntB >= 2 ) ans = min(ans, calc2());

  cout << ans << endl;
  
  return 0;
}
accuracy: 1
time_ms: 800
memory_kb: 62844
final_rank: 5

code_snippet: //#define TUBUANN_DEBUG21
//#define TUBUANN_DEBUG22
//#define TUBUANN_DEBUG23
//#define TUBUANN_DEBUG24
//#define TUBUANN_DEBUG25
//#define TUBUANN_DEBUG26
//#define TUBUANN_DEBUG27
//#define TUBUANN_DEBUG28
//#define TUBUANN_DEBUG29
//#define TUBUANN_DEBUG30
//#define TUBUANN_DEBUG31
//#define TUBUANN_DEBUG32
#define TUBUANN_DEBUG33
//#define TUBUANN_DEBUG34
//#define TUBUANN_DEBUG35
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<ll,ll> pll;
typedef long double D;
typedef complex<D> P;
#define F first
#define S second
const ll E=1e18+7;
//const ll MOD=1000000007;
const ll MOD=998244353;

#define endl "\n"

  
template<typename T,typename U>istream & operator >> (istream &i,pair<T,U> &A){i>>A.F>>A.S; return i;}
template<typename T>istream & operator >> (istream &i,vector<T> &A){for(auto &I:A){i>>I;} return i;}
template<typename T,typename U>ostream & operator << (ostream &o,const pair<T,U> &A){o<<A.F<<" "<<A.S; return o;}
template<typename T>ostream & operator << (ostream &o,const vector<T> &A){ll i=A.size(); for(auto &I:A){o<<I<<(--i?" ":"");} return o;}
template<typename T>vector<T> & cset(vector<T> &A,T e=T()){for(auto &I:A){I=e;} return A;}

#ifdef TUBUANN_DEBUG21
const int MX=999;
#else
const int MX=1000;
#endif
int h,w;
vector<int> dx={1,0,-1,0};
vector<int> dy={0,1,0,-1};
vector<vector<int>> cost(MX,vector<int>(MX));
vector<vector<int>> s_to_v(MX,vector<int>(MX));
vector<vector<int>> b_to_v(MX,vector<int>(MX));
vector<string> mp(MX);

typedef pair<int,int> pt;

inline bool valid(const pt &p){return p.F>=0 && p.F<h && p.S>=0 && p.S<w;}

void bfs(vector<vector<int>> &m,int mx=4){
  deque<pt> Q;
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      if(m[i][j]==0){Q.push_back({i,j});}
    }
  }
  while(!Q.empty()){
    pt u=Q.front(); Q.pop_front();
    for(int i=0;i<mx;i++){
      pt v=u;
      v.F+=dx[i];
      v.S+=dy[i];
      if(valid(v) && m[v.F][v.S]>m[u.F][u.S]+cost[v.F][v.S]){
        m[v.F][v.S]=m[u.F][u.S]+cost[v.F][v.S];
        if(cost[v.F][v.S]==1){Q.push_back(v);}
        else{Q.push_front(v);}
      }
    }
  }
}

void dijk(vector<vector<int>> &m,int mx=4){
  deque<pt> Q;
  vector<pair<int,pt>> A(h*w);
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      A[i*w+j]={m[i][j],{i,j}};
    }
  }
  sort(A.begin(),A.end());
  for(int idx=0;idx<h*w;idx++){
    pt a=A[idx].S;
    int c= idx+1==h*w?MOD:A[idx+1].F;
    //if(m[a.F][a.S]!=A[idx].F){continue;}
    Q.push_front(a);
    while(!Q.empty() && m[Q[0].F][Q[0].S]<c){
      pt u=Q.front(); Q.pop_front();
      for(int i=0;i<mx;i++){
        pt v=u;
        v.F+=dx[i];
        v.S+=dy[i];
        if(valid(v) && m[v.F][v.S]>m[u.F][u.S]+cost[v.F][v.S]){
          m[v.F][v.S]=m[u.F][u.S]+cost[v.F][v.S];
          if(cost[v.F][v.S]==1){Q.push_back(v);}
          else{Q.push_front(v);}
        }
      }
    }
  }
}

void min2D(vector<vector<int>> &m){
  vector<int> dp(w,MOD);
  for(int i=0;i<h;i++){
    int r=MOD;
    for(int j=0;j<w;j++){
      r=min(r,m[i][j]);
      dp[j]=min(dp[j],m[i][j]);
      #ifdef TUBUANN_DEBUG22
      m[i][j]=min(m[i][j],r);
      #else
        #ifdef TUBUANN_DEBUG23
        m[i][j]=min(m[i][j],dp[j]);
        #else
        m[i][j]=min(r,dp[j]);
        #endif
      #endif
    }
  }
}

void set_val(vector<vector<int>> &m,int e=MOD){
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){m[i][j]=e;}
  }
}

void solve(){
  cin>>h>>w;
  set_val(cost,0);
  
  #ifdef TUBUANN_DEBUG24
  set_val(s_to_v,900);
  #else
  set_val(s_to_v);
  #endif
  
  #ifdef TUBUANN_DEBUG25
  set_val(b_to_v,900);
  #else
  set_val(b_to_v);
  #endif
  
  for(int i=0;i<h;i++){cin>>mp[i];}
  int mx=h,my=w;
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      if(mp[i][j]=='#'){cost[i][j]=1;}
      if(mp[i][j]=='B'){mx=min(mx,i); my=min(my,j);}
    }
  }
  s_to_v[0][0]=0;
  
  #ifdef TUBUANN_DEBUG26
  bfs(s_to_v,2);
  #else
  bfs(s_to_v);
  #endif

  #ifdef TUBUANN_DEBUG27
  int ans=MOD;
  if(mx==h){cout<<s_to_v[h-1][w-1]<<endl; return;}
  #else
  int ans=s_to_v[h-1][w-1];
  if(mx==h){cout<<ans<<endl; return;}
  #endif
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      #ifndef TUBUANN_DEBUG28
      if((i!=mx || j!=my) && mp[i][j]=='B'){ans=min(ans,s_to_v[i][j]);}
      #endif
    }
  }
  if(mp[mx][my]!='B'){cout<<ans<<endl; return;}
  b_to_v[mx][my]=0;
  
  #ifdef TUBUANN_DEBUG29
  bfs(b_to_v,2);
  #else
  bfs(b_to_v);
  #endif
  
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      int c=b_to_v[i][j];
      for(int k=0;k<4;k++){
        pt v={i+dx[k],j+dy[k]};
        #ifndef TUBUANN_DEBUG30
        if(valid(v)){c=min(c,b_to_v[v.F][v.S]);}
        #endif
      }
      s_to_v[i][j]+=c;
    }
  }
  
  #ifdef TUBUANN_DEBUG31
  dijk(s_to_v,2);
  #else
  dijk(s_to_v);
  #endif

  #ifndef TUBUANN_DEBUG32
  min2D(s_to_v);
  #endif

  #ifdef TUBUANN_DEBUG33
  dijk(s_to_v,2);
  #else
  dijk(s_to_v);
  #endif

  #ifndef TUBUANN_DEBUG34
  ans=min(ans,s_to_v[h-1][w-1]);
  #endif
  
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      #ifndef TUBUANN_DEBUG35
      if((i!=mx || j!=my) && mp[i][j]=='B'){ans=min(ans,s_to_v[i][j]);}
      #endif
    }
  }
  cout<<ans<<endl;
}

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  solve();
  
  return 0;
}
accuracy: 0.5132743362831859
time_ms: 250
memory_kb: 35988
final_rank: 12

code_snippet: //#define TUBUANN_DEBUG21
//#define TUBUANN_DEBUG22
//#define TUBUANN_DEBUG23
//#define TUBUANN_DEBUG24
//#define TUBUANN_DEBUG25
//#define TUBUANN_DEBUG26
//#define TUBUANN_DEBUG27
//#define TUBUANN_DEBUG28
//#define TUBUANN_DEBUG29
//#define TUBUANN_DEBUG30
#define TUBUANN_DEBUG31
//#define TUBUANN_DEBUG32
//#define TUBUANN_DEBUG33
//#define TUBUANN_DEBUG34
//#define TUBUANN_DEBUG35
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<ll,ll> pll;
typedef long double D;
typedef complex<D> P;
#define F first
#define S second
const ll E=1e18+7;
//const ll MOD=1000000007;
const ll MOD=998244353;

#define endl "\n"

  
template<typename T,typename U>istream & operator >> (istream &i,pair<T,U> &A){i>>A.F>>A.S; return i;}
template<typename T>istream & operator >> (istream &i,vector<T> &A){for(auto &I:A){i>>I;} return i;}
template<typename T,typename U>ostream & operator << (ostream &o,const pair<T,U> &A){o<<A.F<<" "<<A.S; return o;}
template<typename T>ostream & operator << (ostream &o,const vector<T> &A){ll i=A.size(); for(auto &I:A){o<<I<<(--i?" ":"");} return o;}
template<typename T>vector<T> & cset(vector<T> &A,T e=T()){for(auto &I:A){I=e;} return A;}

#ifdef TUBUANN_DEBUG21
const int MX=999;
#else
const int MX=1000;
#endif
int h,w;
vector<int> dx={1,0,-1,0};
vector<int> dy={0,1,0,-1};
vector<vector<int>> cost(MX,vector<int>(MX));
vector<vector<int>> s_to_v(MX,vector<int>(MX));
vector<vector<int>> b_to_v(MX,vector<int>(MX));
vector<string> mp(MX);

typedef pair<int,int> pt;

inline bool valid(const pt &p){return p.F>=0 && p.F<h && p.S>=0 && p.S<w;}

void bfs(vector<vector<int>> &m,int mx=4){
  deque<pt> Q;
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      if(m[i][j]==0){Q.push_back({i,j});}
    }
  }
  while(!Q.empty()){
    pt u=Q.front(); Q.pop_front();
    for(int i=0;i<mx;i++){
      pt v=u;
      v.F+=dx[i];
      v.S+=dy[i];
      if(valid(v) && m[v.F][v.S]>m[u.F][u.S]+cost[v.F][v.S]){
        m[v.F][v.S]=m[u.F][u.S]+cost[v.F][v.S];
        if(cost[v.F][v.S]==1){Q.push_back(v);}
        else{Q.push_front(v);}
      }
    }
  }
}

void dijk(vector<vector<int>> &m,int mx=4){
  deque<pt> Q;
  vector<pair<int,pt>> A(h*w);
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      A[i*w+j]={m[i][j],{i,j}};
    }
  }
  sort(A.begin(),A.end());
  for(int idx=0;idx<h*w;idx++){
    pt a=A[idx].S;
    int c= idx+1==h*w?MOD:A[idx+1].F;
    //if(m[a.F][a.S]!=A[idx].F){continue;}
    Q.push_front(a);
    while(!Q.empty() && m[Q[0].F][Q[0].S]<c){
      pt u=Q.front(); Q.pop_front();
      for(int i=0;i<mx;i++){
        pt v=u;
        v.F+=dx[i];
        v.S+=dy[i];
        if(valid(v) && m[v.F][v.S]>m[u.F][u.S]+cost[v.F][v.S]){
          m[v.F][v.S]=m[u.F][u.S]+cost[v.F][v.S];
          if(cost[v.F][v.S]==1){Q.push_back(v);}
          else{Q.push_front(v);}
        }
      }
    }
  }
}

void min2D(vector<vector<int>> &m){
  vector<int> dp(w,MOD);
  for(int i=0;i<h;i++){
    int r=MOD;
    for(int j=0;j<w;j++){
      r=min(r,m[i][j]);
      dp[j]=min(dp[j],m[i][j]);
      #ifdef TUBUANN_DEBUG22
      m[i][j]=min(m[i][j],r);
      #else
        #ifdef TUBUANN_DEBUG23
        m[i][j]=min(m[i][j],dp[j]);
        #else
        m[i][j]=min(r,dp[j]);
        #endif
      #endif
    }
  }
}

void set_val(vector<vector<int>> &m,int e=MOD){
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){m[i][j]=e;}
  }
}

void solve(){
  cin>>h>>w;
  set_val(cost,0);
  
  #ifdef TUBUANN_DEBUG24
  set_val(s_to_v,900);
  #else
  set_val(s_to_v);
  #endif
  
  #ifdef TUBUANN_DEBUG25
  set_val(b_to_v,900);
  #else
  set_val(b_to_v);
  #endif
  
  for(int i=0;i<h;i++){cin>>mp[i];}
  int mx=h,my=w;
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      if(mp[i][j]=='#'){cost[i][j]=1;}
      if(mp[i][j]=='B'){mx=min(mx,i); my=min(my,j);}
    }
  }
  s_to_v[0][0]=0;
  
  #ifdef TUBUANN_DEBUG26
  bfs(s_to_v,2);
  #else
  bfs(s_to_v);
  #endif

  #ifdef TUBUANN_DEBUG27
  int ans=MOD;
  if(mx==h){cout<<s_to_v[h-1][w-1]<<endl; return;}
  #else
  int ans=s_to_v[h-1][w-1];
  if(mx==h){cout<<ans<<endl; return;}
  #endif
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      #ifndef TUBUANN_DEBUG28
      if((i!=mx || j!=my) && mp[i][j]=='B'){ans=min(ans,s_to_v[i][j]);}
      #endif
    }
  }
  if(mp[mx][my]!='B'){cout<<ans<<endl; return;}
  b_to_v[mx][my]=0;
  
  #ifdef TUBUANN_DEBUG29
  bfs(b_to_v,2);
  #else
  bfs(b_to_v);
  #endif
  
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      int c=b_to_v[i][j];
      for(int k=0;k<4;k++){
        pt v={i+dx[k],j+dy[k]};
        #ifndef TUBUANN_DEBUG30
        if(valid(v)){c=min(c,b_to_v[v.F][v.S]);}
        #endif
      }
      s_to_v[i][j]+=c;
    }
  }
  
  #ifdef TUBUANN_DEBUG31
  dijk(s_to_v,2);
  #else
  dijk(s_to_v);
  #endif

  #ifndef TUBUANN_DEBUG32
  min2D(s_to_v);
  #endif

  #ifdef TUBUANN_DEBUG33
  dijk(s_to_v,2);
  #else
  dijk(s_to_v);
  #endif

  #ifndef TUBUANN_DEBUG34
  ans=min(ans,s_to_v[h-1][w-1]);
  #endif
  
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      #ifndef TUBUANN_DEBUG35
      if((i!=mx || j!=my) && mp[i][j]=='B'){ans=min(ans,s_to_v[i][j]);}
      #endif
    }
  }
  cout<<ans<<endl;
}

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  solve();
  
  return 0;
}
accuracy: 0.5486725663716814
time_ms: 250
memory_kb: 35916
final_rank: 11

code_snippet: //#define TUBUANN_DEBUG21
//#define TUBUANN_DEBUG22
//#define TUBUANN_DEBUG23
//#define TUBUANN_DEBUG24
#define TUBUANN_DEBUG25
//#define TUBUANN_DEBUG26
//#define TUBUANN_DEBUG27
//#define TUBUANN_DEBUG28
//#define TUBUANN_DEBUG29
//#define TUBUANN_DEBUG30
//#define TUBUANN_DEBUG31
//#define TUBUANN_DEBUG32
//#define TUBUANN_DEBUG33
//#define TUBUANN_DEBUG34
//#define TUBUANN_DEBUG35
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<ll,ll> pll;
typedef long double D;
typedef complex<D> P;
#define F first
#define S second
const ll E=1e18+7;
//const ll MOD=1000000007;
const ll MOD=998244353;

#define endl "\n"

  
template<typename T,typename U>istream & operator >> (istream &i,pair<T,U> &A){i>>A.F>>A.S; return i;}
template<typename T>istream & operator >> (istream &i,vector<T> &A){for(auto &I:A){i>>I;} return i;}
template<typename T,typename U>ostream & operator << (ostream &o,const pair<T,U> &A){o<<A.F<<" "<<A.S; return o;}
template<typename T>ostream & operator << (ostream &o,const vector<T> &A){ll i=A.size(); for(auto &I:A){o<<I<<(--i?" ":"");} return o;}
template<typename T>vector<T> & cset(vector<T> &A,T e=T()){for(auto &I:A){I=e;} return A;}

#ifdef TUBUANN_DEBUG21
const int MX=999;
#else
const int MX=1000;
#endif
int h,w;
vector<int> dx={1,0,-1,0};
vector<int> dy={0,1,0,-1};
vector<vector<int>> cost(MX,vector<int>(MX));
vector<vector<int>> s_to_v(MX,vector<int>(MX));
vector<vector<int>> b_to_v(MX,vector<int>(MX));
vector<string> mp(MX);

typedef pair<int,int> pt;

inline bool valid(const pt &p){return p.F>=0 && p.F<h && p.S>=0 && p.S<w;}

void bfs(vector<vector<int>> &m,int mx=4){
  deque<pt> Q;
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      if(m[i][j]==0){Q.push_back({i,j});}
    }
  }
  while(!Q.empty()){
    pt u=Q.front(); Q.pop_front();
    for(int i=0;i<mx;i++){
      pt v=u;
      v.F+=dx[i];
      v.S+=dy[i];
      if(valid(v) && m[v.F][v.S]>m[u.F][u.S]+cost[v.F][v.S]){
        m[v.F][v.S]=m[u.F][u.S]+cost[v.F][v.S];
        if(cost[v.F][v.S]==1){Q.push_back(v);}
        else{Q.push_front(v);}
      }
    }
  }
}

void dijk(vector<vector<int>> &m,int mx=4){
  deque<pt> Q;
  vector<pair<int,pt>> A(h*w);
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      A[i*w+j]={m[i][j],{i,j}};
    }
  }
  sort(A.begin(),A.end());
  for(int idx=0;idx<h*w;idx++){
    pt a=A[idx].S;
    int c= idx+1==h*w?MOD:A[idx+1].F;
    //if(m[a.F][a.S]!=A[idx].F){continue;}
    Q.push_front(a);
    while(!Q.empty() && m[Q[0].F][Q[0].S]<c){
      pt u=Q.front(); Q.pop_front();
      for(int i=0;i<mx;i++){
        pt v=u;
        v.F+=dx[i];
        v.S+=dy[i];
        if(valid(v) && m[v.F][v.S]>m[u.F][u.S]+cost[v.F][v.S]){
          m[v.F][v.S]=m[u.F][u.S]+cost[v.F][v.S];
          if(cost[v.F][v.S]==1){Q.push_back(v);}
          else{Q.push_front(v);}
        }
      }
    }
  }
}

void min2D(vector<vector<int>> &m){
  vector<int> dp(w,MOD);
  for(int i=0;i<h;i++){
    int r=MOD;
    for(int j=0;j<w;j++){
      r=min(r,m[i][j]);
      dp[j]=min(dp[j],m[i][j]);
      #ifdef TUBUANN_DEBUG22
      m[i][j]=min(m[i][j],r);
      #else
        #ifdef TUBUANN_DEBUG23
        m[i][j]=min(m[i][j],dp[j]);
        #else
        m[i][j]=min(r,dp[j]);
        #endif
      #endif
    }
  }
}

void set_val(vector<vector<int>> &m,int e=MOD){
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){m[i][j]=e;}
  }
}

void solve(){
  cin>>h>>w;
  set_val(cost,0);
  
  #ifdef TUBUANN_DEBUG24
  set_val(s_to_v,900);
  #else
  set_val(s_to_v);
  #endif
  
  #ifdef TUBUANN_DEBUG25
  set_val(b_to_v,900);
  #else
  set_val(b_to_v);
  #endif
  
  for(int i=0;i<h;i++){cin>>mp[i];}
  int mx=h,my=w;
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      if(mp[i][j]=='#'){cost[i][j]=1;}
      if(mp[i][j]=='B'){mx=min(mx,i); my=min(my,j);}
    }
  }
  s_to_v[0][0]=0;
  
  #ifdef TUBUANN_DEBUG26
  bfs(s_to_v,2);
  #else
  bfs(s_to_v);
  #endif

  #ifdef TUBUANN_DEBUG27
  int ans=MOD;
  if(mx==h){cout<<s_to_v[h-1][w-1]<<endl; return;}
  #else
  int ans=s_to_v[h-1][w-1];
  if(mx==h){cout<<ans<<endl; return;}
  #endif
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      #ifndef TUBUANN_DEBUG28
      if((i!=mx || j!=my) && mp[i][j]=='B'){ans=min(ans,s_to_v[i][j]);}
      #endif
    }
  }
  if(mp[mx][my]!='B'){cout<<ans<<endl; return;}
  b_to_v[mx][my]=0;
  
  #ifdef TUBUANN_DEBUG29
  bfs(b_to_v,2);
  #else
  bfs(b_to_v);
  #endif
  
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      int c=b_to_v[i][j];
      for(int k=0;k<4;k++){
        pt v={i+dx[k],j+dy[k]};
        #ifndef TUBUANN_DEBUG30
        if(valid(v)){c=min(c,b_to_v[v.F][v.S]);}
        #endif
      }
      s_to_v[i][j]+=c;
    }
  }
  
  #ifdef TUBUANN_DEBUG31
  dijk(s_to_v,2);
  #else
  dijk(s_to_v);
  #endif

  #ifndef TUBUANN_DEBUG32
  min2D(s_to_v);
  #endif

  #ifdef TUBUANN_DEBUG33
  dijk(s_to_v,2);
  #else
  dijk(s_to_v);
  #endif

  #ifndef TUBUANN_DEBUG34
  ans=min(ans,s_to_v[h-1][w-1]);
  #endif
  
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      #ifndef TUBUANN_DEBUG35
      if((i!=mx || j!=my) && mp[i][j]=='B'){ans=min(ans,s_to_v[i][j]);}
      #endif
    }
  }
  cout<<ans<<endl;
}

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  solve();
  
  return 0;
}
accuracy: 0.9203539823008849
time_ms: 270
memory_kb: 36004
final_rank: 10

code_snippet: //#define TUBUANN_DEBUG21
//#define TUBUANN_DEBUG22
//#define TUBUANN_DEBUG23
#define TUBUANN_DEBUG24
//#define TUBUANN_DEBUG25
//#define TUBUANN_DEBUG26
//#define TUBUANN_DEBUG27
//#define TUBUANN_DEBUG28
//#define TUBUANN_DEBUG29
//#define TUBUANN_DEBUG30
//#define TUBUANN_DEBUG31
//#define TUBUANN_DEBUG32
//#define TUBUANN_DEBUG33
//#define TUBUANN_DEBUG34
//#define TUBUANN_DEBUG35
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<ll,ll> pll;
typedef long double D;
typedef complex<D> P;
#define F first
#define S second
const ll E=1e18+7;
//const ll MOD=1000000007;
const ll MOD=998244353;

#define endl "\n"

  
template<typename T,typename U>istream & operator >> (istream &i,pair<T,U> &A){i>>A.F>>A.S; return i;}
template<typename T>istream & operator >> (istream &i,vector<T> &A){for(auto &I:A){i>>I;} return i;}
template<typename T,typename U>ostream & operator << (ostream &o,const pair<T,U> &A){o<<A.F<<" "<<A.S; return o;}
template<typename T>ostream & operator << (ostream &o,const vector<T> &A){ll i=A.size(); for(auto &I:A){o<<I<<(--i?" ":"");} return o;}
template<typename T>vector<T> & cset(vector<T> &A,T e=T()){for(auto &I:A){I=e;} return A;}

#ifdef TUBUANN_DEBUG21
const int MX=999;
#else
const int MX=1000;
#endif
int h,w;
vector<int> dx={1,0,-1,0};
vector<int> dy={0,1,0,-1};
vector<vector<int>> cost(MX,vector<int>(MX));
vector<vector<int>> s_to_v(MX,vector<int>(MX));
vector<vector<int>> b_to_v(MX,vector<int>(MX));
vector<string> mp(MX);

typedef pair<int,int> pt;

inline bool valid(const pt &p){return p.F>=0 && p.F<h && p.S>=0 && p.S<w;}

void bfs(vector<vector<int>> &m,int mx=4){
  deque<pt> Q;
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      if(m[i][j]==0){Q.push_back({i,j});}
    }
  }
  while(!Q.empty()){
    pt u=Q.front(); Q.pop_front();
    for(int i=0;i<mx;i++){
      pt v=u;
      v.F+=dx[i];
      v.S+=dy[i];
      if(valid(v) && m[v.F][v.S]>m[u.F][u.S]+cost[v.F][v.S]){
        m[v.F][v.S]=m[u.F][u.S]+cost[v.F][v.S];
        if(cost[v.F][v.S]==1){Q.push_back(v);}
        else{Q.push_front(v);}
      }
    }
  }
}

void dijk(vector<vector<int>> &m,int mx=4){
  deque<pt> Q;
  vector<pair<int,pt>> A(h*w);
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      A[i*w+j]={m[i][j],{i,j}};
    }
  }
  sort(A.begin(),A.end());
  for(int idx=0;idx<h*w;idx++){
    pt a=A[idx].S;
    int c= idx+1==h*w?MOD:A[idx+1].F;
    //if(m[a.F][a.S]!=A[idx].F){continue;}
    Q.push_front(a);
    while(!Q.empty() && m[Q[0].F][Q[0].S]<c){
      pt u=Q.front(); Q.pop_front();
      for(int i=0;i<mx;i++){
        pt v=u;
        v.F+=dx[i];
        v.S+=dy[i];
        if(valid(v) && m[v.F][v.S]>m[u.F][u.S]+cost[v.F][v.S]){
          m[v.F][v.S]=m[u.F][u.S]+cost[v.F][v.S];
          if(cost[v.F][v.S]==1){Q.push_back(v);}
          else{Q.push_front(v);}
        }
      }
    }
  }
}

void min2D(vector<vector<int>> &m){
  vector<int> dp(w,MOD);
  for(int i=0;i<h;i++){
    int r=MOD;
    for(int j=0;j<w;j++){
      r=min(r,m[i][j]);
      dp[j]=min(dp[j],m[i][j]);
      #ifdef TUBUANN_DEBUG22
      m[i][j]=min(m[i][j],r);
      #else
        #ifdef TUBUANN_DEBUG23
        m[i][j]=min(m[i][j],dp[j]);
        #else
        m[i][j]=min(r,dp[j]);
        #endif
      #endif
    }
  }
}

void set_val(vector<vector<int>> &m,int e=MOD){
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){m[i][j]=e;}
  }
}

void solve(){
  cin>>h>>w;
  set_val(cost,0);
  
  #ifdef TUBUANN_DEBUG24
  set_val(s_to_v,900);
  #else
  set_val(s_to_v);
  #endif
  
  #ifdef TUBUANN_DEBUG25
  set_val(b_to_v,900);
  #else
  set_val(b_to_v);
  #endif
  
  for(int i=0;i<h;i++){cin>>mp[i];}
  int mx=h,my=w;
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      if(mp[i][j]=='#'){cost[i][j]=1;}
      if(mp[i][j]=='B'){mx=min(mx,i); my=min(my,j);}
    }
  }
  s_to_v[0][0]=0;
  
  #ifdef TUBUANN_DEBUG26
  bfs(s_to_v,2);
  #else
  bfs(s_to_v);
  #endif

  #ifdef TUBUANN_DEBUG27
  int ans=MOD;
  if(mx==h){cout<<s_to_v[h-1][w-1]<<endl; return;}
  #else
  int ans=s_to_v[h-1][w-1];
  if(mx==h){cout<<ans<<endl; return;}
  #endif
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      #ifndef TUBUANN_DEBUG28
      if((i!=mx || j!=my) && mp[i][j]=='B'){ans=min(ans,s_to_v[i][j]);}
      #endif
    }
  }
  if(mp[mx][my]!='B'){cout<<ans<<endl; return;}
  b_to_v[mx][my]=0;
  
  #ifdef TUBUANN_DEBUG29
  bfs(b_to_v,2);
  #else
  bfs(b_to_v);
  #endif
  
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      int c=b_to_v[i][j];
      for(int k=0;k<4;k++){
        pt v={i+dx[k],j+dy[k]};
        #ifndef TUBUANN_DEBUG30
        if(valid(v)){c=min(c,b_to_v[v.F][v.S]);}
        #endif
      }
      s_to_v[i][j]+=c;
    }
  }
  
  #ifdef TUBUANN_DEBUG31
  dijk(s_to_v,2);
  #else
  dijk(s_to_v);
  #endif

  #ifndef TUBUANN_DEBUG32
  min2D(s_to_v);
  #endif

  #ifdef TUBUANN_DEBUG33
  dijk(s_to_v,2);
  #else
  dijk(s_to_v);
  #endif

  #ifndef TUBUANN_DEBUG34
  ans=min(ans,s_to_v[h-1][w-1]);
  #endif
  
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      #ifndef TUBUANN_DEBUG35
      if((i!=mx || j!=my) && mp[i][j]=='B'){ans=min(ans,s_to_v[i][j]);}
      #endif
    }
  }
  cout<<ans<<endl;
}

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  solve();
  
  return 0;
}
accuracy: 0.22123893805309736
time_ms: 230
memory_kb: 27784
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<ll,ll> pll;
typedef long double D;
typedef complex<D> P;
#define F first
#define S second
const ll E=1e18+7;
//const ll MOD=1000000007;
const ll MOD=998244353;

#define endl "\n"

  
template<typename T,typename U>istream & operator >> (istream &i,pair<T,U> &A){i>>A.F>>A.S; return i;}
template<typename T>istream & operator >> (istream &i,vector<T> &A){for(auto &I:A){i>>I;} return i;}
template<typename T,typename U>ostream & operator << (ostream &o,const pair<T,U> &A){o<<A.F<<" "<<A.S; return o;}
template<typename T>ostream & operator << (ostream &o,const vector<T> &A){ll i=A.size(); for(auto &I:A){o<<I<<(--i?" ":"");} return o;}
template<typename T>vector<T> & cset(vector<T> &A,T e=T()){for(auto &I:A){I=e;} return A;}

const int MX=1000;
int h,w;
vector<int> dx={1,-1,0,0};
vector<int> dy={0,0,1,-1};
vector<vector<int>> cost(MX,vector<int>(MX));
vector<vector<int>> s_to_v(MX,vector<int>(MX));
vector<vector<int>> b_to_v(MX,vector<int>(MX));
vector<string> mp(MX);

typedef pair<int,int> pt;

inline bool valid(const pt &p){return p.F>=0 && p.F<h && p.S>=0 && p.S<w;}

void bfs(vector<vector<int>> &m){
  deque<pt> Q;
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      if(m[i][j]==0){Q.push_back({i,j});}
    }
  }
  while(!Q.empty()){
    pt u=Q.front(); Q.pop_front();
    for(int i=0;i<4;i++){
      pt v=u;
      v.F+=dx[i];
      v.S+=dy[i];
      if(valid(v) && m[v.F][v.S]>m[u.F][u.S]+cost[v.F][v.S]){
        m[v.F][v.S]=m[u.F][u.S]+cost[v.F][v.S];
        if(cost[v.F][v.S]==1){Q.push_back(v);}
        else{Q.push_front(v);}
      }
    }
  }
}

void dijk(vector<vector<int>> &m){
  deque<pt> Q;
  vector<pair<int,pt>> A(h*w+1,{MOD,{-1,-1}});
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      A[i*w+j]={m[i][j],{i,j}};
    }
  }
  sort(A.begin(),A.end());
  for(int idx=0;idx<h*w;idx++){
    pt a=A[idx].S;
    int c=A[idx+1].F;
    if(m[a.F][a.S]!=A[idx].F){continue;}
    Q.push_front(a);
    while(!Q.empty() && m[Q[0].F][Q[0].S]<c){
      pt u=Q.front(); Q.pop_front();
      for(int i=0;i<4;i++){
        pt v=u;
        v.F+=dx[i];
        v.S+=dy[i];
        if(valid(v) && m[v.F][v.S]>m[u.F][u.S]+cost[v.F][v.S]){
          m[v.F][v.S]=m[u.F][u.S]+cost[v.F][v.S];
          if(cost[v.F][v.S]==1){Q.push_back(v);}
          else{Q.push_front(v);}
        }
      }
    }
  }
}

void min2D(vector<vector<int>> &m){
  vector<int> dp(w,MOD);
  for(int i=0;i<h;i++){
    int r=MOD;
    for(int j=0;j<w;j++){
      r=min(r,m[i][j]);
      dp[j]=min(dp[j],m[i][j]);
      m[i][j]=min(r,dp[j]);
    }
  }
}

void set_val(vector<vector<int>> &m,int e=MOD){
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){m[i][j]=e;}
  }
}

void solve(){
  cin>>h>>w;
  set_val(cost,0);
  set_val(s_to_v);
  set_val(b_to_v);
  for(int i=0;i<h;i++){cin>>mp[i];}
  int mx=h,my=w;
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      if(mp[i][j]=='#'){cost[i][j]=1;}
      if(mp[i][j]=='B'){mx=min(mx,i); my=min(my,j);}
    }
  }
  s_to_v[0][0]=0;
  bfs(s_to_v);
  int ans=s_to_v[h-1][w-1];
  if(mx==h){cout<<ans<<endl; return;}
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      if((i!=mx || j!=my) && mp[i][j]=='B'){ans=min(ans,s_to_v[i][j]);}
    }
  }
  if(mp[mx][my]!='B'){cout<<ans<<endl; return;}
  b_to_v[mx][my]=0;
  bfs(b_to_v);
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      int c=b_to_v[i][j];
      for(int k=0;k<4;k++){
        pt v={i+dx[k],j+dy[k]};
        if(valid(v)){c=min(c,b_to_v[v.F][v.S]);}
      }
      s_to_v[i][j]+=c;
    }
  }
  dijk(s_to_v);
  min2D(s_to_v);
  dijk(s_to_v);
  ans=min(ans,s_to_v[h-1][w-1]);
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      if((i!=mx || j!=my) && mp[i][j]=='B'){ans=min(ans,s_to_v[i][j]);}
    }
  }
  cout<<ans<<endl;
}

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  solve();
  
  return 0;
}
accuracy: 1
time_ms: 7270
memory_kb: 36036
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<ll,ll> pll;
typedef long double D;
typedef complex<D> P;
#define F first
#define S second
const ll E=1e18+7;
//const ll MOD=1000000007;
const ll MOD=998244353;

#define endl "\n"

  
template<typename T,typename U>istream & operator >> (istream &i,pair<T,U> &A){i>>A.F>>A.S; return i;}
template<typename T>istream & operator >> (istream &i,vector<T> &A){for(auto &I:A){i>>I;} return i;}
template<typename T,typename U>ostream & operator << (ostream &o,const pair<T,U> &A){o<<A.F<<" "<<A.S; return o;}
template<typename T>ostream & operator << (ostream &o,const vector<T> &A){ll i=A.size(); for(auto &I:A){o<<I<<(--i?" ":"");} return o;}
template<typename T>vector<T> & cset(vector<T> &A,T e=T()){for(auto &I:A){I=e;} return A;}

const int MX=1000;
int h,w;
vector<int> dx={1,-1,0,0};
vector<int> dy={0,0,1,-1};
vector<vector<int>> cost(MX,vector<int>(MX));
vector<vector<int>> s_to_v(MX,vector<int>(MX));
vector<vector<int>> b_to_v(MX,vector<int>(MX));
vector<string> mp(MX);

typedef pair<int,int> pt;

inline bool valid(const pt &p){return p.F>=0 && p.F<h && p.S>=0 && p.S<w;}

void bfs(vector<vector<int>> &m){
  deque<pt> Q;
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      if(m[i][j]==0){Q.push_back({i,j});}
    }
  }
  while(!Q.empty()){
    pt u=Q.front(); Q.pop_front();
    for(int i=0;i<4;i++){
      pt v=u;
      v.F+=dx[i];
      v.S+=dy[i];
      if(valid(v) && m[v.F][v.S]>m[u.F][u.S]+cost[v.F][v.S]){
        m[v.F][v.S]=m[u.F][u.S]+cost[v.F][v.S];
        if(cost[v.F][v.S]==1){Q.push_back(v);}
        else{Q.push_front(v);}
      }
    }
  }
}

void dijk(vector<vector<int>> &m){
  deque<pt> Q;
  vector<pair<int,pt>> A(h*w+1,{MOD,{-1,-1}});
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      A[i*w+j]={m[i][j],{i,j}};
    }
  }
  sort(A.begin(),A.end());
  for(int idx=0;idx<h*w;idx++){
    pt a=A[idx].S;
    int c=A[idx+1].F;
    //if(m[a.F][a.S]!=A[idx].F){continue;}
    Q.push_front(a);
    while(!Q.empty() && m[Q[0].F][Q[0].S]<c){
      pt u=Q.front(); Q.pop_front();
      for(int i=0;i<4;i++){
        pt v=u;
        v.F+=dx[i];
        v.S+=dy[i];
        if(valid(v) && m[v.F][v.S]>m[u.F][u.S]+cost[v.F][v.S]){
          m[v.F][v.S]=m[u.F][u.S]+cost[v.F][v.S];
          if(cost[v.F][v.S]==1){Q.push_back(v);}
          else{Q.push_front(v);}
        }
      }
    }
  }
}

void min2D(vector<vector<int>> &m){
  vector<int> dp(w,MOD);
  for(int i=0;i<h;i++){
    int r=MOD;
    for(int j=0;j<w;j++){
      r=min(r,m[i][j]);
      dp[j]=min(dp[j],m[i][j]);
      m[i][j]=min(r,dp[j]);
    }
  }
}

void set_val(vector<vector<int>> &m,int e=MOD){
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){m[i][j]=e;}
  }
}

void solve(){
  cin>>h>>w;
  set_val(cost,0);
  set_val(s_to_v);
  set_val(b_to_v);
  for(int i=0;i<h;i++){cin>>mp[i];}
  int mx=h,my=w;
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      if(mp[i][j]=='#'){cost[i][j]=1;}
      if(mp[i][j]=='B'){mx=min(mx,i); my=min(my,j);}
    }
  }
  s_to_v[0][0]=0;
  bfs(s_to_v);
  int ans=s_to_v[h-1][w-1];
  if(mx==h){cout<<ans<<endl; return;}
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      if((i!=mx || j!=my) && mp[i][j]=='B'){ans=min(ans,s_to_v[i][j]);}
    }
  }
  if(mp[mx][my]!='B'){cout<<ans<<endl; return;}
  b_to_v[mx][my]=0;
  bfs(b_to_v);
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      int c=b_to_v[i][j];
      for(int k=0;k<4;k++){
        pt v={i+dx[k],j+dy[k]};
        if(valid(v)){c=min(c,b_to_v[v.F][v.S]);}
      }
      s_to_v[i][j]+=c;
    }
  }
  dijk(s_to_v);
  min2D(s_to_v);
  dijk(s_to_v);
  ans=min(ans,s_to_v[h-1][w-1]);
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      if((i!=mx || j!=my) && mp[i][j]=='B'){ans=min(ans,s_to_v[i][j]);}
    }
  }
  cout<<ans<<endl;
}

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  solve();
  
  return 0;
}
accuracy: 1
time_ms: 260
memory_kb: 36036
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;

const int INF = 1e9;
const int dx[4] = {0, 1, 0, -1}, dy[4] = {-1, 0, 1, 0};

int H, W;
vector<string> grid;

struct State {
  int x, y, cost, b;
  State(int x, int y, int cost, int b): x(x), y(y), cost(cost), b(b) {}
  bool operator<(const State &e) const {
    return cost < e.cost;
  };

  bool operator>(const State &e) const {
    return cost > e.cost;
  };
};

int calc0() {
  bool used[H][W];
  fill_n(*used, H*W, false);
  deque<State> Q;  
  Q.push_front(State(0, 0, 0, 0));
  while ( !Q.empty()) {
    State s = Q.front(); Q.pop_front();    
    int x = s.x, y = s.y, cost = s.cost, b = s.b;      

    if ( x == W-1 && y == H-1 ) return cost;      
      
    if ( used[y][x] ) continue;
    used[y][x] = true;
      
    for ( int i = 0; i < 4; i++ ) {
      int nx = x+dx[i], ny = y+dy[i];
      if ( nx < 0 || nx >= W || ny < 0 || ny >= H ) continue;      
      if ( grid[ny][nx] == '#' ) {
	Q.push_back(State(nx, ny, cost+1, b));	
      } else {
	Q.push_front(State(nx, ny, cost, b));	
      }
    }
  }

  return INF;
}

int calc1() {
  int dist[H][W];
  {        
    fill_n(*dist, H*W, INF);    
    deque<State> Q;  
    for ( int i = 0; i < H; i++ ) {
      for ( int j = 0; j < W; j++ ) {
	if ( grid[i][j] == 'B' ) Q.push_front(State(j, i, 0, 0));
      }
    }
    while ( !Q.empty()) {
      State s = Q.front(); Q.pop_front();    
      int x = s.x, y = s.y, cost = s.cost, b = s.b;    
      
      if ( dist[y][x] != INF ) continue;
      dist[y][x] = cost;
      
      for ( int i = 0; i < 4; i++ ) {
	int nx = x+dx[i], ny = y+dy[i];
	if ( nx < 0 || nx >= W || ny < 0 || ny >= H ) continue;      
	if ( grid[y][x] == '#' ) {
	  Q.push_back(State(nx, ny, cost+1, b));	
	} else {
	  Q.push_front(State(nx, ny, cost, b));	
	}
      }
    }  
  }
  // cout << dist[0][0] << endl;
  vector<int> distR(H, INF), distC(W, INF);
  {
    bool used[H][W][2];
    fill_n(**used, H*W*2, false);
    priority_queue<State, vector<State>, greater<State> > Q;  
    Q.push(State(0, 0, 0, 0));
    while ( !Q.empty()) {
      State s = Q.top(); Q.pop();    
      int x = s.x, y = s.y, cost = s.cost, b = s.b;
      
      if ( b ) {
	distR[y] = min(distR[y], cost);
	distC[x] = min(distC[x], cost);
      }
      else {
	distR[y] = min(distR[y], cost+dist[y][x]);	
	distC[x] = min(distC[x], cost+dist[y][x]);
      } 
      
      if ( used[y][x][b] ) continue;
      used[y][x][b] = true;

      Q.push(State(x, y, cost+dist[y][x], 1));      
      
      for ( int i = 0; i < 4; i++ ) {
	int nx = x+dx[i], ny = y+dy[i];
	if ( nx < 0 || nx >= W || ny < 0 || ny >= H ) continue;      
	if ( grid[ny][nx] == '#' ) {
	  Q.push(State(nx, ny, cost+1, b));	
	} else {
	  int nb = b;
	  if ( grid[ny][nx] == 'B' ) nb = 1;
	  Q.push(State(nx, ny, cost, nb));	
	}
      }
    }
  }

  int ans = INF;  
  bool used[H][W];
  fill_n(*used, H*W, false);
  deque<State> Q;  
  Q.push_front(State(W-1, H-1, 0, 0));  
  while ( !Q.empty()) {
    State s = Q.front(); Q.pop_front();    
    int x = s.x, y = s.y, cost = s.cost, b = s.b;      
    
    ans = min(ans, min(cost+distR[y], cost+distC[x]));   
      
    if ( used[y][x] ) continue;
    used[y][x] = true;
      
    for ( int i = 0; i < 4; i++ ) {
      int nx = x+dx[i], ny = y+dy[i];
      if ( nx < 0 || nx >= W || ny < 0 || ny >= H ) continue;      
      if ( grid[y][x] == '#' ) {
	Q.push_back(State(nx, ny, cost+1, b));	
      } else {
	Q.push_front(State(nx, ny, cost, b));	
      }
    }
  }

  return ans;  
}

int calc2() {
  int ans = INF;
  using P = pair<int, int>;  
  P dist[H][W];
  {        
    fill_n(*dist, H*W, P(INF, INF));    
    deque<State> Q;  
    for ( int i = 0; i < H; i++ ) {
      for ( int j = 0; j < W; j++ ) {
	if ( grid[i][j] == 'B' ) Q.push_front(State(j, i, 0, i*W+j));
      }
    }
    while ( !Q.empty()) {
      State s = Q.front(); Q.pop_front();    
      int x = s.x, y = s.y, cost = s.cost, b = s.b;    
      
      if ( dist[y][x].first != INF ) continue;
      dist[y][x] = P(cost, b);      
      
      for ( int i = 0; i < 4; i++ ) {
	int nx = x+dx[i], ny = y+dy[i];
	if ( nx < 0 || nx >= W || ny < 0 || ny >= H ) continue;      
	if ( grid[y][x] == '#' ) {
	  Q.push_back(State(nx, ny, cost+1, b));	
	} else {
	  Q.push_front(State(nx, ny, cost, b));	
	}
      }
    }  
  }

  vector<vector<State> > distR(H), distC(W);  
  {
    bool used[H][W][2];
    fill_n(**used, H*W*2, false);
    priority_queue<State, vector<State>, greater<State> > Q;  
    Q.push(State(0, 0, 0, 0));
    while ( !Q.empty()) {
      State s = Q.top(); Q.pop();    
      int x = s.x, y = s.y, cost = s.cost, b = s.b;      
      if ( used[y][x][(bool)b] ) continue;
      used[y][x][(bool)b] = true;      
      
      if ( b > 0 ) {
	if ( distR[y].size() < 2 ) {
	  if ( distR[y].size() == 0 ) distR[y].push_back(s);
	  else if ( distR[y][0].b != b ) distR[y].push_back(s);
	}
	if ( distC[x].size() < 2 ) {
	  if ( distC[x].size() == 0 ) distC[x].push_back(s);
	  else if ( distC[x][0].b != b ) distC[x].push_back(s);
	}
      }      
      /* if ( b == 2 ) {
	ans = min(ans, cost);	
	} */      

      if ( dist[y][x].first != INF ) {
	if ( !used[y][x][(bool)dist[y][x].second] )
	  Q.push(State(x, y, cost+dist[y][x].first, dist[y][x].second));
      }
      
      for ( int i = 0; i < 4; i++ ) {
	int nx = x+dx[i], ny = y+dy[i];
	if ( b == ny*W+nx ) continue;	
	if ( nx < 0 || nx >= W || ny < 0 || ny >= H ) continue;      
	if ( grid[ny][nx] == '#' ) {
	  if ( !used[ny][nx][(bool)b] ) Q.push(State(nx, ny, cost+1, b));	
	} else {
	  int nb = b;
	  if ( grid[ny][nx] == 'B' ) nb = ny*W+nx;
	  if ( !used[ny][nx][(bool)nb] ) Q.push(State(nx, ny, cost, nb));	
	}
      }
    }
  }

  vector<vector<State> > distR2(H), distC2(W);
  {
    bool used[H][W];
    fill_n(*used, H*W, false);
    deque<State> Q;  
    for ( int i = 0; i < H; i++ ) {
      for ( int j = 0; j < W; j++ ) {
	if ( grid[i][j] == 'B' ) Q.push_front(State(j, i, 0, i*W+j));
      }
    }
    while ( !Q.empty()) {
      State s = Q.front(); Q.pop_front();    
      int x = s.x, y = s.y, cost = s.cost, b = s.b;
      
      if ( distR2[y].size() < 2 ) {
	if ( distR2[y].size() == 0 ) distR2[y].push_back(s);
	else if ( distR2[y][0].b != b ) distR2[y].push_back(s);
      }
      if ( distC2[x].size() < 2 ) {
	if ( distC2[x].size() == 0 ) distC2[x].push_back(s);
	else if ( distC2[x][0].b != b ) distC2[x].push_back(s);
      }
      
      if ( used[y][x] ) continue;
      used[y][x] = true;
      
      for ( int i = 0; i < 4; i++ ) {
	int nx = x+dx[i], ny = y+dy[i];
	if ( nx < 0 || nx >= W || ny < 0 || ny >= H ) continue;      
	if ( grid[y][x] == '#' ) {
	  Q.push_back(State(nx, ny, cost+1, b));	
	} else {
	  Q.push_front(State(nx, ny, cost, b));	
	}
      }
    }
  }
  
  for ( int i = 0; i < H; i++ ) {
    for ( State j : distR[i] ) {
      for ( State k : distR2[i] ) {
	if ( j.b == k.b ) continue;
	// if ( j.cost+k.cost == 5 ) cout << "R" << i <<  " " << j.b << ":" << j.cost << " " << k.b << ":" << k.cost << endl;	
	ans = min(ans, j.cost+k.cost);	
      }
    }
  }

  for ( int i = 0; i < W; i++ ) {
    for ( State j : distC[i] ) {
      for ( State k : distC2[i] ) {
	if ( j.b == k.b ) continue;
	// if ( j.cost+k.cost == 5 ) cout << "W" << i <<  " " << j.b << ":" << j.cost << " " << k.b << ":" << k.cost << endl;	
	ans = min(ans, j.cost+k.cost);	
      }
    }
  }

  return ans;  
}

signed main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  cin >> H >> W;

  grid = vector<string>(H);
  int cntB = 0;  
  for ( int i = 0; i < H; i++ ) {
    cin >> grid[i];
    for ( int j = 0; j < W; j++ ) cntB += (grid[i][j] == 'B');    
  }

  int ans = calc0();
  if ( cntB ) ans = min(ans, calc1());
  if ( cntB >= 2 ) ans = min(ans, calc2());

  cout << ans << endl;
  
  return 0;
}
accuracy: 1
time_ms: 2230
memory_kb: 140988
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;

#define lp(i,n) for(int i=0;i<n;i++)
#define INF 1e9+7

//field data
int g[1010][1010];
//_0#1B2

//distance from start to point
int dp_stp[1010][1010];

//distance from on the way to blaster in upper left to point
int dp_ptb[1010][1010];

//distance fron point to goal line
int dp[1010][1010];
int dpw[1010];
int dph[1010];
int posw=-1,posh=-1;
int w,h;


void fordebg(){
  return;
  lp(i,h){
    lp(j,w){
      cout<<dp[i+1][j+1];
    }
    cout<<endl;
  }
cout<<endl;
/*
 lp(i,h){
    lp(j,w){
      cout<<dp_stp[i+1][j+1];
    }
    cout<<endl;
  }
  cout<<endl;
  lp(i,h){
    lp(j,w){
      cout<<dp_ptb[i+1][j+1];
    }
    cout<<endl;
  }
  cout<<endl;*/
  
}

void linesolve(){
  priority_queue<pair<int,pair<int,int>>,vector<pair<int,pair<int,int>>>,greater<pair<int,pair<int,int>>>> q;
  q.push({0,{h,w}});
  dp[h][w]=0;
  lp(i,1010){
    lp(j,1010){
      if(g[i][j]==2){
	if(i==posh&&j==posw){
	  continue;
	}
	q.push({0,{i,j}});
	dp[i][j]=0;
      }
    }
  }
  int a[4]={-1,1,0,0};
  int b[4]={0,0,-1,1};
  while(!q.empty()){
    int x=q.top().second.first;
    int y=q.top().second.second;
    int cost=q.top().first;
    q.pop();
    if(g[x][y]==-1)continue;
    lp(i,4){
      int nx=x+a[i];
      int ny=y+b[i];
      int gn=cost;
      if(g[x][y]==1) gn++;
      if(g[nx][ny]==0||g[nx][ny]==2){
	if(dp[nx][ny]<=gn)continue;
	dp[nx][ny]=gn;
	q.push({gn,{nx,ny}});
      }
      else if(g[nx][ny]==1){
	if(dp[nx][ny]<=gn)continue;
	dp[nx][ny]=gn;
	q.push({gn,{nx,ny}});
      }
    }
  }
  fordebg();
  lp(i,1010){
    lp(j,1010){
      dph[i]=min(dp[i][j],dph[i]);
      if(dph[i]==-1)dph[i]=0;
      dpw[j]=min(dpw[j],dp[i][j]);
      if(dpw[j]==-1)dpw[j]=0;
    }
  }
  while(!q.empty())q.pop();
  lp(i,1010){
    lp(j,1010){
      if(g[i][j]==-1) continue;
      dp[i][j]=min(dph[i],dpw[j]);
      q.push({dp[i][j],{i,j}});
    }
  }
  fordebg();
  while(!q.empty()){
    int x=q.top().second.first;
    int y=q.top().second.second;
    int cost=q.top().first;
    q.pop();
    if(dp[x][y]<cost) continue;
    if(g[x][y]==-1)continue;
    lp(i,4){
      int nx=x+a[i];
      int ny=y+b[i];
      int gn=cost;
      if(g[x][y]==1)gn++;
      if(g[nx][ny]==0||g[nx][ny]==2){
	if(dp[nx][ny]<=gn)continue;
	dp[nx][ny]=gn;
	q.push({gn,{nx,ny}});
      }
      else if(g[nx][ny]==1){
	if(dp[nx][ny]<=gn)continue;
	dp[nx][ny]=gn;
	q.push({gn,{nx,ny}});
      }
    }
  }
  return;
}

void bfsptb(int sx,int sy){
  priority_queue<pair<int,pair<int,int>>,vector<pair<int,pair<int,int>>>,greater<pair<int,pair<int,int>>>> q;
  //queue<pair<int,int>> q;
  dp_ptb[sx][sy]=0;
  q.push({0,{sx,sy}});
  int a[4]={-1,1,0,0};
  int b[4]={0,0,-1,1};
  while(!q.empty()){
    int x=q.top().second.first;
    int y=q.top().second.second;
    int cost=dp_ptb[x][y];
    q.pop();
    lp(i,4){
      int nx=x+a[i];
      int ny=y+b[i];
      if(g[nx][ny]==0||g[nx][ny]==2){
	if(dp_ptb[nx][ny]<=cost)continue;
	dp_ptb[nx][ny]=cost;
	q.push({cost,{nx,ny}});
      }
      else if(g[nx][ny]==1){
	if(dp_ptb[nx][ny]<=cost+1)continue;
	dp_ptb[nx][ny]=cost+1;
	q.push({cost+1,{nx,ny}});
      }
    }
  }
}

void bfsstp(){
  priority_queue<pair<int,pair<int,int>>,vector<pair<int,pair<int,int>>>,greater<pair<int,pair<int,int>>>> q;
  //queue<pair<int,int>> q;
  dp_stp[1][1]=0;
  q.push({0,{1,1}});
  int a[4]={-1,1,0,0};
  int b[4]={0,0,-1,1};
  while(!q.empty()){
    int x=q.top().second.first;
    int y=q.top().second.second;
    int cost=dp_stp[x][y];
    q.pop();
    lp(i,4){
      int nx=x+a[i];
      int ny=y+b[i];
      if(g[nx][ny]==0||g[nx][ny]==2){
	if(dp_stp[nx][ny]<=cost)continue;
	dp_stp[nx][ny]=cost;
	q.push({cost,{nx,ny}});
      }
      else if(g[nx][ny]==1){
	if(dp_stp[nx][ny]<=cost+1)continue;
	dp_stp[nx][ny]=cost+1;
	q.push({cost+1,{nx,ny}});
      }
    }
  }
}


int main(){
  cin>>h>>w;
  posw=w,posh=h;
  lp(i,1010){
    lp(j,1010){
      g[i][j]=-1;
      dp_stp[i][j]=INF;
      dp_ptb[i][j]=INF;
      dp[i][j]=INF;
    }
  }
  lp(i,h){
    lp(j,w){
      char c;
      cin>>c;
      if(c=='\n')cin>>c;
      if(c=='_')g[i+1][j+1]=0;
      if(c=='#')g[i+1][j+1]=1;
      if(c=='B'){
	g[i+1][j+1]=2;
	posh=min(i+1,posh);
	posw=min(j+1,posw);
      }
    }
  }
  if(g[posh][posw]!=2){
    posw=-1;
    posh=-1;
  }
  bfsstp();
  if(posw!=-1){
    bfsptb(posh,posw);
  }
  int ans=dp_stp[h][w];
  lp(i,1010){
    dpw[i]=INF;
    dph[i]=INF;
    lp(j,1010){
      if(g[i][j]==2){
	if(i==posh&&j==posw)continue;
	ans=min(ans,dp_stp[i][j]);
      }
    }
  }
  if(posw!=-1){
    linesolve();
    lp(i,h){
      lp(j,w){
	int ne=dp_stp[i+1][j+1]+dp_ptb[i+1][j+1]+dp[i+1][j+1];
	if(g[i+1][j+1]==1)ne--;
	ans=min(ans,ne);
      }
    }
  }
  cout<<ans<<endl;

  fordebg();
  return 0;
}
accuracy: 1
time_ms: 880
memory_kb: 43272
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define int long long
const int INF = 1e9;
const int dx[4] = {0, 1, 0, -1}, dy[4] = {-1, 0, 1, 0};

int H, W;
vector<string> grid;

struct State {
  int x, y, cost, b;
  State(int x, int y, int cost, int b): x(x), y(y), cost(cost), b(b) {}
  bool operator<(const State &e) const {
    return cost < e.cost;
  };

  bool operator>(const State &e) const {
    return cost > e.cost;
  };
};

int calc0() {
  bool used[H][W];
  fill_n(*used, H*W, false);
  deque<State> Q;  
  Q.push_front(State(0, 0, 0, 0));
  while ( !Q.empty()) {
    State s = Q.front(); Q.pop_front();    
    int x = s.x, y = s.y, cost = s.cost, b = s.b;      

    if ( x == W-1 && y == H-1 ) return cost;      
      
    if ( used[y][x] ) continue;
    used[y][x] = true;
      
    for ( int i = 0; i < 4; i++ ) {
      int nx = x+dx[i], ny = y+dy[i];
      if ( nx < 0 || nx >= W || ny < 0 || ny >= H ) continue;      
      if ( grid[ny][nx] == '#' ) {
	Q.push_back(State(nx, ny, cost+1, b));	
      } else {
	Q.push_front(State(nx, ny, cost, b));	
      }
    }
  }

  return INF;
}

int calc1() {
  int dist[H][W];
  {        
    fill_n(*dist, H*W, INF);    
    deque<State> Q;  
    for ( int i = 0; i < H; i++ ) {
      for ( int j = 0; j < W; j++ ) {
	if ( grid[i][j] == 'B' ) Q.push_front(State(j, i, 0, 0));
      }
    }
    while ( !Q.empty()) {
      State s = Q.front(); Q.pop_front();    
      int x = s.x, y = s.y, cost = s.cost, b = s.b;    
      
      if ( dist[y][x] != INF ) continue;
      dist[y][x] = cost;
      
      for ( int i = 0; i < 4; i++ ) {
	int nx = x+dx[i], ny = y+dy[i];
	if ( nx < 0 || nx >= W || ny < 0 || ny >= H ) continue;      
	if ( grid[y][x] == '#' ) {
	  Q.push_back(State(nx, ny, cost+1, b));	
	} else {
	  Q.push_front(State(nx, ny, cost, b));	
	}
      }
    }  
  }
  // cout << dist[0][0] << endl;
  vector<int> distR(H, INF), distC(W, INF);
  {
    bool used[H][W][2];
    fill_n(**used, H*W*2, false);
    priority_queue<State, vector<State>, greater<State> > Q;  
    Q.push(State(0, 0, 0, 0));
    while ( !Q.empty()) {
      State s = Q.top(); Q.pop();    
      int x = s.x, y = s.y, cost = s.cost, b = s.b;
      
      if ( b ) {
	distR[y] = min(distR[y], cost);
	distC[x] = min(distC[x], cost);
      }
      else {
	distR[y] = min(distR[y], cost+dist[y][x]);	
	distC[x] = min(distC[x], cost+dist[y][x]);
      } 
      
      if ( used[y][x][b] ) continue;
      used[y][x][b] = true;

      Q.push(State(x, y, cost+dist[y][x], 1));      
      
      for ( int i = 0; i < 4; i++ ) {
	int nx = x+dx[i], ny = y+dy[i];
	if ( nx < 0 || nx >= W || ny < 0 || ny >= H ) continue;      
	if ( grid[ny][nx] == '#' ) {
	  Q.push(State(nx, ny, cost+1, b));	
	} else {
	  int nb = b;
	  if ( grid[ny][nx] == 'B' ) nb = 1;
	  Q.push(State(nx, ny, cost, nb));	
	}
      }
    }
  }

  int ans = INF;  
  bool used[H][W];
  fill_n(*used, H*W, false);
  deque<State> Q;  
  Q.push_front(State(W-1, H-1, 0, 0));  
  while ( !Q.empty()) {
    State s = Q.front(); Q.pop_front();    
    int x = s.x, y = s.y, cost = s.cost, b = s.b;      
    
    ans = min(ans, min(cost+distR[y], cost+distC[x]));   
      
    if ( used[y][x] ) continue;
    used[y][x] = true;
      
    for ( int i = 0; i < 4; i++ ) {
      int nx = x+dx[i], ny = y+dy[i];
      if ( nx < 0 || nx >= W || ny < 0 || ny >= H ) continue;      
      if ( grid[y][x] == '#' ) {
	Q.push_back(State(nx, ny, cost+1, b));	
      } else {
	Q.push_front(State(nx, ny, cost, b));	
      }
    }
  }

  return ans;  
}

int calc2() {
  int ans = INF;
  using P = pair<int, int>;  
  P dist[H][W];
  {        
    fill_n(*dist, H*W, P(INF, INF));    
    deque<State> Q;  
    for ( int i = 0; i < H; i++ ) {
      for ( int j = 0; j < W; j++ ) {
	if ( grid[i][j] == 'B' ) Q.push_front(State(j, i, 0, i*W+j));
      }
    }
    while ( !Q.empty()) {
      State s = Q.front(); Q.pop_front();    
      int x = s.x, y = s.y, cost = s.cost, b = s.b;    
      
      if ( dist[y][x].first != INF ) continue;
      dist[y][x] = P(cost, b);      
      
      for ( int i = 0; i < 4; i++ ) {
	int nx = x+dx[i], ny = y+dy[i];
	if ( nx < 0 || nx >= W || ny < 0 || ny >= H ) continue;      
	if ( grid[y][x] == '#' ) {
	  Q.push_back(State(nx, ny, cost+1, b));	
	} else {
	  Q.push_front(State(nx, ny, cost, b));	
	}
      }
    }  
  }

  vector<vector<State> > distR(H), distC(W);  
  {
    bool used[H][W][2];
    fill_n(**used, H*W*2, false);
    priority_queue<State, vector<State>, greater<State> > Q;  
    Q.push(State(0, 0, 0, 0));
    while ( !Q.empty()) {
      State s = Q.top(); Q.pop();    
      int x = s.x, y = s.y, cost = s.cost, b = s.b;      
      if ( used[y][x][(bool)b] ) continue;
      used[y][x][(bool)b] = true;      
      
      if ( b > 0 ) {
	if ( distR[y].size() < 2 ) {
	  if ( distR[y].size() == 0 ) distR[y].push_back(s);
	  else if ( distR[y][0].b != b ) distR[y].push_back(s);
	}
	if ( distC[x].size() < 2 ) {
	  if ( distC[x].size() == 0 ) distC[x].push_back(s);
	  else if ( distC[x][0].b != b ) distC[x].push_back(s);
	}
      }      
      /* if ( b == 2 ) {
	ans = min(ans, cost);	
	} */      

      if ( dist[y][x].first != INF ) {
	Q.push(State(x, y, cost+dist[y][x].first, dist[y][x].second));
      }
      
      for ( int i = 0; i < 4; i++ ) {
	int nx = x+dx[i], ny = y+dy[i];
	if ( b == ny*W+nx ) continue;	
	if ( nx < 0 || nx >= W || ny < 0 || ny >= H ) continue;      
	if ( grid[ny][nx] == '#' ) {
	  Q.push(State(nx, ny, cost+1, b));	
	} else {
	  int nb = b;
	  if ( grid[ny][nx] == 'B' ) nb = ny*W+nx;
	  Q.push(State(nx, ny, cost, nb));	
	}
      }
    }
  }

  vector<vector<State> > distR2(H), distC2(W);
  {
    bool used[H][W];
    fill_n(*used, H*W, false);
    deque<State> Q;  
    for ( int i = 0; i < H; i++ ) {
      for ( int j = 0; j < W; j++ ) {
	if ( grid[i][j] == 'B' ) Q.push_front(State(j, i, 0, i*W+j));
      }
    }
    while ( !Q.empty()) {
      State s = Q.front(); Q.pop_front();    
      int x = s.x, y = s.y, cost = s.cost, b = s.b;
      
      if ( distR2[y].size() < 2 ) {
	if ( distR2[y].size() == 0 ) distR2[y].push_back(s);
	else if ( distR2[y][0].b != b ) distR2[y].push_back(s);
      }
      if ( distC2[x].size() < 2 ) {
	if ( distC2[x].size() == 0 ) distC2[x].push_back(s);
	else if ( distC2[x][0].b != b ) distC2[x].push_back(s);
      }
      
      if ( used[y][x] ) continue;
      used[y][x] = true;
      
      for ( int i = 0; i < 4; i++ ) {
	int nx = x+dx[i], ny = y+dy[i];
	if ( nx < 0 || nx >= W || ny < 0 || ny >= H ) continue;      
	if ( grid[y][x] == '#' ) {
	  Q.push_back(State(nx, ny, cost+1, b));	
	} else {
	  Q.push_front(State(nx, ny, cost, b));	
	}
      }
    }
  }
  
  for ( int i = 0; i < H; i++ ) {
    for ( State j : distR[i] ) {
      for ( State k : distR2[i] ) {
	if ( j.b == k.b ) continue;
	// if ( j.cost+k.cost == 5 ) cout << "R" << i <<  " " << j.b << ":" << j.cost << " " << k.b << ":" << k.cost << endl;	
	ans = min(ans, j.cost+k.cost);	
      }
    }
  }

  for ( int i = 0; i < W; i++ ) {
    for ( State j : distC[i] ) {
      for ( State k : distC2[i] ) {
	if ( j.b == k.b ) continue;
	// if ( j.cost+k.cost == 5 ) cout << "W" << i <<  " " << j.b << ":" << j.cost << " " << k.b << ":" << k.cost << endl;	
	ans = min(ans, j.cost+k.cost);	
      }
    }
  }

  return ans;  
}

signed main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  cin >> H >> W;

  grid = vector<string>(H);
  int cntB = 0;  
  for ( int i = 0; i < H; i++ ) {
    cin >> grid[i];
    for ( int j = 0; j < W; j++ ) cntB += (grid[i][j] == 'B');    
  }

  int ans = calc0();
  if ( cntB ) ans = min(ans, calc1());
  if ( cntB >= 2 ) ans = min(ans, calc2());

  cout << ans << endl;
  
  return 0;
}
accuracy: 1
time_ms: 3610
memory_kb: 276020
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}

struct FastIO{
  FastIO(){
    cin.tie(0);
    ios::sync_with_stdio(0);
  }
}fastio_beet;

using P = pair<int, int>;
vector< vector<int> > bfs(vector<string> &s,vector<P> &vp,char wall,int dir){
  int h=s.size(),w=s.front().size();
  vector< vector<int> > dp(h,vector<int>(w,-1));
  deque<P> q;

  for(int i=0;i<(int)vp.size();i++){
    int sy=vp[i].first,sx=vp[i].second;
    dp[sy][sx]=0;
    q.emplace_back(sy,sx);
  }

  int dy[]={1,-1,0,0,1,1,-1,-1};
  int dx[]={0,0,1,-1,1,-1,1,-1};
  auto in=[&](int y,int x){return 0<=y&&y<h&&0<=x&&x<w;};

  while(!q.empty()){
    int y,x;
    tie(y,x)=q.front();q.pop_front();
    for(int k=0;k<dir;k++){
      int ny=y+dy[k],nx=x+dx[k];
      if(!in(ny,nx)) continue;
      int nd=dp[y][x]+(s[ny][nx]==wall);
      if(~dp[ny][nx]&&dp[ny][nx]<=nd) continue;
      dp[ny][nx]=nd;
      if(s[ny][nx]=='#'){
        q.emplace_back(ny,nx);
      }else{
        q.emplace_front(ny,nx);
      }
    }
  }
  return dp;
}

vector< vector<int> > bfs(vector<string> &s,int sy,int sx,char wall,int dir){
  vector<P> vp;
  vp.emplace_back(sy,sx);
  return bfs(s,vp,wall,dir);
}


//INSERT ABOVE HERE

signed main(){
  int h,w;
  cin>>h>>w;
  vector<string> st(h);
  for(int i=0;i<h;i++) cin>>st[i];

  auto d1=bfs(st,0,0,'#',4);
  int ans=d1[h-1][w-1];

  // find B2
  vector< vector<int> > ex(h,vector<int>(w));
  {
    int flg=0;
    for(int i=0;i<h;i++){
      for(int j=0;j<w;j++) if(st[i][j]=='B') ex[i][j]|=flg;
      for(int j=0;j<w;j++) if(st[i][j]=='B') flg=1;
    }
  }
  {
    int flg=0;
    for(int j=0;j<w;j++){
      for(int i=0;i<h;i++) if(st[i][j]=='B') ex[i][j]|=flg;
      for(int i=0;i<h;i++) if(st[i][j]=='B') flg=1;
    }
  }

  // use B2
  for(int i=0;i<h;i++)
    for(int j=0;j<w;j++)
      if(ex[i][j]) chmin(ans,d1[i][j]);

  // find B1
  int by=-1,bx=-1;
  for(int i=0;i<h;i++)
    for(int j=0;j<w;j++)
      if(st[i][j]=='B'&&!ex[i][j]) by=i,bx=j;

  if(~by){
    // dist from B1
    auto d2=bfs(st,by,bx,'#',4);

    // dist to (i, j) with B1
    vector< vector<int> > d3(h,vector<int>(w));
    for(int i=0;i<h;i++)
      for(int j=0;j<w;j++)
        d3[i][j]=d1[i][j]+d2[i][j]-(st[i][j]=='#');

    vector< queue<P> > qs((h+w)*2);
    for(int i=0;i<h;i++)
      for(int j=0;j<w;j++)
        qs[d3[i][j]].emplace(i,j);

    int dy[]={1,-1,0,0,1,1,-1,-1};
    int dx[]={0,0,1,-1,1,-1,1,-1};
    auto in=[&](int y,int x){return 0<=y&&y<h&&0<=x&&x<w;};
    for(int d=0;d+1<(int)qs.size();d++){
      while(!qs[d].empty()){
        int y,x;
        tie(y,x)=qs[d].front();qs[d].pop();
        if(d3[y][x]!=d) continue;
        for(int k=0;k<4;k++){
          int ny=y+dy[k],nx=x+dx[k];
          if(!in(ny,nx)) continue;
          int nd=d3[y][x]+(st[ny][nx]=='#');
          if(d3[ny][nx]<=nd) continue;
          d3[ny][nx]=nd;
          qs[nd].emplace(ny,nx);
        }
      }
    }

    // dist from B2 and goal
    vector<P> vp;
    for(int i=0;i<h;i++)
      for(int j=0;j<w;j++)
        if(ex[i][j]) vp.emplace_back(i,j);
    vp.emplace_back(h-1,w-1);
    auto d4=bfs(st,vp,'#',4);

    // use B1, take B2 and use
    for(int i=0;i<h;i++){
      for(int j=0;j<w;j++){
        int res=d3[i][j];
        for(int k=0;k<i;k++) chmin(res,d3[k][j]);
        for(int k=0;k<j;k++) chmin(res,d3[i][k]);
        chmin(ans,(d4[i][j]-(st[i][j]=='#'))+res);
      }
    }
  }

  cout<<ans<<endl;
  return 0;
}
accuracy: 1
time_ms: 1000
memory_kb: 30704
final_rank: 3