Problem:
Remodeling the Dungeon
The Queen of Icpca resides in a castle peacefully. One day, she heard that many secret agents had been active in other nations, and got worried about the security of the castle.
The castle has a rectangular dungeon consisting of h rows of w square rooms. Adjacent rooms are separated by a wall. Some walls have doorways making the separated rooms intercommunicate. The entrance and the exit of the dungeon are in the rooms located at two diagonal extreme corners. The dungeon rooms form a tree, that is, the exit room is reachable from every room in the dungeon through a unique route that passes all the rooms on the route only once.
In order to enhance the security of the castle, the Queen wants to remodel the dungeon so that the number of rooms on the route from the entrance room to the exit room is maximized. She likes the tree property of the current dungeon, so it must be preserved. Due to the cost limitation, what can be done in the remodeling is to block one doorway to make it unavailable and to construct one new doorway instead on a wall (possibly on the same wall).
Your mission is to find a way to remodel the dungeon as the Queen wants.
Input
The input consists of a single test case in the following format.
$h$ $w$
$c_{1,1}c_{1,2}$ ... $c_{1,2w+1}$
$c_{2,1}c_{2,2}$ ... $c_{2,2w+1}$
.
.
.
$c_{2h+1,1}c_{2h+1,2}$ ... $c_{2h+1,2w+1}$
$h$ and $w$ represent the size of the dungeon, each of which is an integer between $2$ and $500$, inclusive. The characters $c_{i,j}$ ($1 \leq i \leq 2h + 1, 1 \leq j \leq 2w + 1$) represent the configuration of the dungeon as follows:
$c_{2i,2j} =$ '
.
' for $1 \leq i \leq h$ and $1 \leq j \leq w$, which corresponds to the room $i$-th from the north end and $j$-th from the west end of the dungeon; such a room is called the room ($i, j$).
$c_{2i+1,2j} =$ '
.
' or '
-
' for $1 \leq i \leq h − 1$ and $1 \leq j \leq w$, which represents the wall between the rooms ($i, j$) and ($i + 1, j$); the character '
.
' means that the wall has a doorway and '
-
' means it has no doorway.
$c_{2i,2j+1} =$ '
.
' or '
|
' for $1 \leq i \leq h$ and $1 \leq j \leq w − 1$, which represents the wall between the rooms ($i, j$) and ($i, j + 1$); the character '
.
' means that the wall has a doorway and '
|
' means it has no doorway.
$c_{1,2j} = c_{2h+1,2j} =$ '
-
' ($1 \leq j \leq w$) and $c_{2i,1} = c_{2i,2w+1} =$ '
|
' ($1 \leq i \leq h$), which correspond to the outer walls of the dungeon.
$c_{2i+1,2j+1} =$ '
+
' for $0 \leq i \leq h$ and $0 \leq j \leq w$, which corresponds to an intersection of walls or outer walls.
The entrance and the exit of the dungeon are in the rooms (1, 1) and ($h, w$), respectively. The
configuration satisfies the tree property stated above.
Output
Output the maximum length of the route from the entrance room to the exit room achievable by the remodeling, where the length of a route is the number of rooms passed including both the entrance and exit rooms.
Sample Input 1
2 3
+-+-+-+
|.....|

...(truncated)

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using lint = long long;
using ll = long long;
#define rep(i, n) for(int i = 0; i < (n); ++i)
#define all(x) (x).begin(), (x).end()

template<class T1, class T2>
bool chmin(T1 &a, T2 b) {
    if(b < a) {
        a = b;
        return true;
    }
    return false;
}

vector<int> dy={0,-1,0,1};
vector<int> dx={1,0,-1,0};

int main() {
    int h,w;
    cin>>h>>w;
    vector<vector<char>> s(h*2+1,vector<char>(w*2+1));


    rep(i,h*2+1){
        rep(j,w*2+1){
            cin>>s[i][j];
        }
    }

    vector<vector<int>> g(h*w);
    vector<int> df = {1,-w,-1,w};
    rep(i,h){
        rep(j,w){
            int y= i*2+1;
            int x = j*2+1;
            int id = i*w+j;
            rep(k,4){
                int wy = y+dy[k];
                int wx = x+dx[k];
                if(s[wy][wx]=='.'){
                    int nid=id+df[k];
                    g[id].emplace_back(nid);
                }
            }
        }
    }

    int n =h*w;
    vector<int> dists(n,-1);
    dists[0]=1;
    queue<int> q;
    q.push(0);
    while(!q.empty()){
        int cur=q.front();
        q.pop();
        for(auto nex:g[cur]){
            if(dists[nex]==-1){
                q.push(nex);
                dists[nex]=dists[cur]+1;
            }
        }
    }

    vector<int> distg(n,-1);
    distg[n-1]=1;
    q.push(n-1);
    while(!q.empty()){
        int cur=q.front();
        q.pop();
        for(auto nex:g[cur]){
            if(distg[nex]==-1){
                q.push(nex);
                distg[nex]=distg[cur]+1;
            }
        }
    }


    int res=dists[n-1];
     rep(i,h){
        rep(j,w){
            int y= i*2+1;
            int x = j*2+1;
            int id = i*w+j;
            rep(k,4){
                int wy = y+dy[k];
                int wx = x+dx[k];
                if(wy==0 or wx==0 or wy==h*2 or wx==w*2) continue;
                if(s[wy][wx]!='.'){
                    int nid=id+df[k];
                    if(nid<0 or n<=nid) continue;
                    if(dists[id]+distg[nid]==distg[id]+dists[nid]) continue;
                    int ndist = min(dists[id]+distg[nid],distg[id]+dists[nid]);
                    if(res<ndist){
                        res=ndist;
                    }
                }
            }
        }
    }

    cout<<res<<"\n";
            




}
accuracy: 1
time_ms: 50
memory_kb: 20020
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using a2 = array<ll, 2>;
using a3 = array<ll, 3>;

bool chmin(auto& a, const auto& b) { return a > b ? a = b, 1 : 0; }
bool chmax(auto& a, const auto& b) { return a < b ? a = b, 1 : 0; }

const ll INF = 1e18;
ll mod = 998244353;

ifstream in;
ofstream out;

int main(int argc, char** argv) {
    ios::sync_with_stdio(false);
    cin.tie(0);

    if (argc > 2) {
        in.open(argv[1]);
        cin.rdbuf(in.rdbuf());
        out.open(argv[2]);
        cout.rdbuf(out.rdbuf());
    }

    ll h, w;
    cin >> h >> w;
    vector<string> s(2 * h + 1);
    for (auto& x : s) cin >> x;
    vector<vector<ll>> g(h * w);

    vector<a2> wasd = {
        {0, 1},
        {1, 0},
        {0, -1},
        {-1, 0},
    };
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            ll p = 2 * i + 1, q = 2 * j + 1;
            for (auto [x, y] : wasd) {
                if (s[p + x][q + y] == '.')
                    g[i * w + j].push_back((i + x) * w + (j + y));
            }
        }
    }

    vector<ll> dists(h * w, INF), distg(h * w, INF);
    queue<ll> que;
    que.push(0);
    dists[0] = 0;
    while (que.size()) {
        auto f = que.front();
        que.pop();
        for (auto& x : g[f]) {
            if (chmin(dists[x], dists[f] + 1)) {
                que.push(x);
            }
        }
    }

    que.push(h * w - 1);
    distg[h * w - 1] = 0;
    while (que.size()) {
        auto f = que.front();
        que.pop();
        for (auto& x : g[f]) {
            if (chmin(distg[x], distg[f] + 1)) {
                que.push(x);
            }
        }
    }

    ll ans = 0;
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            for (auto [x, y] : wasd) {
                ll p = i + x, q = j + y;
                if (p < 0 || p >= h || q < 0 || q >= w)
                    continue;
                if (dists[i * w + j] + distg[p * w + q] == distg[i * w + j] + dists[p * w + q])
                    continue;
                ll mn = min(dists[i * w + j] + distg[p * w + q], distg[i * w + j] + dists[p * w + q]);
                chmax(ans, mn + 2);
            }
        }
    }
    cout << ans << endl;

    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 23056
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using a2 = array<ll, 2>;
using a3 = array<ll, 3>;

bool chmin(auto& a, const auto& b) { return a > b ? a = b, 1 : 0; }
bool chmax(auto& a, const auto& b) { return a < b ? a = b, 1 : 0; }

const ll INF = 1e18;
ll mod = 998244353;

ifstream in;
ofstream out;

