Problem:
Broken Exit
The popular game "Broken Exits" is a puzzle game where the goal is to escape from a maze with the least number of moves. The maze consists of $N \times M$ squares and each square is assigned a row number and a column number. A square with row number $r$ and column number $c$ is denoted by ($r, c$). The top left corner of the square is occupied by square (0, 0) and the bottom right corner is occupied by square ($N-1, M-1$). Each square is assigned one of the following symbols:
.	Ground
E	Exit
#	Wall
In each play of the game, you start from the square designated for each play and try to reach the exit. Each exit can be reached from any square except walls. If the adjacent square above, below, right or left of the square you are in is the ground or an exit, you can move to that square. However, you cannot move to a square without a square.
A maze may contain two or more exits, one of which is broken. Which exit is broken is specified for each play. The play ends when you reach an exit that is not broken. If an exit is broken, you can still move to that exit square, but it does not end the game.
Write a program which reads a maze and the information for each play and outputs the minimum number of moves until each play is completed.
Input
The input is given in the following form.
$N$ $M$
$row_1$
$row_2$
:
$row_N$
$P$
$sr_1$ $sc_1$ $br_1$ $bc_1$
$sr_2$ $sc_2$ $br_2$ $bc_2$
:
$sr_P$ $sc_P$ $br_P$ $bc_P$
In the first line, two integers $N$ ($2 \leq N \leq 1,000$) and $M$ ($2 \leq M \leq 1,000$) are given to represent the size of a maze. A string $row_i$ is given in the next $N$ lines to represent the information of the $i$-th square from the top. $row_i$ is a string of length $M$ and the $j$-th character represents the symbol of square ($i-1,j-1$). In the following line, the number of plays $P$ ($1 \leq P \leq 100,000$) is given. The subsequent $P$ lines give the integers $sr_i$,$sc_i$,$br_i$,$bc_i$ ($0 \leq sr_i,br_i < N, 0 \leq sc_i, bc_i < M$) that represent the starting ground square ($sr_i, sc_i$) and the broken exit square ($br_i, bc_i$) specified in each play.
Output
The output is $P$ rows. Output the minimum number of moves for each play in a line.
Sample Input and Output
Sample Input
4 5
.....
.#.#E
..##.
.E...
3
0 0 3 1
1 2 3 1
1 2 1 4
Sample Output
5
4
7

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll=long long;
struct dat{
	int r,c,cost;
	int root;
};
int main(){
	int N,M;
	cin>>N>>M;
	auto get_place=[&](int a,int b){
		int res=0;
		res+=M*(a-1);
		res+=b;
		return res;
	};
	char S[N+1][M+1];
	for(int i=1;i<=N;i++){
		for(int j=1;j<=M;j++) cin>>S[i][j];
	}
	int goal[N+1][M+1];
	int dist1[N+1][M+1],dist2[N+1][M+1];
	queue<dat>que;
	for(int i=1;i<=N;i++){
		for(int j=1;j<=M;j++){
			goal[i][j]=-1;
			dist1[i][j]=1e9;
			dist2[i][j]=1e9;
			if(S[i][j]=='E'){
				dist1[i][j]=0;
				goal[i][j]=get_place(i,j);
				que.push({i,j,0,goal[i][j]});
			}
		}
	}
	const int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};
	while(!que.empty()){
		int r=que.front().r,c=que.front().c,now_cost=que.front().cost,now_root=que.front().root;
		que.pop();
		for(int k=0;k<4;k++){
			int nr=r+dx[k],nc=c+dy[k];
			if(nr<=0||nr>N||nc<=0||nc>M) continue;
			if(S[nr][nc]=='#') continue;
			if(now_cost+1<dist1[nr][nc]){
				dist1[nr][nc]=now_cost+1;
				goal[nr][nc]=now_root;
				que.push({nr,nc,now_cost+1,now_root});
			}
			else if(now_cost+1<dist2[nr][nc]){
				if(goal[nr][nc]!=now_root){
					dist2[nr][nc]=now_cost+1;
					que.push({nr,nc,now_cost+1,now_root});
				}
			}
		}
	}
	
	
	int P;
	cin>>P;
	for(int z=1;z<=P;z++){
		int sr,sc,br,bc;
		cin>>sr>>sc>>br>>bc;
		sr++;sc++;br++;bc++;
		int break_pos=get_place(br,bc);
		if(goal[sr][sc]==break_pos){
			cout<<dist2[sr][sc]<<endl;
		}
		else{
			cout<<dist1[sr][sc]<<endl;
		}
	}

}
accuracy: 1
time_ms: 170
memory_kb: 32284
final_rank: 6

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

vector<int> di = {0, 1, 0, -1};
vector<int> dj = {1, 0, -1, 0};

int main() {
	cin.tie(nullptr);
	ios_base::sync_with_stdio(false);
	
	int H, W;
	cin >> H >> W;
	vector S(H, vector<char>(W));
	rep(i, 0, H) rep(j, 0, W) cin >> S[i][j];
	
	vector dist(2, vector(H, vector<int>(W, -1)));
	vector exit(2, vector(H, vector<int>(W, -1)));
	
	queue<pair<pair<int, int>, int>> que;
	
	rep(i, 0, H) rep(j, 0, W) {
		if (S[i][j] == 'E') {
			dist[0][i][j] = 0;
			exit[0][i][j] = i*W + j;
			que.push({{i, j}, 0});
		}
	}
	
	while (!que.empty()) {
		int vi = que.front().first.first;
		int vj = que.front().first.second;
		int vk = que.front().second;
		que.pop();
		
		rep(dir, 0, 4) {
			int ni = vi + di[dir];
			int nj = vj + dj[dir];
			if (ni < 0 || H <= ni || nj < 0 || W <= nj) continue;
			if (S[ni][nj] == '#') continue;
			if (dist[1][ni][nj] != -1) continue;
			if (exit[0][ni][nj] == exit[vk][vi][vj]) continue;
			
			if (dist[0][ni][nj] == -1) {
				dist[0][ni][nj] = dist[vk][vi][vj] + 1;
				exit[0][ni][nj] = exit[vk][vi][vj];
				que.push({{ni, nj}, 0});
			} else {
				dist[1][ni][nj] = dist[vk][vi][vj] + 1;
				exit[1][ni][nj] = exit[vk][vi][vj];
				que.push({{ni, nj}, 1});
			}
		}
	}
	
	int Q;
	cin >> Q;
	rep(query, 0, Q) {
		int si, sj, bi, bj;
		cin >> si >> sj >> bi >> bj;
		
		if (exit[0][si][sj] == bi*W + bj) cout << dist[1][si][sj] << '\n';
		else cout << dist[0][si][sj] << '\n';
	}
}
accuracy: 1
time_ms: 80
memory_kb: 32052
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std; 
/*#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/rational.hpp>
using namespace boost::multiprecision;*/
/*#include <atcoder/all>
using namespace atcoder;
using mint = modint;*/
//long long型=int64_tという認識で大丈夫です。
//#define int long long
#define ll long long
#define ull unsigned long long
#define vec vector
#define vi vector<int>
#define vll vector<ll>
#define pq priority_queue
#define pb push_back
#define rep(i, l, r) for(ll i=(ll)(l); i<(ll)(r); i++)
#define ld long double

const ll INF = 2e9;
const ll inf = 5e18;
const ld ep = 1e-15;

struct Edge {
    int to;
    ll cost;
};

struct SEdge {
    int to;
    pair<ll, ll> cost;
};

template<class T>
using spq = priority_queue<T, vec<T>, greater<T>>; 

const vector<ll> di = {-1, 0, 1, 0}, dj = {0, -1, 0, 1};

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;
}

template<class T, class U> 
istream &operator>>(istream &is, pair<T, U> &p) {
    is >> p.first >> p.second;
    return is;
}

template<class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << p.first << " " << p.second;
    return os;
}
template <class T>
istream &operator>>(istream &is, vector<T> &v) {
    for(auto &x : v) {
        is >> x;
    }
    return is;
}

template <class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
    for(int i = 0; i < (int)v.size(); i++) {
        if(i != (int)v.size() - 1)
            os << v[i] << " ";
        else
            os << v[i];
    }
    return os;
}

string strplus(string a, string b) {
    reverse(a.begin(), a.end()); reverse(b.begin(), b.end());
    bool ch = false;
    if(a.size() < b.size()) {
        swap(a, b);
        ch = true;
    }
    string ret;
    int cnt = 0;
    rep(i, 0, a.size()) {
        if(i >= b.size()) {
            ret += (char)(((int)(a[i] - '0') + cnt) % 10 + '0');
            cnt = (((int)(a[i] - '0') + cnt) / 10);
        }
        else {
            ret += (char)(((int)(a[i] - '0' + b[i] - '0') + cnt) % 10 + '0');
            cnt = ((int)(a[i] - '0' + b[i] - '0') + cnt) / 10;
        }
    }
    if(cnt != 0) ret += "1";
    reverse(ret.begin(), ret.end());
    return ret;
}

string strminus(string a, string b) {
    reverse(a.begin(), a.end()); reverse(b.begin(), b.end());
    bool ch = false;
    if(a.size() < b.size()) {
        swap(a, b);
        ch = true;
    }
    else if(a.size() == b.size() && a < b) {
        swap(a, b);
        ch = true;
    }
    string ret;
    int cnt = 0;
    rep(i, 0, a.size()) {
        if(i >= b.size()) {
            ret += (char)(((int)(a[i] - '0') + cnt + 10) % 10 + '0');
            cnt = ((int)(a[i] - '0') + cnt + 10) / 10 - 1;
        }
        else {
            ret += (char)(((int)(a[i] - b[i]) + cnt + 10) % 10 + '0');
            cnt = ((int)(a[i] - b[i]) + cnt + 10) / 10 - 1;
        }
    }
    while(ret[ret.size() - 1] == '0' && ret.size() >= 1) ret.erase(--ret.end());
    if(ret != "0" && ch) ret += '-';
    reverse(ret.begin(), ret.end());
    return ret;
}

template <class T>
bool jf(pair<T, T> a, pair<T, T> b) {
    if(a.second > b.second) return false;
    else return true;
}

using S = ll;

S op(S a, S b){ return max(a, b); }
S e(){ return 0;}
signed main(){
    int n, m; cin >> n >> m;
    vec<string> s(n); rep(i, 0, n) cin >> s[i];
    queue<tuple<int, int, int, int, int>> Q;
    vec<vec<vec<tuple<int, int, int>>>> dist(n, vec<vec<tuple<int, int, int>>>(m, vec<tuple<int, int, int>>(2, {INF, -1, -1})));
    rep(i, 0, n) rep(j, 0, m) if(s[i][j] == 'E') {Q.push({0, i, j, i, j});dist[i][j][0] = {0, i, j};}
    while(!Q.empty()) {
        auto[num, posi, posj, gi, gj] = Q.front(); Q.pop();
        rep(i, 0, 4) {
            int nexi = posi + di[i], nexj = posj + dj[i];
            if(nexi < 0 || nexi >= n || nexj < 0 || nexj >= m) continue;
            if(s[nexi][nexj] == '#') continue;
            if(tuple<int, int, int>{num + 1, gi, gj} < dist[nexi][nexj][0]) {
                dist[nexi][nexj][1] = dist[nexi][nexj][0];
                dist[nexi][nexj][0] = tuple<int, int, int>{num + 1, gi, gj};
                Q.push({num + 1, nexi, nexj, gi, gj});
                continue;
            }
            if(tuple<int, int, int>{num + 1, gi, gj} < dist[nexi][nexj][1]) {
                auto[nexm, nexr, nexc] = dist[nexi][nexj][0];
                if(gi == nexr && gj == nexc) continue;
                dist[nexi][nexj][1] = tuple<int, int, int>{num + 1, gi, gj};
                Q.push({num + 1, nexi, nexj, gi, gj});
            }
        }
    }
    int p; cin >> p;
    rep(i, 0, p) {
        int sr, sc, br, bc; cin >> sr >> sc >> br >> bc;// sr--, sc--, br--, bc--;
        rep(j, 0, 2) {
            auto[ans, gi, gj] = dist[sr][sc][j];
            if(gi == br && gj == bc) continue;
            cout << ans << endl;
            break;
        }
    }
}
accuracy: 1
time_ms: 290
memory_kb: 80296
final_rank: 13

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

#define int long long
signed main(){
    int h,w;
    cin >> h >> w;
    vector<vector<char>> s(h,vector<char>(w));
    priority_queue<pair<pair<int,int>,pair<int,int>>,vector<pair<pair<int,int>,pair<int,int>>>,greater<pair<pair<int,int>,pair<int,int>>>> q;
    vector<vector<int>> x(h,vector<int>(w));
    int now = 0;
    for(int i = 0;i < h;i++){
        string S;
        cin >> S;
        for(int j = 0;j < w;j++){
            s[i][j] = S[j];
            if(s[i][j] == 'E'){
                x[i][j] = now++;
                q.push({{0,x[i][j]},{i,j}});
            }
        }
    }
    vector<vector<vector<pair<int,int>>>> t(h,vector<vector<pair<int,int>>>(w,vector<pair<int,int>>(2,{-1,-1})));
    vector<int> dx = {0,0,1,-1};
    vector<int> dy = {1,-1,0,0};
    while(!q.empty()){
        pair<pair<int,int>,pair<int,int>> it = q.top();
        q.pop();
        if(t[it.second.first][it.second.second][1].first != -1) continue;
        if(t[it.second.first][it.second.second][0].second == it.first.second) continue;
        if(t[it.second.first][it.second.second][0].first== -1){
            t[it.second.first][it.second.second][0].first = it.first.first;
            t[it.second.first][it.second.second][0].second = it.first.second;
        }else{
            t[it.second.first][it.second.second][1].first = it.first.first;
        }
        for(int i = 0;i < 4;i++){
            int ny = it.second.first + dy[i];
            int nx = it.second.second + dx[i];
            if(ny < 0 || ny >= h || nx < 0 || nx >= w) continue;
            if(s[ny][nx] == '#') continue;
            if(t[ny][nx][0].second == it.first.second) continue;
            if(t[ny][nx][1].first != -1) continue;
            q.push({{it.first.first + 1,it.first.second},{ny,nx}});
        }
    }
    int Q;
    cin >> Q;
    for(int i = 0;i < Q;i++){
        int a,b,c,d;
        cin >> a >> b >> c >> d;
        if(t[a][b][0].second == x[c][d]){
            cout << t[a][b][1].first << endl;
        }else{
            cout << t[a][b][0].first << endl;
        }
    }
}
accuracy: 1
time_ms: 850
memory_kb: 214384
final_rank: 20

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