int main(int argc, char** argv) {
    ios::sync_with_stdio(false);
    cin.tie(0);

    if (argc > 2) {
        in.open(argv[1]);
        cin.rdbuf(in.rdbuf());
        out.open(argv[2]);
        cout.rdbuf(out.rdbuf());
    }

    ll h, w;
    cin >> h >> w;
    vector<string> s(2 * h + 1);
    for (auto& x : s) cin >> x;
    vector<vector<ll>> g(h * w);

    vector<a2> wasd = {
        {0, 1},
        {1, 0},
        {0, -1},
        {-1, 0},
    };
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            ll p = 2 * i + 1, q = 2 * j + 1;
            for (auto [x, y] : wasd) {
                if (s[p + x][q + y] == '.')
                    g[i * w + j].push_back((i + x) * w + (j + y));
            }
        }
    }

    vector<ll> dists(h * w, INF), distg(h * w, INF);
    queue<ll> que;
    que.push(0);
    dists[0] = 0;
    while (que.size()) {
        auto f = que.front();
        que.pop();
        for (auto& x : g[f]) {
            if (x == h * w - 1)
                continue;
            if (chmin(dists[x], dists[f] + 1)) {
                que.push(x);
            }
        }
    }

    que.push(h * w - 1);
    distg[h * w - 1] = 0;
    while (que.size()) {
        auto f = que.front();
        que.pop();
        for (auto& x : g[f]) {
            if (x == 0)
                continue;
            if (chmin(distg[x], distg[f] + 1)) {
                que.push(x);
            }
        }
    }

    ll ans = 0;
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            for (auto [x, y] : wasd) {
                ll p = i + x, q = j + y;
                if (p < 0 || p >= h || q < 0 || q >= w)
                    continue;
                if (dists[i * w + j] == INF || distg[p * w + q] == INF)
                    continue;
                if (dists[i * w + j] + distg[p * w + q] == distg[i * w + j] + dists[p * w + q])
                    continue;
                ll mn = min(dists[i * w + j] + distg[p * w + q], distg[i * w + j] + dists[p * w + q]);
                chmax(ans, mn + 2);
            }
        }
    }
    cout << ans << endl;

    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 23056
final_rank: 5

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

using ll = long long;
#define rep(i, a, b) for (int i = a; i < (b); ++i)
#define sz(x) (int)(x).size()
#define all(x) x.begin(), x.end()
typedef pair<int, int> pii;
typedef vector<int> vi;
template <class T>
inline bool chmin(T &a, T b) {
  return ((a > b) ? (a = b, 1) : (0));
}
template <class T>
inline bool chmax(T &a, T b) {
  return ((a < b) ? (a = b, 1) : (0));
}
#define YesNo(f) cout << (f ? "Yes" : "No") << endl

void solve();
int main() {
  int T = 1;
  // cin >> T;
  while (T--) solve();
  return 0;
}

int H,W;
int cell(int i,int j){
    return i*W+j;
}
void solve() {  // solver      
    cin >> H >> W;
    vector<string> S(2*H+1);
    //????? rep(i,0,2*H+1)rep(j,0,2*W+1)cin>>S[i][j];
    rep(i,0,2*H+1)cin>>S[i];
    vi dp(H*W,-1e7),ep(H*W,-1e7);
    vector<vi>G(H*W);
    for(int i=1;i<2*H+1;i+=2){
        for(int j=1;j<2*W+1;j+=2){
            if(S[i][j+1]=='.'){
                G[cell(i/2,(j+2)/2)].push_back(cell(i/2,j/2));
                G[cell(i/2,j/2)].push_back(cell(i/2,(j+2)/2));
            }
            if((S[i+1][j]=='.')){
                G[cell((i+2)/2,j/2)].push_back(cell(i/2,j/2));
                G[cell(i/2,j/2)].push_back(cell((i+2)/2,j/2));
            }
        }
    }
    auto dfs=[&](auto dfs,int v,int p, int d)->void{
        dp[v]=d;
        for(auto to:G[v]){
            if(to==p)continue;
            dfs(dfs,to,v,d+1);
        }
    };    

    auto efs=[&](auto efs,int v,int p, int d)->void{
        ep[v]=d;
        for(auto to:G[v]){
            if(to==p)continue;
            efs(efs,to,v,d+1);
        }
    };    

    int ans=0;
    rep(step,0,2){
        if(step==1)continue;
        dp=vi(H*W,-1e7);
        ep=vi(H*W,-1e7);
        if(step==0){
            dfs(dfs,cell(0,0),-1,0);
            efs(efs,cell(H-1,W-1),-1,0);
            chmax(ans,ep[cell(0,0)]+1);
        }else{
            dfs(dfs,cell(H-1,0),-1,0);
            efs(efs,cell(0,W-1),-1,0);
            chmax(ans,ep[cell(H-1,0)]+1);
        }
    rep(i,0,H)rep(j,0,W){
        rep(di,0,2)rep(dj,0,2){
            if(i+di>=H||j+dj>=W)continue;
            if(di==dj)continue;
            int gi=2*i+1,gj=2*j+1;
            if(S[gi+di][gj+dj]=='.')continue;
            int a=dp[cell(i,j)]+ep[cell(i+di,j+dj)];
            int b=ep[cell(i,j)]+dp[cell(i+di,j+dj)];
            if(a==b)continue;
            chmax(ans,min(a,b)+2);            
        }
    }
}
    cout<<ans<<endl;
  return;
}

/*
端の部屋は全部出口だと思ってました。
(0,0) と (h-1,w-1)が出口入口ですよ。

*/
accuracy: 1
time_ms: 30
memory_kb: 27488
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define vi vector<int>
#define vl vector<ll>
#define vii vector<pair<int,int>>
#define vll vector<pair<ll,ll>>
#define vvi vector<vector<int>>
#define vvl vector<vector<ll>>
#define vvii vector<vector<pair<int,int>>>
#define vvll vector<vector<pair<ll,ll>>>
#define vst vector<string>
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define mkunique(x) sort(all(x));(x).erase(unique(all(x)),(x).end())
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=998244353,MAX=505,INF=15<<26;

int dis[2][MAX][MAX];
vi dh={0,1,0,-1},dw={1,0,-1,0};
bool G[MAX][MAX][4];
pii ro[MAX][MAX];

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    int H,W;cin>>H>>W;
    vst S(2*H+1);
    for(int i=0;i<2*H+1;i++){
        cin>>S[i];
    }
    
    for(int i=0;i<H;i++){
        for(int j=0;j<W;j++){
            if(i+1<H&&S[2*i+2][2*j+1]=='.'){
                G[i][j][1]=G[i+1][j][3]=1;
            }
            if(j+1<W&&S[2*i+1][2*j+2]=='.'){
                G[i][j][0]=G[i][j+1][2]=1;
            }
        }
    }
    
    for(int q=0;q<2;q++){
        queue<pii> Q;
        for(int i=0;i<H;i++){
            for(int j=0;j<W;j++){
                dis[q][i][j]=INF;
            }
        }
        if(q==0){
            Q.push(mp(0,0));
            dis[q][0][0]=0;
        }else{
            Q.push(mp(H-1,W-1));
            dis[q][H-1][W-1]=0;
        }
        
        while(!Q.empty()){
            auto [h,w]=Q.front();Q.pop();
            for(int k=0;k<4;k++){
                int toh=h+dh[k],tow=w+dw[k];
                if(toh<0||toh>=H||tow<0||tow>=W) continue;
                if(!G[h][w][k]) continue;
                if(chmin(dis[q][toh][tow],dis[q][h][w]+1)) Q.push(mp(toh,tow));
            }
        }
    }
    
    queue<pii> Q;
    for(int i=0;i<H;i++){
        for(int j=0;j<W;j++){
            ro[i][j]=mp(-1,-1);
            if(dis[0][i][j]+dis[1][i][j]==dis[0][H-1][W-1]){
                ro[i][j]=mp(i,j);
                Q.push(mp(i,j));
            }
        }
    }
    
    while(!Q.empty()){
        auto [h,w]=Q.front();Q.pop();
        for(int k=0;k<4;k++){
            int toh=h+dh[k],tow=w+dw[k];
            if(toh<0||toh>=H||tow<0||tow>=W) continue;
            if(!G[h][w][k]) continue;
            if(ro[toh][tow].fi==-1){
                ro[toh][tow]=ro[h][w];
                Q.push(mp(toh,tow));
            }
        }
    }
    
    int ans=dis[0][H-1][W-1];
    
    for(int i=0;i<H;i++){
        for(int j=0;j<W;j++){
            if(i+1<H&&S[2*i+2][2*j+1]=='-'&&ro[i][j]!=ro[i+1][j]){
                int mi=min(dis[0][i][j]+dis[1][i+1][j],dis[0][i+1][j]+dis[1][i][j]);
                chmax(ans,mi+1);
            }
            if(j+1<W&&S[2*i+1][2*j+2]=='|'&&ro[i][j]!=ro[i][j+1]){
                int mi=min(dis[0][i][j]+dis[1][i][j+1],dis[0][i][j+1]+dis[1][i][j]);
                chmax(ans,mi+1);
            }
            //cout<<i<<" "<<j<<" "<<ans<<endl;
        }
    }
    cout<<ans+1<<endl;
}
accuracy: 1
time_ms: 20
memory_kb: 10280
final_rank: 2

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