struct P{
    ll v;
    ll y,x;
};


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

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n,m;
    cin >> n >> m;
    vector<string> s(n);
    rep(i,n) cin >> s[i];

    vector<vector<int>> goal;
    rep(i,n){
        rep(j,m){
            if(s[i][j]=='E'){
                goal.push_back({i,j});
                s[i][j] = '.';
            }
        }
    }
    int gs = goal.size();



    vector<vector<vector<P>>> dist(n,vector<vector<P>>(m,vector<P>(2,P{(int)1e9, -1, -1})));
    queue<vector<int>> q;
    rep(i,gs){
        dist[goal[i][0]][goal[i][1]][0] = P{0, goal[i][0], goal[i][1]};
        q.push({goal[i][0],goal[i][1],0});
    }

    while(!q.empty()){
        vector<int> p = q.front();
        q.pop();

        rep(i,4){
            int y = p[0]+dd[i][0];
            int x = p[1]+dd[i][1];
            if(y<0 || n<=y || x<0 || m<=x) continue;
            if(s[y][x]=='#') continue;

            if(dist[y][x][0].v>dist[p[0]][p[1]][p[2]].v+1){
                if(dist[y][x][0].y!=dist[p[0]][p[1]][p[2]].y || dist[y][x][0].x!=dist[p[0]][p[1]][p[2]].x) swap(dist[y][x][0],dist[y][x][1]);
                dist[y][x][0] = dist[p[0]][p[1]][p[2]];
                dist[y][x][0].v+=1;

                q.push({y,x,0});
            }
            else if(dist[y][x][1].v>dist[p[0]][p[1]][p[2]].v+1 && (dist[y][x][0].y!=dist[p[0]][p[1]][p[2]].y || dist[y][x][0].x!=dist[p[0]][p[1]][p[2]].x)){
                dist[y][x][1] = dist[p[0]][p[1]][p[2]];
                dist[y][x][1].v+=1;
                q.push({y,x,1});
            }
        }
    }

    int p;
    cin >> p;
    rep(i,p){
        int sr,sc,br,bc;
        cin >> sr >> sc >> br >> bc;
        if(dist[sr][sc][0].y==br && dist[sr][sc][0].x==bc){
            cout << dist[sr][sc][1].v << endl;
        }
        else{
            cout << dist[sr][sc][0].v << endl;
        }
    }


}
accuracy: 1
time_ms: 390
memory_kb: 173456
final_rank: 19

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

// #include<atcoder/all>
// using namespace atcoder;
// using mint=atcoder::modint998244353;

#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#define int long long

array<int,3> dist[1009][1009][2];


template<class T>
using pqmin=priority_queue<T,vector<T>,greater<T>>;

signed main(){
	int h,w;cin>>h>>w;
	vector<string> s(h);for(auto&&e:s)cin>>e;

	int q;cin>>q;
	vector<array<int,4>> qs(q);

	for(auto&&v:qs){
		for(auto&&e:v)cin>>e;
	}

	for(int i=0;i<h;i++){
		for(int j=0;j<w;j++){
			for(int k=0;k<2;k++){
				dist[i][j][k]={(int)1e9,-1,-1};
			}
		}
	}

	queue<array<int,5>> pq;
	for(int i=0;i<h;i++){
		for(int j=0;j<w;j++){
			if(s[i][j]=='E'){
				dist[i][j][0]={0,i,j};
				pq.push({0,i,j,i,j});
			}
		}
	}

	int di[4]={-1,0,1,0};
	int dj[4]={0,-1,0,1};

	while(pq.size()){
		auto[cost,pi,pj,i,j]=pq.front();pq.pop();

		// cout<<pi<<" "<<pj<<" : "<<cost<<" "<<i<<" "<<j<<endl;

		if(cost>dist[pi][pj][1][0])continue;

		for(int k=0;k<4;k++){
			int ni=pi+di[k],nj=pj+dj[k];

			if(0<=ni&&ni<h&&0<=nj&&nj<w&&s[ni][nj]!='#'){
				if(dist[ni][nj][0]>array<int,3>{cost+1,i,j}){
					dist[ni][nj][0]=array<int,3>{cost+1,i,j};
					pq.push({cost+1,ni,nj,i,j});
				}else if(dist[ni][nj][1]>array<int,3>{cost+1,i,j}&&(dist[ni][nj][0][1]!=i||dist[ni][nj][0][2]!=j)){
					dist[ni][nj][1]=array<int,3>{cost+1,i,j};
					pq.push({cost+1,ni,nj,i,j});
				}
			}
		}
	}

	// for(int i=0;i<h;i++){
	// 	for(int j=0;j<w;j++){
	// 		cout<<((dist[i][j][0][0]<1e9)?dist[i][j][0][0]:-1)<<" ";
	// 	}
	// 	cout<<endl;
	// }

	
	// cout<<endl;

	// for(int i=0;i<h;i++){
	// 	for(int j=0;j<w;j++){
	// 		cout<<((dist[i][j][0][0]<1e9)?dist[i][j][0][1]:-1)<<" ";
	// 	}
	// 	cout<<endl;
	// }

	for(auto&&v:qs){
		auto[cost,i,j]=dist[v[0]][v[1]][0];

		if(i==v[2]&&j==v[3]){
			cout<<dist[v[0]][v[1]][1][0]<<endl;
		}else{
			cout<<cost<<endl;
		}
	}
}
accuracy: 1
time_ms: 220
memory_kb: 96612
final_rank: 12

code_snippet: #include <bits/stdc++.h>

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

int main() {
    int N, M;
    std::cin >> N >> M;
    std::vector<std::string> S(N);
    for (auto& s : S) std::cin >> s;
    const int INF{(int)1e9};
    std::vector d1(N, std::vector<int>(M, INF)), d2{d1};
    std::vector p1(N, std::vector<std::pair<int, int>>(M, { -1, -1 })), p2{p1};
    std::queue<std::pair<int, int>> que;
    for (int i{} ; i < N ; i++) {
        for (int j{} ; j < M ; j++) {
            if (S[i][j] == 'E') {
                que.push(std::make_pair(i, j));
                d1[i][j] = 0;
                p1[i][j] = std::make_pair(i, j);
            }
        }
    }
    auto in{[&](int x, int y) -> bool {
        return 0 <= x and x < N and 0 <= y and y < M and S[x][y] != '#';
    }};
    while (que.size()) {
        auto [x, y]{que.front()};
        que.pop();
        for (int d{} ; d < 4 ; d++) {
            int nx{x + dx[d]}, ny{y + dy[d]};
            if (!in(nx, ny)) continue;
            bool upd{};
            if (d1[nx][ny] > d1[x][y] + 1) {
                upd = true;
                d2[nx][ny] = d1[nx][ny];
                p2[nx][ny] = p1[nx][ny];
                d1[nx][ny] = d1[x][y] + 1;
                p1[nx][ny] = p1[x][y];
            }
            else if (p1[x][y] != p1[nx][ny] and d2[nx][ny] > d1[x][y] + 1) {
                upd = true;
                d2[nx][ny] = d1[x][y] + 1;
                p2[nx][ny] = p1[x][y];
            }
            else if (p2[x][y] != p1[nx][ny] and d2[nx][ny] > d2[x][y] + 1) {
                upd = true;
                d2[nx][ny] = d2[x][y] + 1;
                p2[nx][ny] = p2[x][y];
            }
            if (upd) que.push(std::make_pair(nx, ny));
        }
    }
    int P;
    std::cin >> P;
    while (P--) {
        int sr, sc, br, bc;
        std::cin >> sr >> sc >> br >> bc;
        if (p1[sr][sc] == std::make_pair(br, bc)) {
            std::cout << d2[sr][sc] << '\n';
        }
        else {
            std::cout << d1[sr][sc] << '\n';
        }
    }
}
accuracy: 1
time_ms: 210
memory_kb: 36952
final_rank: 8

code_snippet: #include <bits/stdc++.h>

int main() {
    int n, m;
    std::cin >> n >> m;
    std::vector<std::string> s(n);
    for (int i = 0; i < n; i++) std::cin >> s[i];
    const int N = 2;
    const int NONE = -1;
    std::vector dist(N, std::vector(n, std::vector<int>(m, NONE)));
    std::vector exit(N, std::vector(n, std::vector<std::pair<int, int>>(m, {NONE, NONE})));
    std::queue<std::tuple<int, int, int>> que;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (s[i][j] == 'E') {
                que.emplace(0, i, j);
                dist[0][i][j] = 0;
                exit[0][i][j] = {i, j};
            }
        }
    }
    const int D[] = {0, 1, 0, -1, 0};
    while (!que.empty()) {
        auto [level, i, j] = que.front();
        que.pop();
        for (int d = 0; d < 4; d++) {
            int ni = i + D[d];
            int nj = j + D[d + 1];
            if (ni < 0 || nj < 0 || ni >= n || nj >= m) continue;
            if (s[ni][nj] == '#') continue;
            if (dist[0][ni][nj] == -1) {
                // assert(level == 0);
                dist[0][ni][nj] = dist[level][i][j] + 1;
                exit[0][ni][nj] = exit[level][i][j];
                que.emplace(0, ni, nj);
            } else if (dist[1][ni][nj] == -1 && exit[level][i][j] != exit[0][ni][nj]) {
                // assert(level == 1);
                dist[1][ni][nj] = dist[level][i][j] + 1;
                exit[1][ni][nj] = exit[level][i][j];
                que.emplace(1, ni, nj);
            }
        }
    }
    int q;
    std::cin >> q;
    while (q--) {
        int si, sj;
        std::cin >> si >> sj;
        int gi, gj;
        std::cin >> gi >> gj;
        if (exit[0][si][sj] != std::pair<int, int>(gi, gj)) {
            std::cout << dist[0][si][sj] << '\n';
        } else {
            std::cout << dist[1][si][sj] << '\n';
        }
    }
}
accuracy: 1
time_ms: 190
memory_kb: 41064
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int INF = (1 << 30) - 1;

const vector<int> dx = {0, 1, 0, -1};
const vector<int> dy = {1, 0, -1, 0};
#ifdef LOCAL
#include <debug_print.hpp>
#define debug(...) debug_print::multi_print(#__VA_ARGS__, __VA_ARGS__)
#else
#define debug(...) (static_cast<void>(0))
#endif

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(20);
    int N, M;
    cin >> N >> M;
    vector<string> A(N);
    for(int i = 0; i < N; i++) cin >> A[i];
    
    // 全出口に id を付けて, その出口からの各マスの距離を求める
    // 各マスについて, 最も近い出口と次に近い出口を求める
    map<pair<int, int>, int> exit;
    vector dist(N, vector(M, vector<int>(2, -1)));
    // {x, y, id, f := 最も近いか, 2 番目に近いか}
    queue<tuple<int, int, int, int>> que;
    // s[i][j][0] := (i, j) に最も近い出口の id
    // s[i][j][1] := (i, j) に 2 番目に近い出口の id
    vector s(N, vector(M, vector<int>(2, -1)));
    int cnt = 0;
    for(int i = 0; i < N; i++){
        for(int j = 0; j < M; j++){
            if(A[i][j] == 'E'){
                dist[i][j][0] = 0;
                que.emplace(i, j, cnt, 0);
                s[i][j] = {cnt, -1};
                exit[{i, j}] = cnt++;
            }
        }
    }

    while(!que.empty()){
        auto [x, y, id, f] = que.front();
        que.pop();
        for(int k = 0; k < 4; k++){
            int nx = x + dx[k], ny = y + dy[k];
            if(nx < 0 || nx >= N || ny < 0 || ny >= M) continue;
            if(A[nx][ny] == '#') continue;
            // 最も近い地点を更新
            if(dist[nx][ny][0] == -1){
                dist[nx][ny][0] = dist[x][y][f] + 1;
                s[nx][ny][0] = id;
                que.emplace(nx, ny, id, 0);
            // 2 番目に近い地点を更新
            }else if(dist[nx][ny][1] == -1 && s[nx][ny][0] != id){
                dist[nx][ny][1] = dist[x][y][f] + 1;
                s[nx][ny][1] = id;
                que.emplace(nx, ny, id, 1);
            }
        }
    }
    debug(dist, s);
    int P;
    cin >> P;
    while(P--){
        int sx, sy, br, bc; cin >> sx >> sy >> br >> bc;
        // 最も近い出口が壊れていない場合
        if(s[sx][sy][0] != exit[{br, bc}]){
            cout << dist[sx][sy][0] << "\n";
        // 壊れている場合, 2 番目に近い出口
        }else{
            cout << dist[sx][sy][1] << "\n";
        }
    }
}
accuracy: 1
time_ms: 300
memory_kb: 161392
final_rank: 18

code_snippet: #include<bits/stdc++.h>
#define overload(a,b,c,d,...) d
#define rep1(a) for(ll _=0;_<a;++_)
#define rep2(i,a) for(ll i=0;i<a;++i)
#define rep3(i,a,b) for(ll i=a;i<b;++i)
#define rep(...) overload(__VA_ARGS__,rep3,rep2,rep1)(__VA_ARGS__)
#define rrep1(i,a) for(ll i=(ll)a-1;i>=0;--i)
#define rrep2(i,a,b) for(ll i=(ll)b-1;i>=(ll)a;--i)
#define rrep(...) overload(__VA_ARGS__,rrep2,rrep1)(__VA_ARGS__)
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define eb emplace_back
#define pb push_back
using namespace std;
using ll=long long;
using ull=unsigned long long;
using ld=long double;
template<typename T,typename U>inline bool chmin(T&a,const U&b){return (a>b?a=b,true:false);}
template<typename T,typename U>inline bool chmax(T&a,const U&b){return (a<b?a=b,true:false);}
static constexpr ll inf=numeric_limits<ll>::max()/2;
/*
ll calc(ll x1,ll y1,ll x2,ll y2,ll x3,ll y3){
    return abs((x1-x3)*(y2-y3)-(x2-x3)*(y1-y3));
}
int main(){
    ll n;cin>>n;
    vector<ll>x(n),y(n);
    rep(i,n)cin>>x[i]>>y[i];
    ll area=0;
    rep(i,1,n-1){
        area+=calc(x[0],y[0],x[i],y[i],x[i+1],y[i+1]);
    }
    ll l=0,r=2;
    ll now=calc(x[0],y[0],x[1],y[1],x[2],y[2]);
    ll ans=abs(area-now*2);
    while(l<n){
        if(now>area/2){
            chmin(ans,abs(area-now*2));
            now-=calc(x[l],y[l],x[(l+1)%n],y[(l+1)%n],x[r],y[r]);
            l++;
            l%=n;
            if((r-l+n)%3==1){
                now+=calc(x[l],y[l],x[r],y[r],x[(r+1)%n],y[(r+1)%n]);
                r++;
                r%=n;
            }
            if(l==0)break;
        }
        chmin(ans,abs(area-now*2));
        now+=calc(x[l],y[l],x[r],y[r],x[(r+1)%n],y[(r+1)%n]);
        r++;
        r%=n;
    }
    cout<<fixed<<setprecision(12)<<ans/2.0<<endl;
}*/
constexpr int dx[]={-1,0,1,0};
constexpr int dy[]={0,-1,0,1};
using T=pair<pair<ll,ll>,pair<ll,ll>>;
const T e={{inf,inf},{inf,inf}};
T merge(T a,T b){
    vector<pair<ll,ll>>v;
    T ans=e;
    ans=a;
    if(b.first.first<ans.first.first){
        if(b.first.second!=ans.first.second){
            ans={b.first,ans.first};
        }
        else{
            ans={b.first,ans.second};
        }
    }
    else if(b.first.first<ans.second.first){
        if(b.first.second!=ans.first.second){
            ans={ans.first,b.first};
        }
    }
    if(b.second.first<ans.first.first){
        if(b.second.second!=ans.first.second){
            ans={b.second,ans.first};
        }
        else{
            ans={b.second,ans.second};
        }
    }
    else if(b.second.first<ans.second.first){
        if(b.second.second!=ans.first.second){
            ans={ans.first,b.second};
        }
    }
    return ans;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    ll n,m;
    cin>>n>>m;
    vector<string>s(n);
    for(auto&e:s)cin>>e;
    vector<T>dist(n*m,e);
    queue<pair<T,ll>>pq;
    rep(i,n)rep(j,m)if(s[i][j]=='E'){
        dist[i*m+j]={{0,i*m+j},{inf,inf}};
        pq.push({dist[i*m+j],i*m+j});
    }
    vector<ll>vis(n*m);
    int cnt=0;
    while(!pq.empty()){
        //cerr<<pq.size()<<endl;
        auto a=pq.front();pq.pop();
        T d=a.first;
        ll id=a.second;
        if(dist[id]!=d)continue;
        cnt++;
        ll x=id/m,y=id%m;
        //cerr<<cnt<<endl;
        //cerr<<x<<" "<<y<<endl;
        //cerr<<'{'<<dist[id].first.first<<" "<<dist[id].first.second<<'}'<<" {"<<dist[id].second.first<<" "<<dist[id].second.second<<"}"<<endl;
        rep(dir,4){
            ll nx=x+dx[dir],ny=y+dy[dir];
            if(nx<0||nx>=n||ny<0||ny>=m||s[nx][ny]=='#')continue;
            T nxt=d;
            nxt.first.first++,nxt.second.first++;
            auto tmp=merge(dist[nx*m+ny],nxt);
            if(tmp!=dist[nx*m+ny]){
                dist[nx*m+ny]=tmp;
                pq.push({dist[nx*m+ny],nx*m+ny});
            }
        }
    }
    /*
    rep(i,n){
        rep(j,m){
            cerr<<'{'<<dist[i*m+j].first.first<<" "<<dist[i*m+j].first.second<<'}'<<" {"<<dist[i*m+j].second.first<<" "<<dist[i*m+j].second.second<<"}  ";
        }
        cout<<endl;
    }*/
    ll q;cin>>q;
    while(q--){
        ll sx,sy,bx,by;
        cin>>sx>>sy>>bx>>by;
        if(dist[sx*m+sy].first.second==bx*m+by){
            cout<<dist[sx*m+sy].second.first<<endl;
        }
        else{
            cout<<dist[sx*m+sy].first.first<<endl;
        }
    }
}
accuracy: 1
time_ms: 200
memory_kb: 84500
final_rank: 11