using ll = long long;

bool chmin(auto &a, auto b) { return a > b ? a = b, true : false; }
bool chmax(auto &a, auto b) { return a < b ? a = b, true : false; }

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int H, W;
    cin >> H >> W;
    vector<string> S(2 * H + 1);
    for(string &s : S) cin >> s;

    vector<vector<int>> G(H * W);
    for(int i = 0; i < 2 * H + 1; i += 1) {
        for(int j = ~i & 1; j < 2 * W + 1; j += 2) {
            if(S[i][j] == '.') {
                int p, q;
                if(~i & 1) {
                    p = W * ((i - 1) / 2) + (j / 2);
                    q = W * ((i + 1) / 2) + (j / 2);
                }else {
                    p = W * (i / 2) + ((j - 1) / 2);
                    q = W * (i / 2) + ((j + 1) / 2);
                }
                G[p].push_back(q);
                G[q].push_back(p);
            }
        }
    }

    auto dfs = [&](auto dfs, int u, int p, vector<int> &d) -> void {
        for(int v : G[u]) {
            if(v != p) {
                d[v] = d[u] + 1;
                dfs(dfs, v, u, d);
            }
        }
    };

    vector<int> d1(H * W), dn(H * W);
    d1[0] = dn[H * W - 1] = 1;
    dfs(dfs, 0, -1, d1);
    dfs(dfs, H * W - 1, -1, dn);

    auto dfs2 = [&](auto dfs2, int u, int p, vector<int> &path) -> void {
        if(u == H * W - 1) {
            const int K = path.size();
            map<int, int> mp;
            vector<int> vl(K), vr(K), ID(H * W);
            for(int i = 0; i < K; i++) mp[path[i]] = i;
            auto dfs3 = [&](auto dfs3, int x, int y, int id) -> void {
                ID[x] = id;
                chmax(vl[id], d1[x]);
                chmax(vr[id], dn[x]);
                for(int z : G[x]) {
                    if(z != y && !mp.count(z)) dfs3(dfs3, z, x, id); 
                }
            };
            for(int i = 0; i < K; i++) dfs3(dfs3, path[i], -1, i);
            int ans = 0;
            for(int i = 0; i < 2 * H + 1; i += 1) {
                for(int j = ~i & 1; j < 2 * W + 1; j += 2) {
                    if(0 < i && i < 2 * H && 0 < j && j < 2 * W) {
                        int p, q;
                        if(~i & 1) {
                            p = W * ((i - 1) / 2) + (j / 2);
                            q = W * ((i + 1) / 2) + (j / 2);
                        }else {
                            p = W * (i / 2) + ((j - 1) / 2);
                            q = W * (i / 2) + ((j + 1) / 2);
                        }
                        // cout << ID[p]
                        if(ID[p] < ID[q]) chmax(ans, d1[p] + dn[q]);
                        if(ID[p] > ID[q]) chmax(ans, dn[p] + d1[q]);
                    }
                }
            }
            cout << ans << endl;
        }else {
            for(int v : G[u]) {
                if(v != p) {
                    path.push_back(v);
                    dfs2(dfs2, v, u, path);
                    path.pop_back();
                }
            }
        }
    };

    vector<int> path = {0};
    dfs2(dfs2, 0, -1, path);
}
accuracy: 1
time_ms: 90
memory_kb: 129280
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define rep(i,N) for(i=0;i<N;i++)
#define ll long long

int main(void){
    int h, w;
    cin >> h >> w;
    vector<string> S(h * 2 + 1);
    for(int i = 0; i < h * 2 + 1; ++i) cin >> S[i];
    int dx[4] = {-1, 0, 1, 0};
    int dy[4] = {0, -1, 0, 1};
    vector<vector<array<bool, 4>>> isPassed(h, vector<array<bool, 4>>(w));
    for(int i = 0; i < h; i++){
        for(int j = 0; j < w; j++){
            for(int dir = 0; dir < 4; dir++){
                isPassed[i][j][dir] = false;
            }
        }
    }

    for(int x = 0; x < h; x++){
        for(int y = 0; y < w; y++){
            for(int dir = 0; dir < 4; ++dir){
                int nx = x + dx[dir];
                int ny = y + dy[dir];
                if(nx < 0 || ny < 0 || nx >= h || ny >= w) continue;
                int midX = ((x * 2 + 1) + (nx * 2 + 1)) / 2;
                int midY = ((y * 2 + 1) + (ny * 2 + 1)) / 2;
                if(S[midX][midY] != '.') continue;
                isPassed[x][y][dir] = true;
            }
        }
    }

    vector<vector<int>> distA(h, vector<int>(w, -1));
    vector<vector<int>> distB(h, vector<int>(w, -1));

    {
        queue<pair<int, int>> que;
        que.push({0, 0});
        distA[0][0] = 1;
        while(!que.empty()){
            auto [x, y] = que.front();
            que.pop();
            for(int dir = 0; dir < 4; dir++){
                if(!isPassed[x][y][dir]) continue;
                int nx = x + dx[dir];
                int ny = y + dy[dir];
                if(distA[nx][ny] != -1) continue;
                distA[nx][ny] = distA[x][y] + 1;
                que.push({nx, ny});
            }
        }
    }

    {
        queue<pair<int, int>> que;
        que.push({h-1, w-1});
        distB[h-1][w-1] = 1;
        while(!que.empty()){
            auto [x, y] = que.front();
            que.pop();
            for(int dir = 0; dir < 4; dir++){
                if(!isPassed[x][y][dir]) continue;
                int nx = x + dx[dir];
                int ny = y + dy[dir];
                if(distB[nx][ny] != -1) continue;
                distB[nx][ny] = distB[x][y] + 1;
                que.push({nx, ny});
            }
        }
    }

    vector<vector<int>> parent(h, vector<int>(w, -1));
    vector<pair<int, int>> path;
    {
        vector<vector<int>> dist(h, vector<int>(w, -1));
        function<void(int, int)> dfs = [&](int x, int y) {
            for(int dir = 0; dir < 4; dir++){
                int nx = x + dx[dir];
                int ny = y + dy[dir];
                if(nx < 0 || ny < 0 || nx >= h || ny >= w) continue;
                if(!isPassed[x][y][dir]) continue;
                if(dist[nx][ny] == -1) {
                    dist[nx][ny] = dist[x][y] + 1;
                    dfs(nx, ny);
                }
            }
        };
        dist[0][0] = 0;
        dfs(0, 0);
        int cx = h - 1, cy = w - 1;
        while(cx != 0 || cy != 0){
            for(int dir = 0; dir < 4; dir++){
                int nx = cx + dx[dir];
                int ny = cy + dy[dir];
                if(nx < 0 || ny < 0 || nx >= h || ny >= w) continue;
                if(!isPassed[nx][ny][(dir + 2) % 4]) continue;
                if(dist[nx][ny] + 1 == dist[cx][cy]){
                    path.push_back({cx, cy});
                    cx = nx;
                    cy = ny;
                    break;
                }
            }
        }
        path.push_back({0, 0});
        reverse(path.begin(), path.end());
    }

    {
        vector<vector<bool>> visited(h, vector<bool>(w, false));
        for(auto [px, py] : path){
            visited[px][py] = true;
        }
        function<void(int, int, int)> dfs = [&](int x, int y, int pr) {
            visited[x][y] = true;
            parent[x][y] = pr;
            for(int dir = 0; dir < 4; dir++){
                int nx = x + dx[dir];
                int ny = y + dy[dir];
                if(nx < 0 || ny < 0 || nx >= h || ny >= w) continue;
                if(!isPassed[x][y][dir]) continue;
                if(visited[nx][ny]) continue;
                dfs(nx, ny, pr);
            }
        };
        for(int idx = 0; idx < (int)path.size(); idx++){
            auto [px, py] = path[idx];
            dfs(px, py, idx);
        }
    }

    int ans = distA[h-1][w-1];
    for (int x = 0; x < h; x++){
        for (int y = 0; y < w; y++){
            for (int dir = 0; dir < 4; dir++){
                if(isPassed[x][y][dir]) continue;
                int nx = x + dx[dir];
                int ny = y + dy[dir];
                if(nx < 0 || ny < 0 || nx >= h || ny >= w) continue;
                if(parent[x][y] == parent[nx][ny]) continue;
                if(parent[x][y]< parent[nx][ny]){
                    ans = max(ans, distA[x][y] + distB[nx][ny]);
                }else{
                    ans = max(ans, distA[nx][ny] + distB[x][y]);
                }
            }
        }
    }

    cout << ans << endl;

    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 30408
final_rank: 13

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

using ll = long long;

bool chmin(auto &a, auto b) { return a > b ? a = b, 1 : 0; }
bool chmax(auto &a, auto b) { return a < b ? a = b, 1 : 0; }

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int H, W; cin >> H >> W;
    vector<string> C(2*H + 1);
    for(int i=0; i<=2*H; ++i) cin >> C[i];

    vector G(H, vector(W, vector<pair<int,int>>()));
    for(int i=1; i<2*H; ++i) {
        if(i % 2) {
            for(int j=2; j<2*W; j+=2) {
                if(C[i][j] == '.') {
                    G[i/2][(j-1)/2].push_back({i/2, j/2});
                    G[i/2][j/2].push_back({i/2, (j-1)/2});
                }
            }
        } else {
            for(int j=1; j<2*W; j+=2) {
                if(C[i][j] == '.') {
                    G[(i-1)/2][j/2].push_back({i/2, j/2});
                    G[i/2][j/2].push_back({(i-1)/2, j/2});
                }
            }
        }
    }

    const vector<int> di = {-1, 1, 0, 0}, dj = {0, 0, -1, 1};
    vector dist1(H, vector<int>(W, -1)), dist2(H, vector<int>(W, -1));
    queue<pair<int,int>> q;
    dist1[0][0] = 0;
    q.push({0, 0});
    while(!q.empty()) {
        int i, j;
        tie(i, j) = q.front(); q.pop();
        for(int d=0; d<4; ++d) {
            int ni = i + di[d], nj = j + dj[d];
            if(!(0 <= ni && ni < H && 0 <= nj && nj < W)) continue;
            for(auto nex : G[i][j]) {
                if(nex.first != ni || nex.second != nj) continue;
                if(dist1[ni][nj] >= 0) continue;
                dist1[ni][nj] = dist1[i][j] + 1;
                q.push({ni, nj});
            }
        }
    }
    dist2[H-1][W-1] = 0;
    q.push({H-1, W-1});
    while(!q.empty()) {
        int i, j;
        tie(i, j) = q.front(); q.pop();
        for(int d=0; d<4; ++d) {
            int ni = i + di[d], nj = j + dj[d];
            if(!(0 <= ni && ni < H && 0 <= nj && nj < W)) continue;
            for(auto nex : G[i][j]) {
                if(nex.first != ni || nex.second != nj) continue;
                if(dist2[ni][nj] >= 0) continue;
                dist2[ni][nj] = dist2[i][j] + 1;
                q.push({ni, nj});
            }
        }
    }
//    for(int i=0; i<H; ++i) for(int j=0; j<W; ++j) cout << dist1[i][j] << " \n"[j == W-1];
//    cout << '\n';
//    for(int i=0; i<H; ++i) for(int j=0; j<W; ++j) cout << dist2[i][j] << " \n"[j == W-1];
    int ans = dist2[0][0] + 1;
    for(int i=0; i<H; ++i) {
        for(int j=0; j<W; ++j) {
            for(int d=0; d<4; ++d) {
                int ni = i + di[d], nj = j + dj[d];
                if(!(0<=ni && ni<H && 0<=nj && nj<W)) continue;
                // if(dist2[i][j] < dist2[ni][nj]) continue;
                // bool found = false;
                // for(auto nex : G[i][j]) {
                //     if(nex.first == ni && nex.second == nj) {
                //         found = true;
                //         break;
                //     }
                // }
                // if(found) continue;
                if(dist1[i][j] + dist2[ni][nj] != dist1[ni][nj] + dist2[i][j]) {
                    chmax(ans, min(dist1[i][j] + dist2[ni][nj], dist1[ni][nj] + dist2[i][j]) + 2);
                }
            }
        }
    }
    cout << ans << '\n';
}
accuracy: 1
time_ms: 40
memory_kb: 21376
final_rank: 11

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <tuple>
#include <queue>
using namespace std;