code_snippet: #pragma GCC target("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N, M;
    cin >> N >> M;
    vector<string> S(N);
    vector<pair<int, int>> dir = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
    vector<vector<vector<int>>> dist(N, vector<vector<int>>(M, vector<int>(6)));
    queue<int> que;
    for( int i = 0; i < N; i++ ) {
        cin >> S[i];
        for( int j = 0; j < M; j++ ) {
            if( S[i][j] == 'E' ) {
                dist[i][j] = {0, i, j, N*M, -1, -1};
                que.emplace((i<<10)|j);
            }else {
                dist[i][j] = {N*M, -1, -1, N*M, -1, -1};
            }
        }
    }
    auto is_valid_cell = [&](int x, int y) {
        return ( 0 <= x && x < N && 0 <= y && y < M && S[x][y] != '#' );
    };
    while( !que.empty() ) {
        int f = que.front(), cx = f>>10, cy = f&1023;
        que.pop();
        for( int k = 0; k < 6; k+=3 ) {
            for( auto& [x, y] : dir ) {
                int nx = cx+x, ny = cy+y;
                if( is_valid_cell(nx, ny) && dist[nx][ny][3] > dist[cx][cy][k]+1 ) {
                    if( ( dist[nx][ny][1] == dist[cx][cy][k+1] && dist[nx][ny][2] == dist[cx][cy][k+2] ) || ( dist[nx][ny][4] == dist[cx][cy][k+1] && dist[nx][ny][5] == dist[cx][cy][k+2] ) ) continue;
                    que.emplace((nx<<10)|ny);
                    dist[nx][ny][3] = dist[cx][cy][k]+1;
                    dist[nx][ny][4] = dist[cx][cy][k+1];
                    dist[nx][ny][5] = dist[cx][cy][k+2];
                    if( dist[nx][ny][0] > dist[nx][ny][3] ) {
                        for( int l = 0; l < 3; l++ ) {
                            swap(dist[nx][ny][l], dist[nx][ny][3+l]);
                        }
                    }
                }
            }
        }
    }
    int P;
    cin >> P;
    for( int p = 0; p < P; p++ ) {
        int sr, sc, br, bc;
        cin >> sr >> sc >> br >> bc;
        if( dist[sr][sc][1] == br && dist[sr][sc][2] == bc ) {
            cout << dist[sr][sc][3] << endl;
        }else {
            cout << dist[sr][sc][0] << endl;
        }
    }
}
accuracy: 1
time_ms: 290
memory_kb: 62844
final_rank: 10

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

constexpr int inf=1e9+10;
constexpr char newl='\n';
constexpr int dx[]={0,1,0,-1};
constexpr int dy[]={1,0,-1,0};

bool valid(int i,int j,int h,int w){
    return 0<=i && i<h && 0<=j && j<w;
}

vector<int> add(vector<int> s,vector<int> t){
    while(s.size()<t.size())s.emplace_back(0);
    while(t.size()<s.size())t.emplace_back(0);
    s.emplace_back(0);
    rep(i,t.size()){
        s[i]+=t[i];
        if(s[i]>=10){
            s[i]-=10;
            s[i+1]++;
        }
    }
    if(s.back()==0)s.pop_back();
    return s;
}
vector<int> prod(vector<int> s,int x){
    vector<int> ans={0};
    rep(i,x)ans=add(ans,s);
    return ans;
}
struct value{
    int x,y;
    int dist;
    value(int x=-1,int y=-1,int dist=inf):x(x),y(y),dist(dist){}
    //distが等しかったらfalse
    bool operator<(const value r)const{
        return dist<r.dist;
    }
    value add_one()const{
        return value(x,y,dist+1);
    }
    pair<int,int> beg()const{
        return make_pair(x,y);
    }
};

template<typename T>
bool chmin(T &a,T b){
    return b<a ? a=b,true:false;
}

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

    int n,m;
    cin >> n >> m;
    vector<string> s(n);
    rep(i,n)cin >> s[i];
    vector<vector<array<value,2>>> dp(n,vector<array<value,2>>(m));
    //{{点},0番or1番}
    queue<pair<pair<int,int>,int>> q;
    rep(i,n)rep(j,m){
        if(s[i][j]=='E'){
            dp[i][j][0]=value(i,j,0);
            q.push({{i,j},0});
        }
    }
    while(!q.empty()){
        auto [p,k]=q.front();q.pop();
        auto [i,j]=p;
        auto now=dp[i][j][k];
        rep(k,4){
            int ni=i+dx[k],nj=j+dy[k];
            if(valid(ni,nj,n,m) && s[ni][nj]!='#'){
                //一番を更新できるか？更新できるなら2番に1番を移すのを忘れない、、？
                //距離が短いところから見ているので、1番が更新できる => まだ一度も見ていない
                if(chmin(dp[ni][nj][0],now.add_one())){
                    q.push({{ni,nj},0});
                }
                else if(dp[ni][nj][0].beg()!=now.beg() && chmin(dp[ni][nj][1],now.add_one())){
                    q.push({{ni,nj},1});
                }
            }
        }
    }

    int p;
    cin >> p;
    while(p--){
        int sx,sy,gx,gy;
        cin >> sx >> sy >> gx >> gy;
        if(dp[sx][sy][0].beg()!=make_pair(gx,gy)){
            cout << dp[sx][sy][0].dist << newl;
        }
        else{
            cout << dp[sx][sy][1].dist << newl;
        }
    }
}
accuracy: 1
time_ms: 90
memory_kb: 39864
final_rank: 4

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

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

int main(){
	int n,m;
	cin >> n >> m;
	vector<string> s(n);
	rep(i, n) cin >> s[i];
	queue<pii> que;
	vector<vector<pii>> dist(n, vector<pii>(m, { -1, -1 }));
	vector<vector<pii>> dist2(n, vector<pii>(m, { -1, -1 }));
	rep(i, n) rep(j, m) if(s[i][j] == 'E'){
		dist[i][j] = { 0, i*m+j };
		que.push({ i*m+j, i*m+j });
	}
	while(!que.empty()){
		const int posy = que.front().first / m;
		const int posx = que.front().first % m;
		const int idx = que.front().second;
		que.pop();
		const int d = dist[posy][posx].second == idx ? dist[posy][posx].first+1 : dist2[posy][posx].first+1;
		rep(i, 4){
			const int y = posy + dy[i];
			const int x = posx + dx[i];
			if(y < 0 || x < 0 || y >= n || x >= m) continue;
			if(s[y][x] == '#') continue;
			if(dist[y][x].first == -1){
				dist[y][x] = { d, idx };
				que.push({ y*m+x, idx });
			}else if(dist2[y][x].first == -1 && dist[y][x].second != idx){
				dist2[y][x] = { d, idx };
				que.push({ y*m+x, idx });
			}
		}
	}
	int p; cin >> p;
	rep(i, p){
		int sy,sx, by,bx;
		cin >> sy >> sx >> by >> bx;
		if(dist[sy][sx].second != by*m+bx) cout << dist[sy][sx].first << "\n";
		else cout << dist2[sy][sx].first << "\n";
	}
}
accuracy: 1
time_ms: 170
memory_kb: 29008
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
using lint = long long;
const lint mod = 998244353;
#define rep(i, n) for(int i = 0; i < int(n); i++)
#define rep2(i, l, r) for(int i = int(l); i < int(r); i++)
#define repr(i, n) for(int i = int(n) - 1; i >= 0; i--)
#define repr2(i, l, r) for(int i = int(r) - 1; i >= int(l); i--)

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

using Graph = vector<vector<int>>;

vector<pair<pair<int, int>, int>> BFS(const Graph &g, vector<int> s){ // dist, dist2, nearest
    int n = int(g.size());
    
    pair<int, int> dist[n]; // length, born
    pair<int, int> dist2[n]; // length, born
    rep(i, n) dist[i] = {-1, -1};
    rep(i, n) dist2[i] = {-1, -1};
    rep(i, s.size()){
        dist[s[i]] = {0, i};
    }
    
    queue<pair<int, pair<int, int>>> que; // at, length, born
    rep(i, s.size()){
        que.push({s[i], {0, i}});
    }
    
    while(!que.empty()){
        auto top = que.front();
        que.pop();
        int at = top.first;
        int length = top.second.first;
        int born = top.second.second;
        
        for(int to: g[at]){
            if(dist[to].first == -1){
                dist[to] = {length + 1, born};
                que.push({to, {length + 1, born}});
            }else if(dist2[to].first == -1 && dist[to].second != born){
                dist2[to] = {length + 1, born};
                que.push({to, {length + 1, born}});
            }
        }
    }
    
    vector<pair<pair<int, int>, int>> res(n);
    rep(i, n){
        res[i] = {{dist[i].first, dist2[i].first}, dist[i].second};
    }
    return res;
}

string s[1010];
int exit_num[1010][1010];

int main(){
    int n, m;
    cin >> n >> m;
    rep(i, n) cin >> s[i];
    
    Graph g(n * m);
    auto func = [&](int y, int x){ return y * m + x; };
    auto is_inside = [&](int y, int x){ return 0 <= y && y < n && 0 <= x && x < m; };
    rep(y, n){
        rep(x, m){
            rep(c, 4){
                int y2 = y + dy[c];
                int x2 = x + dx[c];
                if(!is_inside(y2, x2)) continue;
                if(s[y2][x2] == '#') continue;
                
                int a = func(y, x), b = func(y2, x2);
                g[a].push_back(b);
            }
        }
    }
    
    vector<int> exits;
    rep(i, n) rep(j, m){
        if(s[i][j] == 'E'){
            exit_num[i][j] = int(exits.size());
            
            exits.push_back(func(i, j));
        }
    }
    
    auto dist_data = BFS(g, exits);
    
    int p;
    cin >> p;
    rep(_, p){
        int sy, sx, gy, gx;
        cin >> sy >> sx >> gy >> gx;
        int s = func(sy, sx);
        int g_num = exit_num[gy][gx];
        
        int dist = dist_data[s].first.first;
        int dist2 = dist_data[s].first.second;
        int nearest_exit = dist_data[s].second;
        
        if(g_num != nearest_exit){
            cout << dist << endl;
        }else{
            cout << dist2 << endl;
        }
    }
}
accuracy: 1
time_ms: 280
memory_kb: 106928
final_rank: 15

code_snippet: /* -*- coding: utf-8 -*-
 *
 * 0447.cc: Broken Exit
 */

#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
 
using namespace std;

/* constant */

const int MAX_N = 1000;
const int MAX_M = 1000;
const int MAX_NM = MAX_N * MAX_M;

const int dxs[] = { 1, 0, -1, 0 }, dys[] = { 0, -1, 0, 1 };

/* typedef */

typedef vector<int> vi;

struct Stat {
  int d, i, e;
  Stat() {}
  Stat(int _d, int _i, int _e): d(_d), i(_i), e(_e) {}
};

/* global variables */

char fs[MAX_N][MAX_M + 4];
int ds0[MAX_NM], ds1[MAX_NM], des0[MAX_NM], des1[MAX_NM];

/* subroutines */

/* main */

int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  int nm = n * m;

  vi ev;
  for (int y = 0, p = 0; y < n; y++) {
    scanf("%s", fs[y]);
    for (int x = 0; x < m; x++, p++)
      if (fs[y][x] == 'E') ev.push_back(p);
  }

  fill(ds0, ds0 + nm, -1);
  fill(ds1, ds1 + nm, -1);

  queue<Stat> q;
  for (auto e: ev)
    ds0[e] = 0, des0[e] = e, q.push(Stat(0, e, e));

  while (! q.empty()) {
    Stat u = q.front(); q.pop();
    int uy = u.i / m, ux = u.i % m;
    int vd = u.d + 1;

    for (int di = 0; di < 4; di++) {
      int vy = uy + dys[di], vx = ux + dxs[di];
      if (vy >= 0 && vy < n && vx >= 0 && vx < m && fs[vy][vx] != '#') {
	int v = vy * m + vx;
	if (ds0[v] < 0)
	  ds0[v] = vd, des0[v] = u.e, q.push(Stat(vd, v, u.e));
	else if (ds1[v] < 0 && des0[v] != u.e)
	  ds1[v] = vd, des1[v] = u.e, q.push(Stat(vd, v, u.e));
      }
    }
  }

  int qn;
  scanf("%d", &qn);

  while (qn--) {
    int sy, sx, by, bx;
    scanf("%d%d%d%d", &sy, &sx, &by, &bx);
    int s = sy * m + sx;
    int b = by * m + bx;

    printf("%d\n", (des0[s] != b) ? ds0[s] : ds1[s]);
  }

  return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 33152
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
using vi = vector<int>;
using vvi = vector<vector<int>>;

int INF = 1 << 20;
vvi Directions = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