using ll = long long;

bool chmin(auto &a, auto b) { return a > b ? a = b, 1 : 0; }
bool chmax(auto &a, auto b) { return a < b ? a = b, 1 : 0; }

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int H, W; cin >> H >> W;
    vector<string> C(2*H + 1);
    for(int i=0; i<=2*H; ++i) cin >> C[i];

    vector G(H, vector(W, vector<pair<int,int>>()));
    for(int i=1; i<2*H; ++i) {
        if(i % 2) {
            for(int j=2; j<2*W; j+=2) {
                if(C[i][j] == '.') {
                    G[i/2][(j-1)/2].push_back({i/2, j/2});
                    G[i/2][j/2].push_back({i/2, (j-1)/2});
                }
            }
        } else {
            for(int j=1; j<2*W; j+=2) {
                if(C[i][j] == '.') {
                    G[(i-1)/2][j/2].push_back({i/2, j/2});
                    G[i/2][j/2].push_back({(i-1)/2, j/2});
                }
            }
        }
    }

    const vector<int> di = {-1, 1, 0, 0}, dj = {0, 0, -1, 1};
    vector dist1(H, vector<int>(W, -1)), dist2(H, vector<int>(W, -1));
    queue<pair<int,int>> q;
    dist1[0][0] = 0;
    q.push({0, 0});
    while(!q.empty()) {
        int i, j;
        tie(i, j) = q.front(); q.pop();
        for(int d=0; d<4; ++d) {
            int ni = i + di[d], nj = j + dj[d];
            if(!(0 <= ni && ni < H && 0 <= nj && nj < W)) continue;
            for(auto nex : G[i][j]) {
                if(nex.first != ni || nex.second != nj) continue;
                if(dist1[ni][nj] >= 0) continue;
                dist1[ni][nj] = dist1[i][j] + 1;
                q.push({ni, nj});
            }
        }
    }
    dist2[H-1][W-1] = 0;
    q.push({H-1, W-1});
    while(!q.empty()) {
        int i, j;
        tie(i, j) = q.front(); q.pop();
        for(int d=0; d<4; ++d) {
            int ni = i + di[d], nj = j + dj[d];
            if(!(0 <= ni && ni < H && 0 <= nj && nj < W)) continue;
            for(auto nex : G[i][j]) {
                if(nex.first != ni || nex.second != nj) continue;
                if(dist2[ni][nj] >= 0) continue;
                dist2[ni][nj] = dist2[i][j] + 1;
                q.push({ni, nj});
            }
        }
    }
//    for(int i=0; i<H; ++i) for(int j=0; j<W; ++j) cout << dist1[i][j] << " \n"[j == W-1];
//    cout << '\n';
//    for(int i=0; i<H; ++i) for(int j=0; j<W; ++j) cout << dist2[i][j] << " \n"[j == W-1];
    int ans = 0;
    for(int i=0; i<H; ++i) {
        for(int j=0; j<W; ++j) {
            for(int d=0; d<4; ++d) {
                int ni = i + di[d], nj = j + dj[d];
                if(!(0<=ni && ni<H && 0<=nj && nj<W)) continue;
                if(dist2[i][j] < dist2[ni][nj]) continue;
                bool found = false;
                for(auto nex : G[i][j]) {
                    if(nex.first == ni && nex.second == nj) {
                        found = true;
                        break;
                    }
                }
                if(found) continue;
                if(dist1[i][j] + dist2[ni][nj] != dist1[ni][nj] + dist2[i][j]) chmax(ans, dist1[i][j] + dist2[ni][nj] + 2);
            }
        }
    }
    cout << ans << '\n';
}
accuracy: 0.02
time_ms: 40
memory_kb: 21376
final_rank: 19

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <tuple>
#include <queue>
using namespace std;

using ll = long long;