int main() {
    int n, m, p;
    cin >> n >> m;

    vector<string> S;
    for (int i = 0; i < n; ++i) {
        string s;
        cin >> s;
        S.push_back(s);
    }

    vi E;
    vvi MinE(n, vi(m));
    vector<vvi> DP(n, vvi(m, vi(2)));
    queue<vi> Que;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (S[i][j] == 'E') {
                E.push_back(i * m + j);
                MinE[i][j] = i * m + j;
                DP[i][j][0] = 0;
                DP[i][j][1] = INF;
                Que.push({i, j, i, j, 0});
            }
            else {
                DP[i][j][0] = INF;
                DP[i][j][1] = INF;
            }
        }
    }

    while (!Que.empty()) {
        int ci, cj, ei, ej, di, dj, ni, nj, d;
        ci = Que.front()[0];
        cj = Que.front()[1];
        ei = Que.front()[2];
        ej = Que.front()[3];
        d = Que.front()[4];
        Que.pop();
        for (int i = 0; i < 4; ++i) {
            di = Directions[i][0];
            dj = Directions[i][1];
            ni = ci + di;
            nj = cj + dj;
            if (0 <= ni && ni < n && 0 <= nj && nj < m) {
                if (S[ni][nj] == '#') {
                    continue;
                }
                if (DP[ni][nj][d] <= DP[ci][cj][d] + 1) {
                    if (d == 0) {
                        if (DP[ni][nj][1] <= DP[ci][cj][0] + 1) {
                            continue;
                        }
                        if (MinE[ni][nj] == ei * m + ej) {
                            continue;
                        }
                        DP[ni][nj][1] = DP[ci][cj][0] + 1;
                        Que.push({ni, nj, ei, ej, 1});
                    }
                }
                else {
                    DP[ni][nj][d] = DP[ci][cj][d] + 1;
                    if (d == 0) {
                        MinE[ni][nj] = ei * m + ej;
                    }
                    Que.push({ni, nj, ei, ej, d});
                }
            }
        }
    }

    cin >> p;
    for (int i = 0; i < p; ++i) {
        int ci, cj, ei, ej;
        cin >> ci >> cj >> ei >> ej;
        if (MinE[ci][cj] == ei * m + ej) {
            cout << DP[ci][cj][1] << endl;
        }
        else {
            cout << DP[ci][cj][0] << endl;
        }
    }

}
accuracy: 1
time_ms: 340
memory_kb: 120680
final_rank: 16

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

int INF = 1 << 20;
vector<vector<int>> Directions = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

int main() {
    int n, m, p;
    cin >> n >> m;

    vector<string> S;
    for (int i = 0; i < n; ++i) {
        string s;
        cin >> s;
        S.push_back(s);
    }

    vector<int> E;
    vector<vector<int>> MinE(n, vector<int>(m));
    vector<vector<vector<int>>> DP(n, vector<vector<int>>(m, vector<int>(2)));
    queue<vector<int>> Que;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (S[i][j] == 'E') {
                E.push_back(i * m + j);
                MinE[i][j] = i * m + j;
                DP[i][j][0] = 0;
                DP[i][j][1] = INF;
                Que.push({i, j, i, j, 0});
            }
            else {
                DP[i][j][0] = INF;
                DP[i][j][1] = INF;
            }
        }
    }

    while (!Que.empty()) {
        int ci, cj, ei, ej, di, dj, ni, nj, d;
        ci = Que.front()[0];
        cj = Que.front()[1];
        ei = Que.front()[2];
        ej = Que.front()[3];
        d = Que.front()[4];
        Que.pop();
        for (int i = 0; i < 4; ++i) {
            di = Directions[i][0];
            dj = Directions[i][1];
            ni = ci + di;
            nj = cj + dj;
            if (0 <= ni && ni < n && 0 <= nj && nj < m) {
                if (S[ni][nj] == '#') {
                    continue;
                }
                if (DP[ni][nj][d] <= DP[ci][cj][d] + 1) {
                    if (d == 0) {
                        if (DP[ni][nj][1] <= DP[ci][cj][0] + 1) {
                            continue;
                        }
                        if (MinE[ni][nj] == ei * m + ej) {
                            continue;
                        }
                        DP[ni][nj][1] = DP[ci][cj][0] + 1;
                        Que.push({ni, nj, ei, ej, 1});
                    }
                }
                else {
                    DP[ni][nj][d] = DP[ci][cj][d] + 1;
                    if (d == 0) {
                        MinE[ni][nj] = ei * m + ej;
                    }
                    Que.push({ni, nj, ei, ej, d});
                }
            }
        }
    }

    cin >> p;
    for (int i = 0; i < p; ++i) {
        int ci, cj, ei, ej;
        cin >> ci >> cj >> ei >> ej;
        if (MinE[ci][cj] == ei * m + ej) {
            cout << DP[ci][cj][1] << endl;
        }
        else {
            cout << DP[ci][cj][0] << endl;
        }
    }

}
accuracy: 1
time_ms: 360
memory_kb: 120652
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
const long long mod1 = 1000000007;
const long long mod2 = 998244353;
double pi = 3.141592653589;
using ll = long long;
vector<ll> dx = {-1,0,1,0,1,1,-1,-1};
vector<ll> dy = {0,1,0,-1,1,-1,1,-1};
vector<char> abc = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
vector<char> ABC = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
 
struct UnionFind{
    vector<ll> par, siz;
    
    UnionFind(ll n):par(n,-1),siz(n,1){}
    
    ll root(ll x){//親を返す
        if(par[x] == -1) return x;
        else return par[x] = root(par[x]);
    }
    
    bool issame(ll x,ll y){//同じグループかどうか
        return root(x) == root(y);
    }
    
    bool unite(ll x, ll y){//合体
        x = root(x); y = root(y);
        if(x == y) return false;
        if(siz[x] < siz[y]) swap(x,y);
        par[y] = x;
        siz[x] += siz[y];
        return true;
    }
    
    ll size(ll x){//xがいるグループのサイズ
        return siz[root(x)];
    }
    
    
    
};
 
long long pow2(long long x,long long n){
    long long ans = 1;
    while(n != 0){
        long long a = x;
        long long z = 1;
        while(z*2 <= n){
            a *=a;
            a=a%mod2;
            z*=2;
        }
        ans*=a;
        ans=ans%mod2;
        n-=z;
    }
    return ans; 
}//累乗 x^n
 
template<typename T>
void input_vec(vector<T> &A){
    ll N = A.size();
    for(int i = 0; i < N; i++){
        cin >> A.at(i);
    }
    return;
}//入力を配列で受け取る
 
template<typename T>
void output_vec(vector<T> &A){
    ll N = A.size();
    for(int i = 0; i < N; i++){
        if(i != 0){
            cout << " ";
        }
        cout << A.at(i);
    }
    cout << endl;
    return;
}//配列を出力
 
template<typename T>
long long count_x(vector<T> &A,T x){
    long long counter = 0;
    for(int i = 0; i < (int)A.size(); i++){
        if(A.at(i) == x){
            counter++;
        }
    }
    return counter;
}//配列内のxの個数をreturn
 
template<typename T>
long long duplicate(vector<T> &A){
    ll ans = 0;
    ll N = A.size();
    T a = A.at(0);
    for(int i = 1; i < N; i++){
        if(a == A.at(i)) ans++;
        else a = A.at(i);
    }
    return ans;
}
 
template<typename T>
void chmin(T &a,T b){
    if(a>b){
        a = b;
    }
    return;
}
 
template<typename T>
void chmax(T&a,T b){
    if(a < b){
        a = b;
    }
    return;
}

/*
絶対値   abs()
配列の要素の追加   push_back() 
char→intに変換   -'0'
string→intに変換   atoi(文字列名.c_str())
配列の中身をN個の０で初期化   配列名.resize(N)
配列の中身をN個のaで初期化   配列名.assign(N,a)
配列の中からK以上の数字の最小値を出力　lower_bound(配列.begin(),配列.end(),K)
入力scanf("%lld %lld",&a,&b) みたいな感じ &を忘れずに
小数の桁数設定cout << fixed << setprecision(桁数);
*/
vector<vector<ll>> ans;
vector<vector<ll>> ans2;
vector<vector<pair<ll,ll>>> check;
vector<string> g;
int main(){
    ll N,M; cin >> N >> M;
    g.assign(N,"");
    input_vec(g);
    queue<tuple<ll,ll,ll,ll,ll>> q;
    ans.assign(N,vector<ll>(M,-1));
    ans2.assign(N,vector<ll>(M,-1));
    check.assign(N,vector<pair<ll,ll>>(M));
    for(int i = 0; i < N; i++){
        for(int j = 0; j < M; j++){
            if(g[i][j] == 'E'){
                q.push(make_tuple(i,j,i,j,0));
                ans[i][j] = 0;
                check[i][j] = make_pair(i,j);
            }
        }
    }
    
    while(!q.empty()){
        ll x,y,ox,oy,r; tie(x,y,ox,oy,r) = q.front();
        q.pop();
        for(int i = 0; i < 4; i++){
            ll nx = x+dx[i];
            ll ny = y+dy[i];
            if(nx<0||nx>=N||ny<0||ny>=M) continue;
            if(g[nx][ny] == '#') continue;
            if(ans2[nx][ny] != -1) continue;
            if(ans[nx][ny] == -1){
                ans[nx][ny] = r+1;
                check[nx][ny] = make_pair(ox,oy);
                q.push(make_tuple(nx,ny,ox,oy,r+1));
            }
            else if(check[nx][ny] == make_pair(ox,oy)) continue;
            else {
                ans2[nx][ny] = r+1;
                q.push(make_tuple(nx,ny,ox,oy,r+1));
            }
        }
    }
    
    /*for(int i = 0; i < N; i++){
        for(int j = 0; j < M; j++){
            cout << ans[i][j] << " ";
        }
        cout << endl;
    }*/
    
    ll P; cin >> P;
    for(int i = 0; i < P; i++){
        ll sx,sy,gx,gy; cin >> sx >> sy >> gx >> gy;
        if(check[sx][sy] == make_pair(gx,gy)) cout << ans2[sx][sy] << endl;
        else cout << ans[sx][sy] << endl;
    }
    
    
}
accuracy: 1
time_ms: 220
memory_kb: 77652
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
template<class T> using vc = vector<T>;
template<class T> using vvc = vc<vc<T>>;
template<class T> using vvvc = vc<vvc<T>>;
template<class T> using vvvvc = vvc<vvc<T>>;
template<class T> using PQ = priority_queue<T>;
template<class T> using invPQ = priority_queue<T, vector<T>, greater<T>>;
using IP = pair<int, int>;
using LP = pair<ll, ll>;
#define all(x) begin(x), end(x)
#define allr(x) rbegin(x), rend(x)
#define rep(i, n) for (int i = 0; (i) < (int)(n); i++)
#define rep3(i, m, n) for (int i = (m); (i) < (int)(n); i++)
#define repr(i, n) for (int i = (n) - 1; (i) >= 0; i--)
#define rep3r(i, m, n) for (int i = (n) - 1; (i) >= (int)(m); i--)
template<class T> inline bool chmax(T & a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T & a, T b) { if (a > b) { a = b; return 1; } return 0; }
#define INF 1000000

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

bool chmin2(pair<IP, IP> &a, IP b) {
    if (a.first.second < b.first) return false;
    if (a.second.first == b.second) {
        if (a.first.first > b.first) {
            a.first.first = b.first;
            return true;
        }
        else {
            return false;
        }
    }
    else if (a.second.second == b.second) {
        if (a.first.first > b.first) {
            a.first.second = a.first.first;
            a.second.second = a.second.first;
            a.first.first = b.first;
            a.second.first = b.second;
            return true;
        }
        else {
            a.first.second = b.first;
            return true;
        }
    }
    if (a.first.first > b.first) {
        a.first.second = a.first.first;
        a.second.second = a.second.first;
        a.first.first = b.first;
        a.second.first = b.second;
        return true;
    }
    a.first.second = b.first;
    a.second.second = b.second;
    return true;
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    
    int N, M;
    cin >> N >> M;
    vc<string> row(N);
    rep (i, N) cin >> row[i];
    int P;
    cin >> P;
    vc<int> sr(P), sc(P), br(P), bc(P);
    rep (i, P) cin >> sr[i] >> sc[i] >> br[i] >> bc[i];
    
    vvc<pair<IP, IP>> dist(N, vc<pair<IP, IP>>(M, make_pair(make_pair(INF, INF), make_pair(-1, -1))));
    queue<tuple<int, int, int>> que;
    vvvc<bool> seen(N, vvc<bool>(M, vc<bool>(2)));
    rep (i, N) rep (j, M) {
        if (row[i][j] == 'E') {
            dist[i][j].first.first = 0;
            dist[i][j].second.first = i*M+j;
            que.push({ 0, i*M+j, i*M+j });
            seen[i][j][0] = true;
        }
    }
    
    while (!que.empty()) {
        int r = get<1>(que.front()) / M, c = get<1>(que.front()) % M, d = get<0>(que.front()), e = get<2>(que.front()); que.pop();
        rep (i, 4) {
            int er = r + dx[i], ec = c + dy[i];
            if (er < 0 || er >= N || ec < 0 || ec >= M || row[er][ec] == '#' || seen[er][ec][1]) continue;
            if (!seen[er][ec][0]) {
                seen[er][ec][0] = true;
                dist[er][ec].first.first = d+1;
                dist[er][ec].second.first = e;
                que.push({ d+1, er*M+ec, e });
            }
            else if (!seen[er][ec][1] && !(dist[er][ec].second.first == e)) {
                seen[er][ec][1] = true;
                dist[er][ec].first.second = d+1;
                dist[er][ec].second.second = e;
                que.push({ d+1, er*M+ec, e });
            }
        }
    }
    
    rep (i, P) {
        if (dist[sr[i]][sc[i]].second.first == br[i] * M + bc[i]) cout << dist[sr[i]][sc[i]].first.second << endl;
        else cout << dist[sr[i]][sc[i]].first.first << endl;
    }
}
accuracy: 1
time_ms: 260
memory_kb: 103788
final_rank: 14

code_snippet: #include <bits/stdc++.h>

using ll = long long;

template <class T> using Vec = std::vector<T>;

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

int main() {
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int n, m;
    std::cin >> n >> m;
    Vec<Vec<char>> grid(n + 2, Vec<char>(m + 2, '#'));
    Vec<std::pair<int, int>> exit;
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            std::cin >> grid[i][j];
            if (grid[i][j] == 'E') {
                exit.emplace_back(i, j);
            }
        }
    }
    Vec<Vec<std::array<int, 2>>> dist(n + 2, Vec<std::array<int, 2>>(m + 2));
    Vec<Vec<std::array<int, 2>>> exit_id(n + 2, Vec<std::array<int, 2>>(m + 2));
    for (int i = 0; i <= n + 1; ++i) {
        for (int j = 0; j <= m + 1; ++j) {
            dist[i][j].fill(-1);
            exit_id[i][j].fill(-1);
        }
    }
    std::queue<std::tuple<int, int, int>> que;
    auto push = [&](int i, int j, int d, int e) {
        if (dist[i][j][0] == -1) {
            dist[i][j][0] = d;
            exit_id[i][j][0] = e;
            que.emplace(i, j, 0);
        } else if (dist[i][j][1] == -1 and exit_id[i][j][0] != e) {
            dist[i][j][1] = d;
            exit_id[i][j][1] = e;
            que.emplace(i, j, 1);
        }
    };
    for (int e = 0; e < (int)exit.size(); ++e) {
        push(exit[e].first, exit[e].second, 0, e);
    }
    while (!que.empty()) {
        const auto [i, j, k] = que.front();
        que.pop();
        for (int dir = 0; dir < 4; ++dir) {
            int ni = i + dx[dir];
            int nj = j + dy[dir];
            if (grid[ni][nj] != '#') {
                push(ni, nj, dist[i][j][k] + 1, exit_id[i][j][k]);
            }
        }
    }
    int q;
    std::cin >> q;
    while (q--) {
        int a, b, c, d;
        std::cin >> a >> b >> c >> d;
        a += 1, b += 1, c += 1, d += 1;
        for (int k = 0; k < 2; ++k) {
            const auto& [x, y] = exit[exit_id[a][b][k]];
            if (x != c or y != d) {
                std::cout << dist[a][b][k] << '\n';
                break;
            }
        }
    }
    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 35980
final_rank: 3