bool chmin(auto &a, auto b) { return a > b ? a = b, 1 : 0; }
bool chmax(auto &a, auto b) { return a < b ? a = b, 1 : 0; }

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int H, W; cin >> H >> W;
    vector<string> C(2*H + 1);
    for(int i=0; i<=2*H; ++i) cin >> C[i];

    vector G(H, vector(W, vector<pair<int,int>>()));
    for(int i=1; i<2*H; ++i) {
        if(i % 2) {
            for(int j=2; j<2*W; j+=2) {
                if(C[i][j] == '.') {
                    G[i/2][(j-1)/2].push_back({i/2, j/2});
                    G[i/2][j/2].push_back({i/2, (j-1)/2});
                }
            }
        } else {
            for(int j=1; j<2*W; j+=2) {
                if(C[i][j] == '.') {
                    G[(i-1)/2][j/2].push_back({i/2, j/2});
                    G[i/2][j/2].push_back({(i-1)/2, j/2});
                }
            }
        }
    }

    const vector<int> di = {-1, 1, 0, 0}, dj = {0, 0, -1, 1};
    vector dist1(H, vector<int>(W, -1)), dist2(H, vector<int>(W, -1));
    queue<pair<int,int>> q;
    dist1[0][0] = 0;
    q.push({0, 0});
    while(!q.empty()) {
        int i, j;
        tie(i, j) = q.front(); q.pop();
        for(int d=0; d<4; ++d) {
            int ni = i + di[d], nj = j + dj[d];
            if(!(0 <= ni && ni < H && 0 <= nj && nj < W)) continue;
            for(auto nex : G[i][j]) {
                if(nex.first != ni || nex.second != nj) continue;
                if(dist1[ni][nj] >= 0) continue;
                dist1[ni][nj] = dist1[i][j] + 1;
                q.push({ni, nj});
            }
        }
    }
    dist2[H-1][W-1] = 0;
    q.push({H-1, W-1});
    while(!q.empty()) {
        int i, j;
        tie(i, j) = q.front(); q.pop();
        for(int d=0; d<4; ++d) {
            int ni = i + di[d], nj = j + dj[d];
            if(!(0 <= ni && ni < H && 0 <= nj && nj < W)) continue;
            for(auto nex : G[i][j]) {
                if(nex.first != ni || nex.second != nj) continue;
                if(dist2[ni][nj] >= 0) continue;
                dist2[ni][nj] = dist2[i][j] + 1;
                q.push({ni, nj});
            }
        }
    }
//    for(int i=0; i<H; ++i) for(int j=0; j<W; ++j) cout << dist1[i][j] << " \n"[j == W-1];
//    cout << '\n';
//    for(int i=0; i<H; ++i) for(int j=0; j<W; ++j) cout << dist2[i][j] << " \n"[j == W-1];
    int ans = 0;
    for(int i=0; i<H; ++i) {
        for(int j=0; j<W; ++j) {
            for(int d=0; d<4; ++d) {
                int ni = i + di[d], nj = j + dj[d];
                if(!(0<=ni && ni<H && 0<=nj && nj<W)) continue;
                if(dist2[i][j] < dist2[ni][nj]) continue;
            //    bool found = false;
            //    for(auto nex : G[i][j]) {
            //        if(nex.first == ni && nex.second == nj) {
            //            found = true;
            //            break;
            //        }
            //    }
            //    if(found) continue;
                if(dist1[i][j] + dist2[ni][nj] != dist1[ni][nj] + dist2[i][j]) chmax(ans, dist1[i][j] + dist2[ni][nj] + 2);
            }
        }
    }
    cout << ans << '\n';
}
accuracy: 0.02
time_ms: 40
memory_kb: 21376
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
int h, w;
int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};
constexpr int inf = 1 << 30;

bool check(int x, int y) {
  return 0 <= x && x < 2 * h + 1 && 0 <= y && y < 2 * w + 1;
}

vector<int> calc(const vector<vector<int>>& g, int s) {
  int n = g.size();
  vector<int> dist(n, inf);
  dist[s] = 0;
  queue<int> Q;
  Q.push(s);
  while (!Q.empty()) {
    int v = Q.front();
    Q.pop();
    for (int vv : g[v])
      if (dist[vv] == inf) {
        Q.push(vv);
        dist[vv] = dist[v] + 1;
      }
  }
  return dist;
}

signed main() {
  cin.tie(0)->sync_with_stdio(0);
  cin >> h >> w;
  vector<string> s(2 * h + 1);
  for (auto& e : s) cin >> e;

  auto id = [&](int x, int y) {
    x /= 2, y /= 2;
    return w * x + y;
  };
  vector<vector<int>> g(h * w);
  for (int i = 1; i < 2 * h + 1; i += 2)
    for (int j = 1; j < 2 * w + 1; j += 2) {
      rep(dir, 4) {
        int x = i + dx[dir], y = j + dy[dir];
        if (!(check(x, y) && s[x][y] == '.')) continue;
        x += dx[dir], y += dy[dir];
        g[id(i, j)].emplace_back(id(x, y));
      }
    }
  auto dp = calc(g, 0), ep = calc(g, h * w - 1);
  auto is_adj = [&](int u, int v) -> bool {
    if (!(0 <= u && u < h * w)) return 0;
    if (!(0 <= v && v < h * w)) return 0;
    if (u / w == v / w) {
      return abs(u - v) == 1;
    }
    return abs(u - v) == w;
  };
  int ans = ep[0] + 1;
  rep(i, h * w) {
    for (int d : {-1, 1, -w, w}) {
      int j = i + d;
      if (!is_adj(i, j)) continue;
      if (dp[i] + ep[j] != dp[j] + ep[i])
        ans = max(ans, min(dp[i] + ep[j] + 2, dp[j] + ep[i] + 2));
    }
  }
  cout << ans << endl;
  /*
  rep(i, 2 * h + 1) rep(j, 2 * w + 1) {
    if (i % 2 == 1 && j % 2 == 1)
      cout << dp[w * (i / 2) + (j / 2)];
    else
      cout << s[i][j];
    if (j == 2 * w) cout << '\n';
  }
  rep(i, 2 * h + 1) rep(j, 2 * w + 1) {
    if (i % 2 == 1 && j % 2 == 1)
      cout << ep[w * (i / 2) + (j / 2)];
    else
      cout << s[i][j];
    if (j == 2 * w) cout << '\n';
  }
   */
}
accuracy: 1
time_ms: 30
memory_kb: 20112
final_rank: 4

code_snippet: #include<bits/stdc++.h>
// #include<atcoder/all>
// #include<boost/multiprecision/cpp_int.hpp>

using namespace std;
// using namespace atcoder;
// using bint = boost::multiprecision::cpp_int;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using vi = vector<ll>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using ve = vector<vector<int>>;
using vb = vector<bool>;
using vvb = vector<vb>;
#define rep(i,s,n) for(ll i = (ll)s;i < (ll)n;i++)
#define rrep(i,l,r) for(ll i = r-1;i >= l;i--)
#define ALL(x) (x).begin(),(x).end()
#define sz(c) ((ll)(c).size())
#define LB(A,x) (int)(lower_bound(A.begin(),A.end(),x)-A.begin())
#define UB(A,x) (int)(upper_bound(A.begin(),A.end(),x)-A.begin())
// #define MOD 1000000007
#define MOD 998244353
template<typename T>using min_priority_queue=priority_queue<T,vector<T>,greater<T>>;
template<typename T>ostream&operator<<(ostream&os,vector<T>&v){for(int i = 0;i < v.size();i++)os<<v[i]<<(i+1!=v.size()?" ":"");return os;}
template<typename T>istream&operator>>(istream&is,vector<T>&v){for(T&in:v)is>>in;return is;}
template<typename T1,typename T2>ostream&operator<<(ostream&os,pair<T1,T2>&p){os<<p.first<<" "<<p.second;return os;}
template<typename T1,typename T2>istream&operator>>(istream&is,pair<T1,T2>&p){is>>p.first>>p.second;return is;}
template<typename T> inline bool chmax(T &a,T b){if(a < b){a = b;return true;}return false;}
template<typename T> inline bool chmin(T &a,T b){if(a > b){a = b;return true;}return false;}
ld dist(ld x1,ld y1,ld x2, ld y2){return sqrtl((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}

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

int main(){
  
  ios_base::sync_with_stdio(0), cin.tie(0);
  int h,w;cin >> h >> w;
  vector<string> s(2*h + 1);
  cin >> s;
  auto dist = [&](int S,vi &d){
    d[S] = 1;
    queue<int> que;
    que.push(S);
    while(!que.empty()){
      int ov = que.front();que.pop();
      rep(k,0,4){
        int ny = ov/w + dy[k],nx = ov%w + dx[k];
        if(ny < 0 || ny >= h || nx < 0 || nx >= w)continue;
        if(s[ny + (ov/w)+1][nx + ov%w + 1] != '.')continue;
        if(d[ny*w + nx] != MOD)continue;
        d[ny*w + nx] = d[ov] + 1;
        que.push(ny*w + nx);
      }
    }
  };
  vi d(h*w,MOD),D(h*w,MOD);
  dist(0,d);dist(h*w-1,D);
  ll res = d[h*w-1];
  rep(i,0,h)rep(j,0,w){
    rep(k,0,4){
      int ny = i + dy[k],nx = j + dx[k];
      if(ny < 0 || ny >= h || nx < 0 || nx >= w)continue;
      if(s[ny + i +1][nx + j + 1] != '.' && d[i*w + j] + D[ny*w + nx] != D[i*w + j] + d[ny*w + nx]){
        chmax(res,min(d[i*w + j] + D[ny*w + nx],D[i*w + j] + d[ny*w + nx]));
      }
    }
  }
  cout << res << endl;
  // rep(i,0,h)rep(j,0,w)cout << d[i*w + j] << " \n"[j+1 == w];
  

  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 8100
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = s; i < (int)(t); i++)
#define rrep(i, s, t) for (int i = (ll)(t) - 1; i >= (int)(s); i--)
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)

#define TT template <typename T>
TT using vec = vector<T>;
template <class T1, class T2>
bool chmin(T1 &x, T2 y) { return x > y ? (x = y, true) : false; }
template <class T1, class T2>
bool chmax(T1 &x, T2 y) { return x < y ? (x = y, true) : false; }

struct io_setup {
    io_setup() {
        ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        cout << fixed << setprecision(15);
        srand(time(NULL));
    }
} io_setup;

struct LCA {
    vector<int> d;
    vector<vector<int>> par;
    LCA(int n) {
        d.resize(n);
        par.resize(22, vector<int>(n));
    }
    void dfs(int x, int p, vector<vector<int>> const &g) {
        par[0][x] = p;
        for (auto i : g[x]) {
            if (i == p) continue;
            d[i] = d[x] + 1;
            dfs(i, x, g);
        }
    }
    void set(vector<vector<int>> &g) {
        for (int i = 0; i < (int)par.size() - 1; i++) {
            for (int j = 0; j < (int)g.size(); j++) {
                if (par[i][j] == -1) par[i + 1][j] = -1;
                else par[i + 1][j] = par[i][par[i][j]];
            }
        }
    }
    int get(int u, int v) {
        if (d[u] < d[v]) swap(u, v);
        int n = par.size();
        for (int i = 0; i < n; i++) {
            if ((d[u] - d[v]) >> i & 1) {
                u = par[i][u];
            }
        }
        if (u == v) return u;
        for (int i = n - 1; i >= 0; i--) {
            if (par[i][u] != par[i][v]) {
                u = par[i][u];
                v = par[i][v];
            }
        }
        return par[0][u];
    }
};

void solve(){
    int H, W;
    cin >> H >> W;
    vector<string> S(2 * H  + 1);
    vector<vector<int>> G(H * W);
    rep(i, 0, 2 * H + 1) cin >> S[i];
    vector to_right(H, vector<bool>(W));
    vector to_down(H, vector<bool>(W));
    for (int i = 1; i < 2 * H + 1; i += 2) {
        for (int j = 1; j < 2 * W + 1; j += 2) {
            int x = i / 2, y = j / 2;
            if (i + 2 < 2 * H + 1 && S[i + 1][j] == '.') {
                G[W * x + y].push_back(W * (x + 1) + y);
                G[W * (x + 1) + y].push_back(W * x + y);
                to_down[x][y] = true;
            }
            if (j + 2 < 2 * W + 1 && S[i][j + 1] == '.') {
                G[W * x + y].push_back(W * x + y + 1);
                G[W * x + y + 1].push_back(W * x + y);
                to_right[x][y] = true;
            }
        }
    }
    vector<int> DS(H * W), DT(H * W);
    auto f = [&](int s, vector<int> &d) -> void {
        queue<pair<int, int>> q;
        q.push({s, -1});
        while (q.size()) {
            auto [x, p] = q.front();
            q.pop();
            for (auto i : G[x]) {
                if (i == p) continue;
                d[i] = d[x] + 1;
                q.push({i, x});
            }
        }
    };
    f(0, DS);
    f(H * W - 1, DT);
    assert(DS[H * W - 1] == DT[0]);
    LCA lca(H * W);
    lca.dfs(0, -1, G);
    lca.set(G);
    int ans = DS[H * W - 1] + 1;
    auto g = [&](int a, int b, int c) -> void {
        // s -> b -> a -> t
        {
            int x = lca.get(a, b), y = lca.get(a, c);
            if (x != y && lca.get(x, y) == x) {
                // cout << DS[b] + 1 + DT[a] + 1 << endl;
                chmax(ans, DS[b] + 1 + DT[a] + 1);
            }
        }
        // s -> a -> b -> t
        {
            int x = lca.get(a, b), y = lca.get(b, c);
            if (x != y && lca.get(x, y) == x) {
                // cout << DS[a] + 1 + DT[b] + 1 << endl;
                chmax(ans, DS[a] + 1 + DT[b] + 1);
            }
        }
    };
    for (int i = 0; i < H; i++) {
        for (int j = 0; j < W; j++) {
            if (i + 1 < H && !to_down[i][j]) {
                int a = W * i + j, b = W * (i + 1) + j;
                g(a, b, H * W - 1);
            }
            if (j + 1 < W && !to_right[i][j]) {
                int a = W * i + j, b = W * i + j + 1;
                g(a, b, H * W - 1);
            }
        }
    }
    cout << ans << endl;
}

int main() {
    solve();
}
accuracy: 1
time_ms: 200
memory_kb: 50488
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int h, w;
    cin >> h >> w;
    vector<string> s(h * 2 + 1);
    rep(i, h * 2 + 1) cin >> s[i];
    int n = h * w;
    vector<vector<int>> v(n);
    vector<pair<int, int>> canedges;
    vector<int> path;
    vector<int> dis1(n, 0), dis2(n, 0);
    rep(i, h) rep(j, w) {
        if(i > 0) {
            int x = i * w + j;
            int y = (i - 1) * w + j;
            if(s[i * 2][j * 2 + 1] == '.') {
                v[x].pb(y);
                v[y].pb(x);
            } else canedges.push_back({x, y});
        } 
        if(j > 0) {
            int x = i * w + j;
            int y = i * w + j - 1;
            if(s[i * 2 + 1][j * 2] == '.') {
                v[x].pb(y);
                v[y].pb(x);
            } else canedges.push_back({x, y});
        }
    }
    auto dfs = [&](auto dfs, int now, int p, bool f) -> void {
        foa(e, v[now]) {
            if(e == p) continue;
            if(f) {
                dis1[e] = dis1[now] + 1;
            } else {
                dis2[e] = dis2[now] + 1;
            }
            dfs(dfs, e, now, f);
        }
    };
    dfs(dfs, 0, -1, 1);
    dfs(dfs, n - 1, -1, 0);
    int ans = dis1[n - 1];

    auto dfs1 = [&](auto dfs1, int now, int p) -> bool {
        if(now == n - 1) {
            path.pb(n - 1);
            return true;
        }
        foa(e, v[now]) {
            if(e == p) continue;
            bool ret = dfs1(dfs1, e, now);
            if(ret) {
                path.pb(now);
                return true;
            }
        }
        return false;
    };
    dfs1(dfs1, 0, -1);
    vector<bool> isp(n, 0);
    foa(e, path) isp[e] = 1;
    reverse(all(path));
    int sz = path.size();

    vector<int> anc(n, -1);
    auto dfs2 = [&](auto dfs2, int now, int p) -> void {
        foa(e, v[now]) {
            if(isp[e] or p == e) continue;
            anc[e] = anc[now];
            dfs2(dfs2, e, now);
        }
    };
    rep(i, sz) {
        anc[path[i]] = i;
        dfs2(dfs2, path[i], -1);
    }

    for(auto [x, y] : canedges) {
        rep(_, 2) {
            if(anc[x] < anc[y]) {
                ans = max(ans, dis1[x] + dis2[y] + 1);
            }
            swap(x, y);
        }
    }
    cout << ans + 1 << endl;
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 33352
final_rank: 15

code_snippet: // AOJ #1439 Remodeling the Dungeon
// 2025.3.27

#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;

inline int idx(int i, int j, int w) { return i * w + j; }

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    int h, w;
    cin >> h >> w;
    int H = 2 * h + 1, W = 2 * w + 1;
    vector<string> g(H);
    for (int i = 0; i < H; i++) cin >> g[i];

    int n = h * w;
    vector<vector<int>> adj(n);
    for (int i = 0; i < h; i++){
        for (int j = 0; j < w; j++){
            int u = idx(i, j, w);
            if(j + 1 < w){
                if(g[2*i+1][2*j+2] == '.'){
                    int v = idx(i, j+1, w);
                    adj[u].push_back(v);
                    adj[v].push_back(u);
                }
            }
            if(i + 1 < h){
                if(g[2*i+2][2*j+1] == '.'){
                    int v = idx(i+1, j, w);
                    adj[u].push_back(v);
                    adj[v].push_back(u);
                }
            }
        }
    }

    vector<int> dist(n, INF), par(n, -1);
    queue<int> que;
    int s = idx(0, 0, w), t = idx(h-1, w-1, w);
    dist[s] = 0;
    que.push(s);
    while(!que.empty()){
        int u = que.front(); que.pop();
        for (int v : adj[u]){
            if(dist[v] > dist[u] + 1){
                dist[v] = dist[u] + 1;
                par[v] = u;
                que.push(v);
            }
        }
    }
    vector<int> P;
    for (int cur = t; cur != -1; cur = par[cur]) P.push_back(cur);

    reverse(P.begin(), P.end());
    int L = dist[t] + 1;

    vector<bool> onP(n, false);
    vector<int> pos(n, -1);
    for (int i = 0; i < (int)P.size(); i++){
        onP[P[i]] = true;
        pos[P[i]] = i;
    }

    vector<vector<int>> child(n);
    for (int u = 0; u < n; u++)
        if(par[u] != -1) child[par[u]].push_back(u);

    vector<int> f(n, -1), dd(n, 0);
    function<void(int)> dfs = [&](int u){
        if(onP[u]){
            f[u] = u;
            dd[u] = 0;
        }
        for (int v : child[u]){
            if(onP[v]){
                f[v] = v;
                dd[v] = 0;
            } else {
                f[v] = f[u];
                dd[v] = dd[u] + 1;
            }
            dfs(v);
        }
    };
    dfs(s);

    int ans = L;

    for (int i = 0; i < h; i++){
        for (int j = 0; j < w - 1; j++){
            if(g[2*i+1][2*j+2] == '.') continue;
            int u = idx(i, j, w), v = idx(i, j+1, w);
            int pu = pos[f[u]], pv = pos[f[v]];
            if(pu > pv){
                swap(u, v);
                swap(pu, pv);
            }
            if(pu == pv) continue;
            int cand = L + (dd[u] + dd[v] + 1 - (pv - pu));
            ans = max(ans, cand);
        }
    }

    for (int i = 0; i < h - 1; i++){
        for (int j = 0; j < w; j++){
            if(g[2*i+2][2*j+1] == '.') continue;
            int u = idx(i, j, w), v = idx(i+1, j, w);
            int pu = pos[f[u]], pv = pos[f[v]];
            if(pu > pv){
                swap(u, v);
                swap(pu, pv);
            }
            if(pu == pv) continue;
            int cand = L + (dd[u] + dd[v] + 1 - (pv - pu));
            ans = max(ans, cand);
        }
    }

    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 50168
final_rank: 16

code_snippet: #ifdef NACHIA
#define _GLIBCXX_DEBUG
#endif

#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
#include <queue>
using namespace std;
using ll = long long;
template<class A, class B> void chmax(A& a, const B& b){ if(a < b) a = b; }
template<class A, class B> void chmin(A& a, const B& b){ if(b < a) a = b; }
using PLL = pair<ll, ll>;
#define rep(i,n) for(ll i=0; i<ll(n); i++)

const ll INF = 1001001001001001001;

void testcase(){
    ll H, W; cin >> H >> W;
    auto Idx = [&](ll y, ll x){ return y * W + x; };
    ll N = H * W;
    vector<vector<ll>> adj(N);
    auto addEdge = [&](ll a, ll b){
        adj[a].push_back(b);
        adj[b].push_back(a);
    };
    rep(y,H*2+1){
        string s; cin >> s;
        if(y % 2 == 1){
            rep(x,W-1) if(s[x*2+2] == '.') addEdge(Idx(y/2, x), Idx(y/2,x+1));
        } else {
            rep(x,W) if(s[x*2+1] == '.') addEdge(Idx(y/2-1, x), Idx(y/2,x));
        }
    }
    auto bfs = [&](ll s) -> vector<ll> {
        vector<ll> dist(N, -1);
        dist[s] = 0;
        vector<ll> que; que.push_back(s);
        rep(i,que.size()){
            ll v = que[i];
            for(auto w : adj[v]) if(dist[w] == -1){
                dist[w] = dist[v] + 1;
                que.push_back(w);
            }
        }
        return dist;
    };
    auto d0 = bfs(0);
    auto d1 = bfs(N-1);
    ll ans = d0[N-1] + 1;
    auto check = [&](ll u, ll v){
        if(d0[u] - d1[u] == d0[v] - d1[v]) return;
        chmax(ans, min(d0[u] + 1 + d1[v], d1[u] + 1 + d0[v]) + 1);
    };
    rep(y,H) rep(x,W-1) check(Idx(y,x), Idx(y,x+1));
    rep(y,H-1) rep(x,W) check(Idx(y,x), Idx(y+1,x));
    cout << ans << "\n";
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    #ifdef NACHIA
    ll T; cin >> T; rep(t,T){
    #endif
    testcase();
    
    #ifdef NACHIA
    cout << "---------------------" << endl; }
    #endif
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 25868
final_rank: 8

code_snippet: #ifdef NACHIA
#define _GLIBCXX_DEBUG
#endif

#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
#include <queue>
using namespace std;
using ll = long long;
template<class A, class B> void chmax(A& a, const B& b){ if(a < b) a = b; }
template<class A, class B> void chmin(A& a, const B& b){ if(b < a) a = b; }
using PLL = pair<ll, ll>;
#define rep(i,n) for(ll i=0; i<ll(n); i++)

const ll INF = 1001001001001001001;

void testcase(){
    ll H, W; cin >> H >> W;
    auto Idx = [&](ll y, ll x){ return y * W + x; };
    ll N = H * W;
    vector<vector<ll>> adj(N);
    auto addEdge = [&](ll a, ll b){
        adj[a].push_back(b);
        adj[b].push_back(a);
    };
    rep(y,H*2+1){
        string s; cin >> s;
        if(y % 2 == 1){
            rep(x,W-1) if(s[x*2+2] == '.') addEdge(Idx(y/2, x), Idx(y/2,x+1));
        } else {
            rep(x,W) if(s[x*2+1] == '.') addEdge(Idx(y/2-1, x), Idx(y/2,x));
        }
    }
    auto bfs = [&](ll s) -> vector<ll> {
        vector<ll> dist(N, -1);
        dist[s] = 0;
        vector<ll> que; que.push_back(s);
        rep(i,que.size()){
            ll v = que[i];
            for(auto w : adj[v]) if(dist[w] == -1){
                dist[w] = dist[v] + 1;
                que.push_back(w);
            }
        }
        return dist;
    };
    auto d0 = bfs(0);
    auto d1 = bfs(N-1);
    ll ans = d0[N-1] + 1;
    auto check = [&](ll u, ll v){
        if(d0[u] - d1[u] == d0[v] - d1[v]) return;
        chmax(ans, min(d0[u] + 1 + d1[v], d1[u] + 1 + d0[v]) + 1);
    };
    rep(y,H) rep(x,W-1) check(Idx(y,x), Idx(y,x+1));
    rep(y,H-1) rep(x,W) check(Idx(y,x), Idx(y+1,x));
    cout << ans << "\n";
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    #ifdef NACHIA
    ll T; cin >> T; rep(t,T){
    #endif
    testcase();
    
    #ifdef NACHIA
    cout << "---------------------" << endl; }
    #endif
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 25876
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for(ll i = 0; i < n; i++)

// right | down | left | up
#define DIR_NUM 4
vector<ll> dx = {0, 1, 0, -1};
vector<ll> dy = {1, 0, -1, 0};

inline bool outField(pair<int, int> now, int h, int w) {
  auto &&[x, y] = now;
  if(0 <= x && x < h && 0 <= y && y < w) return false;
  return true;
}

int main() {
  cin.tie(nullptr);
  ios_base::sync_with_stdio(false);

  using T = tuple<ll, ll, ll>;
  using P = pair<ll, ll>;

  ll h, w;
  cin >> h >> w;
  vector<string> s(2 * h + 1);
  rep(i, 2 * h + 1) cin >> s[i];
  vector goable(h, vector(w, vector<bool>(DIR_NUM, false)));
  rep(i, h) rep(j, w) {
    ll now_x = 2 * i + 1;
    ll now_y = 2 * j + 1;
    rep(k, DIR_NUM) {
      ll nx           = now_x + dx[k];
      ll ny           = now_y + dy[k];
      goable[i][j][k] = (s[nx][ny] == '.');
    }
  }
  vector dist1(h, vector<ll>(w, 1e9)), dist2(h, vector<ll>(w, 1e9));
  queue<T> q;
  q.push({0, 0, 0});
  dist1[0][0] = 0;
  while(!q.empty()) {
    auto [dis, x, y] = q.front();
    q.pop();
    rep(k, DIR_NUM) {
      ll nx = x + dx[k];
      ll ny = y + dy[k];
      if(!goable[x][y][k] || dist1[nx][ny] <= dis + 1) continue;
      dist1[nx][ny] = dis + 1;
      q.push({dis + 1, nx, ny});
    }
  }
  q.push({0, h - 1, w - 1});
  dist2[h - 1][w - 1] = 0;
  while(!q.empty()) {
    auto [dis, x, y] = q.front();
    q.pop();
    rep(k, DIR_NUM) {
      ll nx = x + dx[k];
      ll ny = y + dy[k];
      if(!goable[x][y][k] || dist2[nx][ny] <= dis + 1) continue;
      dist2[nx][ny] = dis + 1;
      q.push({dis + 1, nx, ny});
    }
  }
  ll ans = 0;
  rep(i, h) rep(j, w) rep(d, DIR_NUM) {
    ll nx = i + dx[d];
    ll ny = j + dy[d];
    if(outField({nx, ny}, h, w) || dist1[i][j] == 1e9 || dist2[nx][ny] == 1e9 || goable[i][j][d]) continue;
    bool flag = (dist1[i][j] + dist2[nx][ny] == dist1[nx][ny] + dist2[i][j]);
    if(flag) continue;
    ll tmp = min(dist1[i][j] + dist2[nx][ny], dist1[nx][ny] + dist2[i][j]) + 2;
    ans    = max(ans, tmp);
  }
  cout << ans << endl;

  return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 25804
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(ll i=0;i<n;i++)
#define rep2(i,s,t) for(ll i=s;i<t;i++)
#define all(A) A.begin(),A.end()
using ll=long long;

int main(){
    
    cin.tie(nullptr);
    ios::sync_with_stdio(false);


    
    int N,M;
    cin>>N>>M;
    vector<vector<array<int,4>>> G(N,vector<array<int,4>>(M));
    rep(i,N*2+1){
      string S;
      cin>>S;
      rep(j,2*M+1){
        if((i%2==0)&&(j%2==1)&&S[j]=='.'){
          // cout<<i/2<<" "<<j/2<<endl;
          G[i/2-1][j/2][0]=1;
          G[i/2][j/2][2]=1;
        }
        if((i%2==1)&&(j%2==0)&&S[j]=='.'){
          // cout<<i/2<<":"<<j/2<<endl;
          G[i/2][j/2-1][1]=1;
          G[i/2][j/2][3]=1;
        }
      }
    }
    vector<vector<vector<int>>> D(2,vector<vector<int>>(N,vector<int>(M,1e8)));
    vector<int> dx={0,1,0,-1},dy={1,0,-1,0};
    rep(_,2){
      int y=0,x=0;
      if(_==1)y=N-1,x=M-1;
      queue<pair<int,int>> Q;
      Q.push({y,x});
      D[_][y][x]=0;
      while(!Q.empty()){
        auto [h,w]=Q.front();
        Q.pop();
        rep(d,4){
          if(G[h][w][d]){
            int nh=h+dy[d];
            int nw=w+dx[d];
            if(D[_][nh][nw]>D[_][h][w]+1){
              D[_][nh][nw]=D[_][h][w]+1;
              Q.push({nh,nw});
            }
          }
        }
      }
    }  
    int an=D[0][N-1][M-1]+1;
    rep(i,N){
      rep(j,M){
        if(i!=N-1&&G[i][j][0]==0){
            int a=D[0][i][j]+D[1][i+1][j];
            int b=D[0][i+1][j]+D[1][i][j];
            
            if(a!=b)an=max(an,min(a,b)+2);
        }
        if(j!=M-1&&G[i][j][1]==0){
          int a=D[0][i][j]+D[1][i][j+1];
          int b=D[0][i][j+1]+D[1][i][j];
          if(a!=b)an=max(an,min(a,b)+2);
        }
      }
    }
    cout<<an<<endl;
}
accuracy: 1
time_ms: 20
memory_kb: 10104
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,n) for (ll i = 0; i < (ll)(n); i++)
#define rrep(i,start,end) for (ll i = start;i >= (ll)(end);i--)
#define repn(i,end) for(long long i = 0; i <= (long long)(end); i++)
#define reps(i,start,end) for(long long i = start; i < (long long)(end); i++)
#define repsn(i,start,end) for(long long i = start; i <= (long long)(end); i++)
#define each(p,a) for(auto &p:a)
typedef vector<ll> vll;
typedef vector<pair<ll ,ll>> vpll;
typedef vector<vector<ll>> vvll;
typedef pair<ll ,ll> pll;
#define all(a) (a).begin(),(a).end()
#define sz(x) (ll)x.size()
template<class T> bool chmin(T& a, T b){if(a > b){a = b;return true;}return false;}
template<class T> bool chmax(T& a, T b){if(a < b){a = b;return true;}return false;}
using tpl3 = tuple<ll,ll,ll>;
vector<ll> _ta = {0,0,1,-1,1,1,-1,-1};
vector<ll> _yo = {1,-1,0,0,1,-1,1,-1};
bool isin(ll now_i,ll now_j,ll h,ll w){return (0<=now_i && now_i < h && 0 <= now_j && now_j < w);}
ll INF = 1LL << 60;
int main() {
  ll h,w;cin >> h >> w;
  vector<string> s(2  * h + 1);
  rep(i,2 * h+1) {
    cin >> s[i];
  }
  vvll g(h * w);
  auto toid = [&](ll i,ll j) {
    return i * w + j;
  };

  rep(i,h) {
    rep(j,w) {
      ll y = 2 * i + 1;
      ll x = 2 * j + 1;
      rep(k,4) {
        ll ny = y + _ta[k];
        ll nx = x + _yo[k];
        if (s[ny][nx] == '.') {
          g[toid(i,j)].push_back(toid(i+_ta[k],j+_yo[k]));
        }
      }
    }
  }
  vector<ll> ds(h*w,INF),de(h*w,INF);
  {
    queue<ll> que;
    ds[0] = 0;
    que.push(0);
    while (!que.empty()) {
      ll v = que.front();
      que.pop();
      each(p,g[v])if (ds[p] == INF) {
        ds[p] = ds[v] + 1;
        que.push(p);
      }
    }
  }
  {
    queue<ll> que;
    de[toid(h-1,w-1)] = 0;
    que.push(toid(h-1,w-1));
    while (!que.empty()) {
      ll v = que.front();
      que.pop();
      each(p,g[v])if (de[p] == INF) {
        de[p] = de[v] + 1;
        que.push(p);
      }
    }
  }
  ll ans = de[0]-1 ;
  // vll found(h*w,0);
  // set<ll> used;
  // auto clccost = [&](ll id,ll nid) {
  //   return min(ds[id]+de[nid],ds[nid]+de[id]);
  // };
  // auto dfs = [&](auto dfs,ll v)->void {
  //   found[v] = 1;
  //   used.insert(v);
  //   //隣接について見る
  //   ll i = v/w;
  //   ll j = v%w;
  //   ll y = 2 * i + 1;
  //   ll x = 2 * j + 1;
  //   if (i != 0 && s[y-1][x] == '-') {
  //     //上
  //     ll nv = toid(i-1,j);
  //     if (!used.count(nv) ) {
  //       chmax(ans,clccost(v,nv));
  //     }
  //   }
  //   if (i != h-1 && s[y+1][x] == '-') {
  //     ll nv = toid(i+1,j);
  //     if (!used.count(nv)) {
  //
  //     chmax(ans,clccost(v,nv));
  //     }
  //   }
  //   if (j != 0 && s[y][x-1] == '|') {
  //     ll nv = toid(i,j-1);
  //     if (!used.count(nv)) {
  //
  //     chmax(ans,clccost(v,nv));
  //     }
  //   }
  //   if (j != w-1 && s[y][x+1] == '|') {
  //     ll nv = toid(i,j+1);
  //     if (!used.count(nv)) {
  //
  //     chmax(ans,clccost(v,nv));
  //     }
  //   }
  //   each(p,g[v]) {
  //     if (found[p] == 0) {
  //       dfs(dfs,p);
  //     }
  //
  //   }
  //   used.erase(v);
  // };
  // dfs(dfs,0);
  //横で隣接
  rep(i,h) {
    rep(j,w-1) {
      ll y = 2 * i + 1;
      ll x = 2 * j + 1;
      ll id = toid(i,j);
      ll nid = toid(i,j+1);
      if (s[y][x+1] == '|' && ds[nid] - ds[id] != de[nid] - de[id] ) {
        chmax(ans,min(ds[id]+de[nid],ds[nid]+de[id]));
      }
    }
  }
  //縦
  rep(i,h-1) {
    rep(j,w) {
      ll y = 2 * i + 1;
      ll x = 2 * j + 1;
      ll id = toid(i,j);
      ll nid = toid(i+1,j);
      if (s[y+1][x] == '-'  && ds[nid] - ds[id] != de[nid] - de[id]) {
        chmax(ans,min(ds[id]+de[nid],ds[nid]+de[id]));
      }
    }
  }
  cout << ans+2 << endl;


}
accuracy: 1
time_ms: 30
memory_kb: 23864
final_rank: 7