Problem:
A Two Floors Dungeon
It was the last day of the summer camp you strayed into the labyrinth on the way to Komaba Campus, the University of Tokyo. 
The contest has just begun.
Your teammates  must impatiently wait for you.
So you have to escape from this labyrinth as soon as possible.
The labyrinth is represented by a grid map.
Initially, each grid  except for walls  and stairs is either on the first floor or on the second floor.
Some grids have a switch which can move up or down some of the grids (the grids on the first floor move to the second floor, and the grids on the second floor  to the first floor).
In each step, you can take one of the following actions:
Move to an adjacent grid (includes stairs) on the same floor you  are now in.
Move to another floor (if you  are in the stairs grid).
Operate the switch (if you  are in a grid  with a switch).
Luckily, you have just found a map of the labyrinth for some unknown reason.
Let's calculate the minimum step to escape from the labyrinth, and go to the place your teammates are waiting!
Input
The format of the input is as follows.
W
H
M
11
M
12
M
13
...M
1W
M
21
M
22
M
23
...M
2W
........
M
H1
M
H2
M
H3
...M
HW
S
MS
111
MS
112
MS
113
...MS
11W
MS
121
MS
122
MS
123
...MS
12W
........
MS
1H1
MS
1H2
MS
1H3
...MS
1HW
MS
211
MS
212
MS
213
...MS
21W
MS
221
MS
222
MS
223
...MS
22W
........
MS
2H1
MS
2H2
MS
2H3
...MS
2HW
MS
S11
MS
S12
MS
S13
...MS
S1W
MS
S21
MS
S22
MS
S23
...MS
S2W
........
MS
SH1
MS
SH2
MS
SH3
...MS
SHW
The first line contains two integers
W
(
3 ≤ W ≤ 50
) and
H
(
3 ≤ H ≤ 50
).  They represent the width and height of the labyrinth, respectively.
The following
H
lines represent the initial state of the labyrinth.
Each of
M
ij
is  one of the following symbols:
'#' representing a wall,
'|' representing stairs,
'_' representing a grid which is initially on the first floor,
'^' representing a grid which is initially on the second floor,
a lowercase letter from 'a' to 'j' representing a switch the grid has, and the grid is initially on the first floor,
an uppercase letter from 'A' to 'J' representing a switch the grid has, and the grid is initially on the second floor,
'%' representing  the grid you  are initially in (which is initially on the first floor) or
'&' representing  the exit of the labyrinth (which is initially on the first floor).
The next line contains one integer
S
(
0 ≤ S ≤ 10
), and then the following
SH
lines represent the information of the switches.
Each of
MS
kij
is  one of:
'#' if
M
ij
is a '#',
'|' if
M
ij
is a '|',
'*' if the grid is moved by  the switch represented by the
k
-th alphabet letter, or
'.' otherwise.
Note that the grid which contains a switch may be moved by operating the switch.
In this case, you will move together with the grid.
You may assume each of the '%' (start) and '&' (goal)  appears  exacyly once, that the map is surround by walls, and that each alphabet in the map is any of the letters from 'A' (or 'a') to
S
-th alphabet letter.
Output
Print the mi
...(truncated)

Submitted solutions:

code_snippet: /*
 * main.cpp
 *
 *  Created on: 2014年7月8日
 *      Author: whd
 */

#include <cstdio>
#include <cstring>
#include <iostream>

#define mp make_pair
#define pb push_back

using namespace std;
typedef long long big;

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

int w, h;
char map[1 << 10][50][50];
int id[50][50];
int s;
char swi[10][50][50];
int sx, sy, tx, ty;
bool vis[1 << 10];
struct state {
	int st, f, x, y;
	state() {
	}
	state(int st, int f, int x, int y) :
			st(st), f(f), x(x), y(y) {
	}
} q[(1 << 10) * 2 * 50 * 50];
int qh, qt;
int d[1 << 10][2][50][50];
int ans;

int main() {
	scanf("%d%d", &w, &h);
	memset(id, -1, sizeof id);
	for (int i = 0; i < h; i++) {
		for (int j = 0; j < w; j++) {
			scanf(" %c", &map[0][i][j]);
			if (map[0][i][j] == '%') {
				sx = i, sy = j;
				map[0][i][j] = '_';
			}
			if (map[0][i][j] == '&') {
				tx = i, ty = j;
				map[0][i][j] = '_';
			}
			if ('a' <= map[0][i][j] && map[0][i][j] <= 'z') {
				id[i][j] = map[0][i][j] - 'a';
				map[0][i][j] = '_';
			}
			if ('A' <= map[0][i][j] && map[0][i][j] <= 'Z') {
				id[i][j] = map[0][i][j] - 'A';
				map[0][i][j] = '^';
			}
		}
	}
	scanf("%d", &s);
	for (int k = 0; k < s; k++) {
		for (int i = 0; i < h; i++) {
			for (int j = 0; j < w; j++) {
				scanf(" %c", &swi[k][i][j]);
			}
		}
	}
	vis[0] = true;
	memset(d, -1, sizeof d);
	ans = -1;
	q[qh] = state(0, 0, sx, sy);
	d[0][0][sx][sy] = 0;
	while (qh <= qt) {
		state u = q[qh++], v;
		if ( u.x == tx && u.y == ty) {
			ans = d[u.st][u.f][u.x][u.y];
			break;
		}
//		cout << u.st << " " << u.f << " " << u.x << " " << u.y << " : "
//				<< d[u.st][u.f][u.x][u.y] << endl;
//		for (int i = 0; i < h; i++) {
//			for (int j = 0; j < w; j++) {
//				cout << map[u.st][i][j];
//			}
//			cout << endl;
//		}
		if (map[u.st][u.x][u.y] == '|') {
			v.st = u.st, v.f = u.f ^ 1, v.x = u.x, v.y = u.y;
			if (d[v.st][v.f][v.x][v.y] == -1) {
				d[v.st][v.f][v.x][v.y] = d[u.st][u.f][u.x][u.y] + 1;
				q[++qt] = v;
			}
		}
		if ((map[u.st][u.x][u.y] == '|' && u.f == 0)
				|| map[u.st][u.x][u.y] == '_') {
			for (int dir = 0; dir < 4; dir++) {
				v.st = u.st, v.f = u.f, v.x = u.x + dx[dir], v.y = u.y + dy[dir];
				if ((map[v.st][v.x][v.y] == '|' && v.f == 0)
						|| map[v.st][v.x][v.y] == '_') {
					if (d[v.st][v.f][v.x][v.y] == -1) {
						d[v.st][v.f][v.x][v.y] = d[u.st][u.f][u.x][u.y] + 1;
						q[++qt] = v;
					}
				}
			}
		}
		if ((map[u.st][u.x][u.y] == '|' && u.f == 1)
				|| map[u.st][u.x][u.y] == '^') {
			for (int dir = 0; dir < 4; dir++) {
				v.st = u.st, v.f = u.f, v.x = u.x + dx[dir], v.y = u.y + dy[dir];
				if ((map[v.st][v.x][v.y] == '|' && v.f == 1)
						|| map[v.st][v.x][v.y] == '^') {
					if (d[v.st][v.f][v.x][v.y] == -1) {
						d[v.st][v.f][v.x][v.y] = d[u.st][u.f][u.x][u.y] + 1;
						q[++qt] = v;
					}
				}
			}
		}
		if (id[u.x][u.y] != -1) {
			v.st = u.st ^ (1 << id[u.x][u.y]), v.f = u.f
					^ (swi[id[u.x][u.y]][u.x][u.y] == '*'), v.x = u.x, v.y = u.y;
			if (d[v.st][v.f][v.x][v.y] == -1) {
				d[v.st][v.f][v.x][v.y] = d[u.st][u.f][u.x][u.y] + 1;
				q[++qt] = v;
			}
			if (!vis[v.st]) {
				for (int i = 0; i < h; i++) {
					for (int j = 0; j < w; j++) {
						if (swi[id[u.x][u.y]][i][j] == '*') {
							map[v.st][i][j] = '_' + '^' - map[u.st][i][j];
						} else {
							map[v.st][i][j] = map[u.st][i][j];
						}
					}
				}
			}
		}
	}
	printf("%d\n", ans);
}
accuracy: 1
time_ms: 900
memory_kb: 65032
final_rank: 17

code_snippet: #include <iostream>
#include <iomanip>
#include <cassert>
#include <vector>
#include <algorithm>
#include <utility>
#include <numeric>
#include <queue>
// #include "Src/Utility/BinarySearch.hpp"
// #include "Src/Sequence/CompressedSequence.hpp"
// #include "Src/Sequence/RunLengthEncoding.hpp"
// using namespace zawa;
// #include "atcoder/modint"
// using mint = atcoder::modint998244353;
int W, H, S;
std::string M[50];
std::string T[10][50];
int main() {
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    std::ios::sync_with_stdio(false);
    std::cin >> W >> H;
    for (int i = 0 ; i < H ; i++) std::cin >> M[i];
    std::cin >> S;
    for (int i = 0 ; i < S ; i++) {
        for (int j = 0 ; j < H ; j++) std::cin >> T[i][j];
    }
    int sx = -1, sy = -1, gx = -1, gy = -1;
    for (int i = 0 ; i < H ; i++) for (int j = 0 ; j < W ; j++) {
        if (M[i][j] == '%') {
            sx = i;
            sy = j;
            M[i][j] = '_';
        }
        if (M[i][j] == '&') {
            gx = i;
            gy = j;
            M[i][j] = '_';
        }
    }
    assert(sx != -1);
    assert(gx != -1);
    std::vector state(1 << S, std::vector<std::string>(H));
    for (int bit = 0 ; bit < (1 << S) ; bit++) {
        state[bit] = std::vector(M, M + H);
        for (int i = 0 ; i < H ; i++) for (int j = 0 ; j < W ; j++) {
            if (M[i][j] == '#' or M[i][j] == '|') continue; 
            int flip = 0;
            for (int k = 0 ; k < S ; k++) if ((bit & (1 << k)) and T[k][i][j] == '*') flip ^= 1;
            if (flip) {
                if (state[bit][i][j] == '_' or state[bit][i][j] == '^') {
                    state[bit][i][j] ^= '_' ^ '^';
                }
                else {
                    int id = state[bit][i][j] - ('A' <= state[bit][i][j] and state[bit][i][j] <= 'Z' ? 'A' : 'a');
                    state[bit][i][j] ^= ('A' + id) ^ ('a' + id);
                }
            }
        }
    }
    struct item {
        int f, bit, x, y;
    };
    auto valid = [&](int f, int bit, int x, int y) -> bool {
        assert(0 <= f and f < 2);
        assert(0 <= bit and bit < (1 << S));
        if (x < 0 or x >= H) return false;
        if (y < 0 or y >= W) return false;
        char c = state[bit][x][y];
        if (c == '#') return false;
        if (c == '|') return true;
        if (c == '_' or ('a' <= c and c <= 'z')) return f == 0;
        if (c == '^' or ('A' <= c and c <= 'Z')) return f == 1;
        std::cerr << f << ' ' << bit << ' ' << x << ' ' << y << ' ' << c << std::endl;
        assert(false);
        return false;
    };
    std::vector d(2, std::vector(1 << S, std::vector(H, std::vector<int>(W, -1))));
    std::queue<item> que;
    auto relax = [&](int f, int bit, int x, int y, int v) {
        // std::cout << f << ' ' << bit << ' ' << x << ' ' << y << std::endl;
        assert(0 <= v);
        assert(valid(f, bit, x, y));
        if (d[f][bit][x][y] == -1) {
            d[f][bit][x][y] = v+1;
            que.push({f,bit,x,y});
        }
    };
    const int dx[4]{0,1,0,-1}, dy[4]{1,0,-1,0};
    d[0][0][sx][sy] = 0;
    que.push({0,0,sx,sy});
    while (que.size()) {
        auto [f, bit, x, y] = que.front();
        que.pop();
        assert(valid(f, bit, x, y));
        assert(d[f][bit][x][y] != -1);
        // std::cout << "check adj" << std::endl;
        for (int de = 0 ; de < 4 ; de++) {
            int nx = x+dx[de], ny = y + dy[de];
            if (valid(f, bit, nx, ny)) {
                relax(f, bit, nx, ny, d[f][bit][x][y]);
            }
        }
        if (M[x][y] == '|') {
            // std::cout << "check stair" << std::endl;
            relax(f^1, bit, x, y, d[f][bit][x][y]);
        }
        if (f == 0 and 'a' <= state[bit][x][y] and state[bit][x][y] <= 'z') {
            int nbit = bit^(1<<(state[bit][x][y]-'a'));
            int nf = 'A' <= state[nbit][x][y] and state[nbit][x][y] <= 'Z';
            relax(nf,nbit,x,y,d[f][bit][x][y]);
        }
        if (f == 1 and 'A' <= state[bit][x][y] and state[bit][x][y] <= 'Z') {
            int nbit = bit^(1<<(state[bit][x][y]-'A'));
            int nf = 'A' <= state[nbit][x][y] and state[nbit][x][y] <= 'Z';
            relax(nf,nbit,x,y,d[f][bit][x][y]);
        }
    }
    const int INF = (int)1e9;
    int ans = INF;
    for (int bit = 0 ; bit < (1 << S) ; bit++) {
        int f = state[bit][gx][gy] == '^';
        if (d[f][bit][gx][gy] != -1) ans = std::min(ans, d[f][bit][gx][gy]);
    }
    std::cout << (ans == INF ? -1 : ans) << '\n';
}
accuracy: 1
time_ms: 150
memory_kb: 43136
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for(int i = 0; i < (n); i++)
#define srep(i, s, t) for(int i = (s); i < (t); i++)
#define len(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
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 i64 = long long;
using f64 = long double;
i64 floor_div(const i64 n, const i64 d) { assert(d != 0); return n / d - static_cast<i64>((n ^ d) <  0 && n % d != 0); }
i64  ceil_div(const i64 n, const i64 d) { assert(d != 0); return n / d + static_cast<i64>((n ^ d) >= 0 && n % d != 0); }

constexpr int di[4] = {-1, 0, +1, 0};
constexpr int dj[4] = {0, -1, 0, +1};
int dist[1 << 10][50][50][2] = {};

int main() {
    cin.tie(0)->sync_with_stdio(0);
    
    int W, H; cin >> W >> H;
    using MAP = vector<string>;
    MAP M(H);
    rep(i, H) cin >> M[i];
    int si, sj, ti, tj;
    rep(i, H) rep(j, W) {
        if(M[i][j] == '%') tie(si, sj) = make_pair(i, j), M[i][j] = '_';
        if(M[i][j] == '&') tie(ti, tj) = make_pair(i, j), M[i][j] = '_';
    }

    int S; cin >> S;
    vector MS(S, MAP(H));
    rep(k, S) rep(i, H) cin >> MS[k][i];

    vector MT(1 << S, MAP(H));
    rep(ss, 1 << S) {
        MT[ss] = M;
        rep(id, S) if(ss >> id & 1) {
            rep(i, H) rep(j, W) if(MS[id][i][j] == '*') {
                char& c = MT[ss][i][j];
                     if(c == '#') continue;
                else if(c == '|') continue;
                else if(c == '_') c = '^';
                else if(c == '^') c = '_';
                else if(islower(c)) c = (char)toupper(c);
                else if(isupper(c)) c = (char)tolower(c);
            }
        }
    }

    auto FLOOR = [&](char c) {
        if(c == '_') return 0;
        if(c == '^') return 1;
        if(islower(c)) return 0;
        if(isupper(c)) return 1;
        return -1;
    };
    const int INF = 1e9;
    rep(ss, 1 << S) rep(i, H) rep(j, W) rep(f, 2) dist[ss][i][j][f] = INF;
    queue<tuple<int, int, int, int>> q;
    dist[0][si][sj][0] = 0;
    q.push({0, si, sj, 0});
    while(not q.empty()) {
        auto [ss, i, j, f] = q.front(); q.pop();
        const int nd = dist[ss][i][j][f] + 1;
        rep(d, 4) {
            int ni = i + di[d], nj = j + dj[d];
            if(0 <= ni and ni < H and 0 <= nj and nj < W) {
                const char nc = MT[ss][ni][nj];
                if(nc == '|' or f == FLOOR(nc)) {
                    if(chmin(dist[ss][ni][nj][f], nd)) {
                        q.push({ss, ni, nj, f});
                    }
                }
            }
        }
        if(MT[ss][i][j] == '|') {
            if(chmin(dist[ss][i][j][f ^ 1], nd)) {
                q.push({ss, i, j, f ^ 1});
            }
        }

        const char c = MT[ss][i][j];
        if(isalpha(c) and FLOOR(c) == f) {
            int id = c - (islower(c) ? 'a' : 'A');
            int nss = ss ^ (1 << id);
            int nf = FLOOR(MT[nss][i][j]);
            if(chmin(dist[nss][i][j][nf], nd)) {
                q.push({nss, i, j, nf});
            }
        }
    }
    int ans = INF;
    rep(ss, 1 << S) chmin<int>(ans, dist[ss][ti][tj][FLOOR(MT[ss][ti][tj])]);
    cout << (ans == INF ? -1 : ans) << "\n";
}
accuracy: 1
time_ms: 140
memory_kb: 28832
final_rank: 7

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

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

int main() {
    int N, M, K;
    cin >> M >> N;
    vector<vector<int>> Floor(N,vector<int>(M,0));
    vector<vector<int>> Button(N,vector<int>(M,-1));
    int SX, SY, GX, GY;
    rep(i,0,N) {
        string S;
        cin >> S;
        rep(j,0,M) {
            if (S[j] == '#') Floor[i][j] = -1;
            if (S[j] == '|') Floor[i][j] = 2;
            if (S[j] == '_') Floor[i][j] = 0;
            if (S[j] == '^') Floor[i][j] = 1;
            if ('a' <= S[j] && S[j] <= 'j') Floor[i][j] = 0, Button[i][j] = S[j]-'a';
            if ('A' <= S[j] && S[j] <= 'J') Floor[i][j] = 1, Button[i][j] = S[j]-'A';
            if (S[j] == '%') SX = i, SY = j, Floor[i][j] = 0;
            if (S[j] == '&') GX = i, GY = j, Floor[i][j] = 0;
        }
    }
    vector<vector<int>> Flip(N,vector<int>(M,0));
    cin >> K;
    rep(i,0,K) {
        rep(j,0,N) {
            string S;
            cin >> S;
            rep(k,0,M) {
                if (S[k] == '*') Flip[j][k] |= (1<<i);
            }
        }
    }
    vector<int> DP(N*M*2*(1<<K),inf);
    auto encode = [&](int x, int y, int floor, int flip) -> int {return x*M*2*(1<<K)+y*2*(1<<K)+floor*(1<<K)+flip;};
    auto decode = [&](int e) -> tuple<int,int,int,int> {return {e/(M*2*(1<<K)),(e/(2*(1<<K)))%M,(e/(1<<K))%2,e%(1<<K)};};
    queue<int> Q;
    DP[encode(SX,SY,0,0)] = 0;
    Q.push(encode(SX,SY,0,0));
    int dx[4] = {1,0,-1,0}, dy[4] = {0,1,0,-1};
    auto canmove = [&](int x, int y, int floor, int flip) -> bool {
        if (x < 0 || N <= x || y < 0 || M <= y) return false;
        if (Floor[x][y] == 2) return true;
        if (Floor[x][y] == -1) return false;
        int nowfloor = (Floor[x][y] + popcnt(flip & Flip[x][y])) % 2;
        return nowfloor == floor;
    };
    while(!Q.empty()) {
        int P = Q.front();
        Q.pop();
        auto [X,Y,floor,flip] = decode(P);

        //move
        rep(i,0,4) {
            int NX = X + dx[i], NY = Y + dy[i];
            if (canmove(NX,NY,floor,flip)) {
                if (chmin(DP[encode(NX,NY,floor,flip)],DP[P]+1)) {
                    Q.push(encode(NX,NY,floor,flip));
                }
            }
        }

        //updown
        if (Floor[X][Y] == 2) {
            int nfloor = 1 - floor;
            if (chmin(DP[encode(X,Y,nfloor,flip)],DP[P]+1)) {
                Q.push(encode(X,Y,nfloor,flip));
            }
        }

        //push button
        if (Button[X][Y] >= 0) {
            int nflip = flip ^ (1 << Button[X][Y]);
            int nfloor;
            if (Flip[X][Y] & (1 << Button[X][Y])) nfloor = 1 - floor;
            else nfloor = floor;
            if (chmin(DP[encode(X,Y,nfloor,nflip)],DP[P]+1)) {
                Q.push(encode(X,Y,nfloor,nflip));
            }
        }
    }
    int ANS = inf;
    rep(i,0,1<<K) chmin(ANS,DP[encode(GX,GY,popcnt(Flip[GX][GY] & i) % 2,i)]);
    cout << (ANS == inf ? -1 : ANS) << endl;
}
accuracy: 1
time_ms: 120
memory_kb: 23352
final_rank: 2

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

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

int main() {
    int N, M, K;
    cin >> M >> N;
    vector<vector<int>> Floor(N,vector<int>(M,0));
    vector<vector<int>> Button(N,vector<int>(M,-1));
    int SX, SY, GX, GY;
    rep(i,0,N) {
        string S;
        cin >> S;
        rep(j,0,M) {
            if (S[j] == '#') Floor[i][j] = -1;
            if (S[j] == '|') Floor[i][j] = 2;
            if (S[j] == '_') Floor[i][j] = 0;
            if (S[j] == '^') Floor[i][j] = 1;
            if ('a' <= S[j] && S[j] <= 'j') Floor[i][j] = 0, Button[i][j] = S[j]-'a';
            if ('A' <= S[j] && S[j] <= 'J') Floor[i][j] = 1, Button[i][j] = S[j]-'A';
            if (S[j] == '%') SX = i, SY = j, Floor[i][j] = 0;
            if (S[j] == '&') GX = i, GY = j, Floor[i][j] = 0;
        }
    }
    vector<vector<int>> Flip(N,vector<int>(M,0));
    cin >> K;
    rep(i,0,K) {
        rep(j,0,N) {
            string S;
            cin >> S;
            rep(k,0,M) {
                if (S[k] == '*') Flip[j][k] |= (1<<i);
            }
        }
    }
    vector<int> DP(N*M*2*(1<<K),inf);
    auto encode = [&](int x, int y, int floor, int flip) -> int {return x*M*2*(1<<K)+y*2*(1<<K)+floor*(1<<K)+flip;};
    auto decode = [&](int e) -> tuple<int,int,int,int> {return {e/(M*2*(1<<K)),(e/(2*(1<<K)))%M,(e/(1<<K))%2,e%(1<<K)};};
    queue<int> Q;
    DP[encode(SX,SY,0,0)] = 0;
    Q.push(encode(SX,SY,0,0));
    int dx[4] = {1,0,-1,0}, dy[4] = {0,1,0,-1};
    auto canmove = [&](int x, int y, int floor, int flip) -> bool {
        if (x < 0 || N <= x || y < 0 || M <= y) return false;
        if (Floor[x][y] == 2) return true;
        if (Floor[x][y] == -1) return false;
        int nowfloor = (Floor[x][y] + popcnt(flip & Flip[x][y])) % 2;
        return nowfloor == floor;
    };
    while(!Q.empty()) {
        int P = Q.front();
        Q.pop();
        auto [X,Y,floor,flip] = decode(P);

        //move
        rep(i,0,4) {
            int NX = X + dx[i], NY = Y + dy[i];
            if (canmove(NX,NY,floor,flip)) {
                if (chmin(DP[encode(NX,NY,floor,flip)],DP[P]+1)) {
                    Q.push(encode(NX,NY,floor,flip));
                }
            }
        }

        //updown
        if (Floor[X][Y] == 2) {
            int nfloor = 1 - floor;
            if (chmin(DP[encode(X,Y,nfloor,flip)],DP[P]+1)) {
                Q.push(encode(X,Y,nfloor,flip));
            }
        }

        //push button
        if (Button[X][Y] >= 0) {
            int nflip = flip ^ (1 << Button[X][Y]);
            int nfloor;
            if (Flip[X][Y] & (1 << Button[X][Y])) nfloor = 1 - floor;
            else nfloor = floor;
            if (chmin(DP[encode(X,Y,nfloor,nflip)],DP[P]+1)) {
                Q.push(encode(X,Y,nfloor,nflip));
            }
        }
    }
    int ANS = inf;
    rep(i,0,1<<K) chmin(ANS,DP[encode(GX,GY,popcnt(Flip[GX][GY] & i),i)]);
    cout << (ANS == inf ? -1 : ANS) << endl;
}
accuracy: 0.08333333333333333
time_ms: 30
memory_kb: 7092
final_rank: 18

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

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

int main() {
    int N, M, K;
    cin >> M >> N;
    vector<vector<int>> Floor(N,vector<int>(M,0));
    vector<vector<int>> Button(N,vector<int>(M,-1));
    int SX, SY, GX, GY;
    rep(i,0,N) {
        string S;
        cin >> S;
        rep(j,0,M) {
            if (S[j] == '#') Floor[i][j] = -1;
            if (S[j] == '|') Floor[i][j] = 2;
            if (S[j] == '_') Floor[i][j] = 0;
            if (S[j] == '^') Floor[i][j] = 1;
            if ('a' <= S[j] && S[j] <= 'j') Floor[i][j] = 0, Button[i][j] = S[j]-'a';
            if ('A' <= S[j] && S[j] <= 'J') Floor[i][j] = 1, Button[i][j] = S[j]-'A';
            if (S[j] == '%') SX = i, SY = j, Floor[i][j] = 0;
            if (S[j] == '&') GX = i, GY = j, Floor[i][j] = 0;
        }
    }
    vector<vector<int>> Flip(N,vector<int>(M,0));
    cin >> K;
    rep(i,0,K) {
        rep(j,0,N) {
            string S;
            cin >> S;
            rep(k,0,M) {
                if (S[k] == '*') Flip[j][k] |= (1<<i);
            }
        }
    }
    vector<int> DP(N*M*2*(1<<K),inf);
    auto encode = [&](int x, int y, int floor, int flip) -> int {return x*M*2*(1<<K)+y*2*(1<<K)+floor*(1<<K)+flip;};
    auto decode = [&](int e) -> tuple<int,int,int,int> {return {e/(M*2*(1<<K)),(e/(2*(1<<K)))%M,(e/(1<<K))%2,e%(1<<K)};};
    queue<int> Q;
    DP[encode(SX,SY,0,0)] = 0;
    Q.push(encode(SX,SY,0,0));
    int dx[4] = {1,0,-1,0}, dy[4] = {0,1,0,-1};
    auto canmove = [&](int x, int y, int floor, int flip) -> bool {
        if (x < 0 || N <= x || y < 0 || M <= y) return false;
        if (Floor[x][y] == 2) return true;
        if (Floor[x][y] == -1) return false;
        int nowfloor = (Floor[x][y] + popcnt(flip & Flip[x][y])) % 2;
        return nowfloor == floor;
    };
    while(!Q.empty()) {
        int P = Q.front();
        Q.pop();
        auto [X,Y,floor,flip] = decode(P);

        //move
        rep(i,0,4) {
            int NX = X + dx[i], NY = Y + dy[i];
            if (canmove(NX,NY,floor,flip)) {
                if (chmin(DP[encode(NX,NY,floor,flip)],DP[P]+1)) {
                    Q.push(encode(NX,NY,floor,flip));
                }
            }
        }

        //updown
        if (Floor[X][Y] == 2) {
            int nfloor = 1 - floor;
            if (chmin(DP[encode(X,Y,nfloor,flip)],DP[P]+1)) {
                Q.push(encode(X,Y,nfloor,flip));
            }
        }

        //push button
        if (Button[X][Y] >= 0) {
            int nflip = flip ^ (1 << Button[X][Y]);
            int nfloor;
            if (Flip[X][Y] & (1 << Button[X][Y])) nfloor = 1 - floor;
            else nfloor = floor;
            if (chmin(DP[encode(X,Y,nfloor,nflip)],DP[P]+1)) {
                Q.push(encode(X,Y,nfloor,nflip));
            }
        }
    }
    int ANS = inf;
    rep(i,0,1<<K) chmin(ANS,DP[encode(GX,GY,0,i)]);
    cout << (ANS == inf ? -1 : ANS) << endl;
}
accuracy: 0.05555555555555555
time_ms: 10
memory_kb: 4180
final_rank: 19

code_snippet: #include<bits/stdc++.h>
#define rep(i,a,...) for(int i = (a)*(strlen(#__VA_ARGS__)!=0);i<(int)(strlen(#__VA_ARGS__)?__VA_ARGS__:(a));++i)
#define per(i,a,...) for(int i = (strlen(#__VA_ARGS__)?__VA_ARGS__:(a))-1;i>=(int)(strlen(#__VA_ARGS__)?(a):0);--i)
#define foreach(i, n) for(auto &i:(n))
#define all(x) (x).begin(), (x).end()
#define bit(x) (1ll << (x))
#define lambda(RES_TYPE, ...) (function<RES_TYPE(__VA_ARGS__)>)[&](__VA_ARGS__) -> RES_TYPE
#define method(FUNC_NAME, RES_TYPE, ...) function<RES_TYPE(__VA_ARGS__)> FUNC_NAME = lambda(RES_TYPE, __VA_ARGS__)
using namespace std;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
//const ll MOD = (ll)1e9+7;
const ll MOD = 998244353;
const int INF = (ll)1e9+7;
const ll INFLL = (ll)1e18;
template<class t>
using vvector = vector<vector<t>>;
template<class t>
using vvvector = vector<vector<vector<t>>>;
template<class t>
using vvvvector = vvector<vector<vector<t>>>;
template<class t>
using priority_queuer = priority_queue<t, vector<t>, greater<t>>;
template<class t, class u> bool chmax(t &a, u b){if(a<b){a=b;return true;}return false;}
template<class t, class u> bool chmin(t &a, u b){if(a>b){a=b;return true;}return false;}
#ifdef DEBUG
#define debug(x) cout<<"LINE "<<__LINE__<<": "<<#x<<" = "<<x<<endl;
#else
#define debug(x) (void)0
#endif

namespace templates{
    ll modpow(ll x, ll b,ll mod=MOD){
        ll res = 1;
        while(b){
            if(b&1)res = res * x % mod;
            x = x * x % mod;
            b>>=1;
        }
        return res;
    }

    ll modinv(ll x){
        return modpow(x, MOD-2);
    }

    bool was_output = false;

    void print();
    template <class t> void print(const vector<t> &);
    template <class t, class u> void print(const pair<t, u> &);
    template <class t> void print(const t&);
    template <class Head, class... Tail> void print(const Head&, const Tail&...);

    template <class t> void println(const vector<vector<t>>&);
    template <class t> void println(const vector<t>&);
    template <class t> void println(const t&);
    template <class Head, class... Tail> void println(const Head&, const Tail&...);
    void println();
    void newline();

    void print(){
        return;
    }

    template <class t>
    void print(const vector<t>&x){
        for(const t&i:x)print(i);
    }
    template <class t, class u>
    void print(const pair<t,u>&p){
        print(p.first);
        print(p.second);
    }
    template <class t>
    void print(const t&x){
        if(was_output)cout<<" ";
        cout<<x;
        was_output = true;
    }
    template <class Head, class... Tail>
    void print(const Head&head,const Tail&...tail){
        print(head);
        print(tail...);
    }

    template<class t>
    void println(const vector<vector<t>>&x){
        for(vector<t> i:x)println(i);
    }
    template<class t>
    void println(const vector<t>&x){
        for(const t&i:x)print(i);
        println();
    }
    template <class t>
    void println(const t&x){
        print(x);
        println();
    }
    void println(){
        if(was_output){
            cout << endl;
            was_output = false;
        }
    }
    template <class Head, class... Tail>
    void println(const Head&head,const Tail&...tail){
        print(head);
        println(tail...);
    }

    void newline(){
        was_output = true;
        println();
    }

    template<class t>
    istream& operator>>(istream&is, vector<t>&x){
        for(auto &i:x)is >> i;
        return is;
    }

    template<class t, class u>
    istream& operator>>(istream&is, pair<t, u>&x){
        is >> x.first >> x.second;
        return is;
    }

    template<class t>
    ostream& operator<<(ostream&os, vector<t> &v){
        os << "{";
        for(t &i:v){
            os << i << ", ";
        }
        os << "}";
        return os;
    }

    template<class t = long long>
    t in(){
        t res; cin >> res; return res;
    }

    template<class t>
    vector<t> sorted(vector<t> line,function<bool(t,t)> comp=[](t a,t b){return a<b;}){
        sort(line.begin(),line.end(),comp);
        return line;
    }

    template<class t>
    vector<t> reversed(vector<t> line){
        reverse(line.begin(),line.end());
        return line;
    }
    string reversed(string str){
        reverse(str.begin(),str.end());
        return str;
    }

    long long gcd(long long a,long long b){
        while(b){
            a %= b;
            swap(a,b);
        }
        return a;
    }

    long long lcm(long long a,long long b){
        return a / gcd(a,b) * b;
    }

    class output_initializer{
    public:
        output_initializer(){
            ios::sync_with_stdio(false);
            cin.tie(nullptr);
            cout << setprecision(20);
        }
    };output_initializer OUTPUT_INITIALIZER_INSTANCE = output_initializer();
}

using namespace templates;

int func(){
    int w = in();
    int h = in();
    vvector<int> floor(h,vector<int>(w,0));
    vvector<int> switches(h,vector<int>(w,0));
    int sx;
    int sy;
    int gx;
    int gy;
        
    rep(i,h)rep(j,w){
        char c = in<char>();
        if(c=='|'){
            floor[i][j] = 3;
        }else if(c=='_'){
            floor[i][j] = 1;
        }else if(c=='^'){
            floor[i][j] = 2;
        }else if('a' <= c and c <= 'z'){
            switches[i][j] = c - 'a' + 1;
            floor[i][j] = 1;
        }else if('A' <= c and c <= 'Z'){
            switches[i][j] = c - 'A' + 1;
            floor[i][j] = 2;
        }else if(c=='%'){
            floor[i][j] = 1;
            sx = j;
            sy = i;
        }else if(c=='&'){
            floor[i][j] = 1;
            gx = j;
            gy = i;
        }else if(c=='#'){
        }else{
            cerr << "INVALID CHAR" << endl;
            exit(1);
        }
    }
    int q = in();
    vvvector<int> toggles(q,vvector<int>(h,vector<int>(w,0)));
    rep(t,q){
        rep(i,h){
            rep(j,w){
                char c = in<char>();
                if(c=='*'){
                    toggles[t][i][j] = 3;
                }
            }
        }
    }
    vvvvector<int> fast(4,vvvector<int>(h,vvector<int>(w,vector<int>(bit(q),INF))));
    priority_queuer<pair<int,array<int,4>>> pq;
    method(isin,bool,int y,int x){
        return 0 <= y and y < h and 0 <= x and x < w;
    };
    method(valid,bool,int f,int y,int x,int used){
        if(not isin(y,x))return false;
        int sum = floor[y][x];
        rep(i,q){
            if(used & bit(i)){
                sum ^= toggles[i][y][x];
            }
        }
        return sum & f;
    };
    method(moves,vector<pii>,int f,int y,int x,int used){
        if(not isin(y,x))return {};
        int dx[]={1,0,-1,0};
        int dy[]={0,1,0,-1};
        vector<pii> res;
        rep(i,4){
            if(valid(f,y+dy[i],x+dx[i],used)){
                res.emplace_back(y+dy[i],x+dx[i]);
            }
        }
        return move(res);
    };
    method(add,void,int f,int y,int x,int used,int t){
        if(chmin(fast[f][y][x][used],t)){
            pq.emplace(t,array<int,4>({f,y,x,used}));
        }
    };
    add(1,sy,sx,0,0);
    while(pq.size()){
        auto current = pq.top();
        pq.pop();
        int t = current.first;
        int f = current.second[0];
        int y = current.second[1];
        int x = current.second[2];
        int used = current.second[3];
        if(fast[f][y][x][used] != t)continue;
        foreach(mv,moves(f,y,x,used)){
            add(f,mv.first,mv.second,used,t+1);
        }
        if(valid(f^3,y,x,used)){
            add(f^3,y,x,used,t+1);
        }
        if(switches[y][x]){
            int p = switches[y][x] - 1;
            int nused = used ^ bit(p);
            if(valid(f,y,x,nused)){
                add(f,y,x,nused,t+1);
            }
            if(valid(f^3,y,x,nused)){
                add(f^3,y,x,nused,t+1);
            }
        }
    }
    int ans = INF;
    foreach(i,fast[1][gy][gx]){
        chmin(ans,i);
    }
    foreach(i,fast[2][gy][gx]){
        chmin(ans,i);
    }
    if(ans==INF)return -1;
    return ans;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    println(func());
    return 0;
}
accuracy: 1
time_ms: 920
memory_kb: 54040
final_rank: 16

code_snippet: #include <cstdio>
#include <iostream>
#include <vector>
#include <map>
#include <queue>
using namespace std;

int main() {
  // printf("%d\n", 50 * 50 * (1<<10) * 2);
  int n, m;
  scanf("%d%d", &m, &n);
  vector<string> s(n);
  int x0, y0;
  int x1, y1;
  for (int i = 0; i < n; i++) { 
    cin >> s[i];
    for (int j = 0; j < m; j++) {
      if (s[i][j] == '%') x0 = i, y0 = j;
      if (s[i][j] == '&') x1 = i, y1 = j;
    }
  }
  int k;
  scanf("%d", &k);
  vector<vector<int>> tag(k, vector<int>(n * m));
  for (int it = 0; it < k; it++) {
    for (int i = 0; i < n; i++) {
      string s;
      cin >> s;
      for (int j = 0; j < m; j++) {
        if (s[j] == '*') {
          int u = i * m + j;
          tag[it][u] = 1;
        }
      }
    }
  } 
  struct State {
    int s; // switch
    int u; // r, c
    int t; // floor
    bool operator < (const State& o) const {
      if (s != o.s) return s < o.s;
      if (u != o.u) return u < o.u;
      return t < o.t;
    }
  };
  //map<State, int> d;
  int maxn = 1 + (n * m - 1) * 2 + ((1 << k) - 1) * (1 + 2 * (n * m - 1) + 1);
  vector<int> d(maxn + 1, -1);
  auto ids = [&](int r, int c) { return r * m + c; };
  auto gets = [&](char c) {
    if (c >= 'a' && c <= 'z') return c - 'a';
    if (c >= 'A' && c <= 'Z') return c - 'A';
    return -1;
  };
  auto getf = [&](int msk, int r, int c) { 
    int t = 0;
    if (s[r][c] >= 'A' && s[r][c] <= 'Z') t = 1;
    if (s[r][c] == '^') t = 1; 
    int u = r * m + c;
    for (int i = 0; i < k; i++) {
      if ((msk & (1<<i)) && tag[i][u]) t = !t;
    }
    return t;
  };
  auto id = [&](State u) {
    return u.t + u.u * 2 + u.s * (1 + 2 * (n * m - 1) + 1);
  };
  auto st = State{0, ids(x0, y0), 0};
  queue<State> Q;
  d[id(st)] = 0;
  Q.push(st);
  int dx[4] = {-1, 1, 0, 0};
  int dy[4] = {0, 0, -1, 1};
  int ans = -1;
  while (Q.size() != 0) {
    auto cur = Q.front();
    Q.pop();
    int msk = cur.s;
    int u = cur.u;
    int t = cur.t;
    int r = u / m, c = u % m;
    // printf("msk = %d, r = %d, c = %d, t = %d: %d\n", msk, r, c, t, d[cur]);
    if (r == x1 && c == y1) {
      ans = d[id(cur)];
      break;   
    }
    int it = gets(s[r][c]);
    if (it != -1) {
      int nt = t;
      if (tag[it][u]) nt = !nt;
      auto nxt = State{msk ^ (1<<it), u, nt};
      // if (!d.count(nxt)) {
      if (d[id(nxt)] == -1) {
        d[id(nxt)] = d[id(cur)] + 1;
        Q.push(nxt); 
      }
    }
    if (s[r][c] == '|') {
      auto nxt = State{msk, u, !t};
      if (d[id(nxt)] == -1) {
        d[id(nxt)] = d[id(cur)] + 1;
        Q.push(nxt); 
      }
    }
    for (int i = 0; i < 4; i++) {
      int x = r + dx[i];
      int y = c + dy[i];
      if (x >= 0 && x < n && y >= 0 && y < m && s[r][c] != '#') {
        int nt = -1;
        if (s[x][y] == '|') nt = t;
        else nt = getf(msk, x, y);
        if (nt == t) {
          auto nxt = State{msk, x * m + y, nt};
          if (d[id(nxt)] == -1) {
            d[id(nxt)] = d[id(cur)] + 1;
            Q.push(nxt); 
          }
        }
      }
    }
  }
  printf("%d\n", ans);
  return 0; 
}
// 4, 2, 0
// 4, 3, 0
// 3, 3, 0
// 3, 3, 1
// 3, 4, 1
// 3, 4, 0
// 2, 4, 0
// 1, 4, 0
accuracy: 1
time_ms: 170
memory_kb: 23808
final_rank: 4

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

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


int dist[1<<10][50][50][2];

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    vector<int> di = {0, 1, 0, -1};
    vector<int> dj = {1, 0, -1, 0};
    int W, H;
    cin >> W >> H;
    vector<string> M(H);
    for (auto& x : M) cin >> x;
    int S;
    cin >> S;
    vector<vector<string>> MS(S, vector<string>(H));
    for (auto& m : MS) for (auto& x : m) cin >> x;
    int si, sj, gi, gj;
    rep(i,0,H) rep(j,0,W) {
        if (M[i][j] == '%') si = i, sj = j;
        if (M[i][j] == '&') gi = i, gj = j;
    }

    auto check_floor = [&](int s, int i, int j) -> int {
        int f = 0;
        if ('A' <= M[i][j] && M[i][j] <= 'J') f = 1;
        if (M[i][j] == '^') f = 1;
        rep(k,0,S) {
            if (s>>k&1 && MS[k][i][j] == '*') {
                f ^= 1;
            }
        }
        return f;
    };

    rep(s,0,1<<S) rep(i,0,H) rep(j,0,W) rep(f,0,2) dist[s][i][j][f] = -1;
    queue<tuple<int, int, int, int>> que;
    que.push({0, si, sj, 0});
    dist[0][si][sj][0] = 0;

    while (!que.empty()) {
        auto [s, i, j, f] = que.front(); que.pop();
        if (M[i][j] == '|') {
            if (dist[s][i][j][f^1] == -1) {
                dist[s][i][j][f^1] = dist[s][i][j][f] + 1;
                que.push({s, i, j, f^1});
            }
        }
        if (('a' <= M[i][j] && M[i][j] <= 'j') || ('A' <= M[i][j] && M[i][j] <= 'J')) {
            int t = s;
            if ('a' <= M[i][j] && M[i][j] <= 'j') t ^= 1 << (M[i][j]-'a');
            else t ^= 1 << (M[i][j]-'A');
            int nf = check_floor(t, i, j);
            if (dist[t][i][j][nf] == -1) {
                dist[t][i][j][nf] = dist[s][i][j][f] + 1;
                que.push({t, i, j, nf});
            }
        }
        rep(k,0,4) {
            int ni = i+di[k], nj = j+dj[k];
            if (M[ni][nj] != '#' && (M[ni][nj] == '|' || check_floor(s, ni, nj) == f)
                && dist[s][ni][nj][f] == -1) {
                dist[s][ni][nj][f] = dist[s][i][j][f] + 1;
                que.push({s, ni, nj, f});
            }
        }
    }

    int ans = 1e9;
    rep(s,0,1<<S) rep(f,0,2) if (dist[s][gi][gj][f] != -1) ans = min(ans, dist[s][gi][gj][f]);
    cout << (ans < 1e9 ? ans : -1) << endl;
}
accuracy: 1
time_ms: 210
memory_kb: 24096
final_rank: 6

code_snippet: // #pragma comment(linker, "/stack:200000000")

#include <bits/stdc++.h>

#include <limits>
#include <type_traits>

namespace suisen {
// ! utility
template <typename ...Types>
using constraints_t = std::enable_if_t<std::conjunction_v<Types...>, std::nullptr_t>;
template <bool cond_v, typename Then, typename OrElse>
constexpr decltype(auto) constexpr_if(Then&& then, OrElse&& or_else) {
    if constexpr (cond_v) {
        return std::forward<Then>(then);
    } else {
        return std::forward<OrElse>(or_else);
    }
}

// ! function
template <typename ReturnType, typename Callable, typename ...Args>
using is_same_as_invoke_result = std::is_same<std::invoke_result_t<Callable, Args...>, ReturnType>;
template <typename F, typename T>
using is_uni_op = is_same_as_invoke_result<T, F, T>;
template <typename F, typename T>
using is_bin_op = is_same_as_invoke_result<T, F, T, T>;

template <typename Comparator, typename T>
using is_comparator = std::is_same<std::invoke_result_t<Comparator, T, T>, bool>;

// ! integral
template <typename T, typename = constraints_t<std::is_integral<T>>>
constexpr int bit_num = std::numeric_limits<std::make_unsigned_t<T>>::digits;
template <typename T, unsigned int n>
struct is_nbit { static constexpr bool value = bit_num<T> == n; };
template <typename T, unsigned int n>
static constexpr bool is_nbit_v = is_nbit<T, n>::value;

// ?
template <typename T>
struct safely_multipliable {};
template <>
struct safely_multipliable<int> { using type = long long; };
template <>
struct safely_multipliable<long long> { using type = __int128_t; };
template <>
struct safely_multipliable<float> { using type = float; };
template <>
struct safely_multipliable<double> { using type = double; };
template <>
struct safely_multipliable<long double> { using type = long double; };
template <typename T>
using safely_multipliable_t = typename safely_multipliable<T>::type;

} // namespace suisen

// ! type aliases
using i128 = __int128_t;
using u128 = __uint128_t;
using ll = long long;
using uint = unsigned int;
using ull  = unsigned long long;

template <typename T> using vec  = std::vector<T>;
template <typename T> using vec2 = vec<vec <T>>;
template <typename T> using vec3 = vec<vec2<T>>;
template <typename T> using vec4 = vec<vec3<T>>;

template <typename T>
using pq_greater = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <typename T, typename U>
using umap = std::unordered_map<T, U>;

// ! macros (capital: internal macro)
#define OVERLOAD2(_1,_2,name,...) name
#define OVERLOAD3(_1,_2,_3,name,...) name
#define OVERLOAD4(_1,_2,_3,_4,name,...) name

#define REP4(i,l,r,s)  for(std::remove_reference_t<std::remove_const_t<decltype(r)>>i=(l);i<(r);i+=(s))
#define REP3(i,l,r)    REP4(i,l,r,1)
#define REP2(i,n)      REP3(i,0,n)
#define REPINF3(i,l,s) for(std::remove_reference_t<std::remove_const_t<decltype(l)>>i=(l);;i+=(s))
#define REPINF2(i,l)   REPINF3(i,l,1)
#define REPINF1(i)     REPINF2(i,0)
#define RREP4(i,l,r,s) for(std::remove_reference_t<std::remove_const_t<decltype(r)>>i=(l)+fld((r)-(l)-1,s)*(s);i>=(l);i-=(s))
#define RREP3(i,l,r)   RREP4(i,l,r,1)
#define RREP2(i,n)     RREP3(i,0,n)

#define rep(...)    OVERLOAD4(__VA_ARGS__, REP4   , REP3   , REP2   )(__VA_ARGS__)
#define rrep(...)   OVERLOAD4(__VA_ARGS__, RREP4  , RREP3  , RREP2  )(__VA_ARGS__)
#define repinf(...) OVERLOAD3(__VA_ARGS__, REPINF3, REPINF2, REPINF1)(__VA_ARGS__)

#define CAT_I(a, b) a##b
#define CAT(a, b) CAT_I(a, b)
#define UNIQVAR(tag) CAT(tag, __LINE__)
#define loop(n) for (std::remove_reference_t<std::remove_const_t<decltype(n)>> UNIQVAR(loop_variable) = n; UNIQVAR(loop_variable) --> 0;)

#define all(iterable) (iterable).begin(), (iterable).end()
#define input(type, ...) type __VA_ARGS__; read(__VA_ARGS__)

// ! I/O utilities

// pair
template <typename T, typename U>
std::ostream& operator<<(std::ostream& out, const std::pair<T, U> &a) {
    return out << a.first << ' ' << a.second;
}
// tuple
template <unsigned int N = 0, typename ...Args>
std::ostream& operator<<(std::ostream& out, const std::tuple<Args...> &a) {
    if constexpr (N >= std::tuple_size_v<std::tuple<Args...>>) {
        return out;
    } else {
        out << std::get<N>(a);
        if constexpr (N + 1 < std::tuple_size_v<std::tuple<Args...>>) {
            out << ' ';
        }
        return operator<<<N + 1>(out, a);
    }
}
// vector
template <typename T>
std::ostream& operator<<(std::ostream& out, const std::vector<T> &a) {
    for (auto it = a.begin(); it != a.end();) {
        out << *it;
        if (++it != a.end()) out << ' ';
    }
    return out;
}
inline void print() { std::cout << '\n'; }
template <typename Head, typename... Tail>
inline void print(const Head &head, const Tail &...tails) {
    std::cout << head;
    if (sizeof...(tails)) std::cout << ' ';
    print(tails...);
}
template <typename Iterable>
auto print_all(const Iterable& v, std::string sep = " ", std::string end = "\n") -> decltype(std::cout << *v.begin(), void()) {
    for (auto it = v.begin(); it != v.end();) {
        std::cout << *it;
        if (++it != v.end()) std::cout << sep;
    }
    std::cout << end;
}

// pair
template <typename T, typename U>
std::istream& operator>>(std::istream& in, std::pair<T, U> &a) {
    return in >> a.first >> a.second;
}
// tuple
template <unsigned int N = 0, typename ...Args>
std::istream& operator>>(std::istream& in, std::tuple<Args...> &a) {
    if constexpr (N >= std::tuple_size_v<std::tuple<Args...>>) {
        return in;
    } else {
        return operator>><N + 1>(in >> std::get<N>(a), a);
    }
}
// vector
template <typename T>
std::istream& operator>>(std::istream& in, std::vector<T> &a) {
    for (auto it = a.begin(); it != a.end(); ++it) in >> *it;
    return in;
}
template <typename ...Args>
void read(Args &...args) {
    ( std::cin >> ... >> args );
}

// ! integral utilities

// Returns pow(-1, n)
template <typename T>
constexpr inline int pow_m1(T n) {
    return -(n & 1) | 1;
}
// Returns pow(-1, n)
template <>
constexpr inline int pow_m1<bool>(bool n) {
    return -int(n) | 1;
}

// Returns floor(x / y)
template <typename T>
constexpr inline T fld(const T x, const T y) {
    return (x ^ y) >= 0 ? x / y : (x - (y + pow_m1(y >= 0))) / y;
}
template <typename T>
constexpr inline T cld(const T x, const T y) {
    return (x ^ y) <= 0 ? x / y : (x + (y + pow_m1(y >= 0))) / y;
}

template <typename T, suisen::constraints_t<suisen::is_nbit<T, 32>> = nullptr>
constexpr inline int popcount(const T x) { return __builtin_popcount(x); }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 64>> = nullptr>
constexpr inline int popcount(const T x) { return __builtin_popcountll(x); }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 32>> = nullptr>
constexpr inline int count_lz(const T x) { return x ? __builtin_clz(x)   : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 64>> = nullptr>
constexpr inline int count_lz(const T x) { return x ? __builtin_clzll(x) : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 32>> = nullptr>
constexpr inline int count_tz(const T x) { return x ? __builtin_ctz(x)   : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 64>> = nullptr>
constexpr inline int count_tz(const T x) { return x ? __builtin_ctzll(x) : suisen::bit_num<T>; }
template <typename T>
constexpr inline int floor_log2(const T x) { return suisen::bit_num<T> - 1 - count_lz(x); }
template <typename T>
constexpr inline int ceil_log2(const T x)  { return floor_log2(x) + ((x & -x) != x); }
template <typename T>
constexpr inline int kth_bit(const T x, const unsigned int k) { return (x >> k) & 1; }
template <typename T>
constexpr inline int parity(const T x) { return popcount(x) & 1; }

struct all_subset {
    struct all_subset_iter {
        const int s; int t;
        constexpr all_subset_iter(int s) : s(s), t(s + 1) {}
        constexpr auto operator*() const { return t; }
        constexpr auto operator++() {}
        constexpr auto operator!=(std::nullptr_t) { return t ? (--t &= s, true) : false; }
    };
    int s;
    constexpr all_subset(int s) : s(s) {}
    constexpr auto begin() { return all_subset_iter(s); }
    constexpr auto end()   { return nullptr; }
};

// ! container

template <typename T, typename Comparator, suisen::constraints_t<suisen::is_comparator<Comparator, T>> = nullptr>
auto priqueue_comp(const Comparator comparator) {
    return std::priority_queue<T, std::vector<T>, Comparator>(comparator);
}

template <typename Iterable>
auto isize(const Iterable &iterable) -> decltype(int(iterable.size())) {
    return iterable.size();
}

template <typename T, typename Gen, suisen::constraints_t<suisen::is_same_as_invoke_result<T, Gen, int>> = nullptr>
auto generate_vector(int n, Gen generator) {
    std::vector<T> v(n);
    for (int i = 0; i < n; ++i) v[i] = generator(i);
    return v;
}

template <typename T>
void sort_unique_erase(std::vector<T> &a) {
    std::sort(a.begin(), a.end());
    a.erase(std::unique(a.begin(), a.end()), a.end());
}

// ! other utilities

// x <- min(x, y). returns true iff `x` has chenged.
template <typename T>
inline bool chmin(T &x, const T &y) {
    if (y >= x) return false;
    x = y;
    return true;
}
// x <- max(x, y). returns true iff `x` has chenged.
template <typename T>
inline bool chmax(T &x, const T &y) {
    if (y <= x) return false;
    x = y;
    return true;
}

namespace suisen {}
using namespace suisen;
using namespace std;

struct io_setup {
    io_setup(int precision = 20) {
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        std::cout << std::fixed << std::setprecision(precision);
    }
} io_setup_{};

// ! code from here

void bit_swap(int &s, int i, int j) {
    int p = (s >> i) & 1;
    int q = (s >> j) & 1;
    s &= ~(1 << i), s |= q << i;
    s &= ~(1 << j), s |= p << j;
}

#include <utility>
#include <vector>

// l <= x < r
template <typename T>
constexpr inline bool in_range(const T &x, const T &l, const T &r) {
    return l <= x and x < r;
}
// 0 <= x < r
template <typename T>
constexpr inline bool in_range(const T &x, const T &r) {
    return (std::make_unsigned_t<T>) x < (std::make_unsigned_t<T>) r;
}
// not (l <= x < r)
template <typename T>
constexpr inline bool out_range(const T &x, const T &l, const T &r) {
    return x < l or r <= x;
}
// not (0 <= x < r)
template <typename T>
constexpr inline bool out_range(const T &x, const T &r) {
    return (std::make_unsigned_t<T>) x >= (std::make_unsigned_t<T>) r;
}

constexpr int dx4[4] = {1, 0, -1, 0};
constexpr int dy4[4] = {0, 1, 0, -1};
constexpr int dx8[8] = {1, 1, 0, -1, -1, -1, 0, 1};
constexpr int dy8[8] = {0, 1, 1, 1, 0, -1, -1, -1};

constexpr std::pair<int, int> dxy4[4] = {
    { dx4[0], dy4[0] }, { dx4[1], dy4[1] }, { dx4[2], dy4[2] }, { dx4[3], dy4[3] },
};
constexpr std::pair<int, int> dxy8[8] = {
    { dx8[0], dy8[0] }, { dx8[1], dy8[1] }, { dx8[2], dy8[2] }, { dx8[3], dy8[3] },
    { dx8[4], dy8[4] }, { dx8[5], dy8[5] }, { dx8[6], dy8[6] }, { dx8[7], dy8[7] },
};

template <int D, auto dx, auto dy>
struct AdjacentCells {
    struct Iterator {
        const int x, y;
        int d;
        bool operator!=(std::nullptr_t) { return d != D; }
        void operator++() { ++d; }
        std::pair<int, int> operator*() { return { x + dx[d], y + dy[d] }; }
    };
    const int x, y;
    AdjacentCells(int x, int y) : x(x), y(y) {}
    auto begin() { return Iterator { x, y, 0 }; }
    constexpr std::nullptr_t end() { return nullptr; }
    operator std::vector<std::pair<int, int>>() {
        std::vector<std::pair<int, int>> res;
        for (const auto &p : *this) res.push_back(p);
        return res;
    }
};

template <int D, auto dx, auto dy>
struct AdjacentCellsBounded {
    struct Iterator {
        const int x, y, xl, xr, yl, yr;
        int d;
        bool operator!=(std::nullptr_t) {
            for (; d != D; ++d) if (in_range(x + dx[d], xl, xr) and in_range(y + dy[d], yl, yr)) return true;
            return false;
        }
        void operator++() { ++d; }
        std::pair<int, int> operator*() { return { x + dx[d], y + dy[d] }; }
    };
    const int x, y, xl, xr, yl, yr;
    AdjacentCellsBounded(int x, int y, int xl, int xr, int yl, int yr) : x(x), y(y), xl(xl), xr(xr), yl(yl), yr(yr) {}
    AdjacentCellsBounded(int x, int y, int xr, int yr) : AdjacentCellsBounded(x, y, 0, xr, 0, yr) {}
    auto begin() { return Iterator { x, y, xl, xr, yl, yr, 0 }; }
    constexpr std::nullptr_t end() { return nullptr; }
    operator std::vector<std::pair<int, int>>() {
        std::vector<std::pair<int, int>> res;
        for (const auto &p : *this) res.push_back(p);
        return res;
    }
};

// [ {x+dx4[i], y+dy4[i]} for i in range(4) ]
using AdjacentFourCells = AdjacentCells<4, dx4, dy4>;
// [ {nx:=x+dx4[i], ny:=y+dy4[i]} for i in range(4) if xl<=nx<xr and yl<=ny<yr ]
using AdjacentFourCellsBounded = AdjacentCellsBounded<4, dx4, dy4>;

// [ {x+dx8[i], y+dy8[i]} for i in range(8) ]
using AdjacentEightCells = AdjacentCells<8, dx8, dy8>;
// [ {nx:=x+dx8[i], ny:=y+dy8[i]} for i in range(8) if xl<=nx<xr and yl<=ny<yr ]
using AdjacentEightCellsBounded = AdjacentCellsBounded<8, dx8, dy8>;

// [ {x+dx4[i], y+dy4[i]} for i in range(4) ]
auto adjacent_four_cells(int x, int y) { return AdjacentFourCells { x, y }; }
// [ {nx:=x+dx4[i], ny:=y+dy4[i]} for i in range(4) if xl<=nx<xr and yl<=ny<yr ]
auto adjacent_four_cells(int x, int y, int xl, int xr, int yl, int yr) { return AdjacentFourCellsBounded { x, y, xl, xr, yl, yr }; }
// [ {nx:=x+dx4[i], ny:=y+dy4[i]} for i in range(4) if 0 <=nx<xr and 0 <=ny<yr ]
auto adjacent_four_cells(int x, int y,         int xr,         int yr) { return AdjacentFourCellsBounded { x, y, 0 , xr, 0 , yr }; }

// [ {x+dx8[i], y+dy8[i]} for i in range(8) ]
auto adjacent_eight_cells(int x, int y) { return AdjacentEightCells { x, y }; }
// [ {nx:=x+dx8[i], ny:=y+dy8[i]} for i in range(8) if xl<=nx<xr and yl<=ny<yr ]
auto adjacent_eight_cells(int x, int y, int xl, int xr, int yl, int yr) { return AdjacentEightCellsBounded { x, y, xl, xr, yl, yr }; }
// [ {nx:=x+dx8[i], ny:=y+dy8[i]} for i in range(8) if 0 <=nx<xr and 0 <=ny<yr ]
auto adjacent_eight_cells(int x, int y,         int xr,         int yr) { return AdjacentEightCellsBounded { x, y, 0 , xr, 0 , yr }; }

constexpr int inf = numeric_limits<int>::max();

int main() {
    input(int, w, h);
    vector<string> g(h);
    read(g);
    input(int, n);
    vector op(n, vector<string>(h));
    read(op);

    int sx = -1, sy = -1, tx = -1, ty = -1;
    rep(i, h) rep(j, w) {
        if (g[i][j] == '%') {
            sx = i, sy = j;
        } else if (g[i][j] == '&') {
            tx = i, ty = j;
        }
    }

    auto get_state = [&](int s, int i, int j) {
        int state;
        if (g[i][j] == '#') {
            state = 0;
        } else if (g[i][j] == '_') {
            state = 1;
        } else if (g[i][j] == '^') {
            state = 2;
        } else if (g[i][j] == '|') {
            state = 3;
        } else if (g[i][j] == '%' or g[i][j] == '&') {
            state = 1;
        } else if (islower(g[i][j])) {
            state = 1;
        } else if (isupper(g[i][j])) {
            state = 2;
        } else {
            assert(false);
        }
        rep(k, n) {
            if (kth_bit(s, k) and op[k][i][j] == '*') {
                bit_swap(state, 0, 1);
            }
        }
        return state;
    };

    auto comp = [&](int f, int s, int i, int j) {
        return f * (h * w * (1 << n)) + s * (h * w) + i * w + j;
    };
    auto decomp = [&](int fsij) {
        int f = fsij / (h * w * (1 << n)), sij = fsij % (h * w * (1 << n));
        int s = sij / (h * w), ij = sij % (h * w);
        int i = ij / w, j = ij % w;
        return make_tuple(f, s, i, j);
    };

    vector<int> dist(2 * ((w * h) << n), inf);
    int src = comp(0, 0, sx, sy);
    dist[src] = 0;
    deque<int> dq{ src };
    while (dq.size()) {
        int fsij = dq.front();
        dq.pop_front();
        auto [f, s, i, j] = decomp(fsij);
        for (auto [ni, nj] : adjacent_four_cells(i, j, h, w)) {
            if (g[ni][nj] == '#') continue;
            int nf = get_state(s, ni, nj);
            if (not kth_bit(nf, f)) continue;
            int nfsij = comp(f, s, ni, nj);
            if (dist[nfsij] == inf) {
                dist[nfsij] = dist[fsij] + 1;
                dq.push_back(nfsij);
            }
        }
        if (g[i][j] == '|') {
            int nfsij = comp(f ^ 1, s, i, j);
            if (dist[nfsij] == inf) {
                dist[nfsij] = dist[fsij] + 1;
                dq.push_back(nfsij);
            }
        }
        
        if (islower(g[i][j]) or isupper(g[i][j])) {
            int k = g[i][j] - (islower(g[i][j]) ? 'a' : 'A');
            int nfsij = comp(f ^ (op[k][i][j] == '*'), s ^ (1 << k), i, j);
            if (dist[nfsij] == inf) {
                dist[nfsij] = dist[fsij] + 1;
                dq.push_back(nfsij);
            }
        }
    }

    int ans = inf;
    rep(f, 2) rep(s, 1 << n) {
        chmin(ans, dist[comp(f, s, tx, ty)]);
    }
    if (ans == inf) {
        print(-1);
    } else {
        print(ans);
    }
    return 0;
}
accuracy: 1
time_ms: 250
memory_kb: 23408
final_rank: 8

code_snippet: #include <cmath>
#include <vector>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <algorithm>
#include <set>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <climits>
#include <array>
#include <unordered_set>
#include <unordered_map>
#include <memory>
#include <functional>
#include <cfloat>
#include <numeric>
#include <random>
#include <sstream>
#include <bitset>
#include <complex>
#include <chrono>
#include <cassert>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>


struct State {
	short switch_state;
	char x, y;
	bool floor;
};
int main() {
	constexpr std::array<int, 4> diff{ 0, -1, 0, 1 };
	int height, width; std::cin >> width >> height;
	std::vector<std::string> maze(height);
	for (auto& line : maze) {
		std::cin >> line;
	}
	int switch_count; std::cin >> switch_count;
	std::vector<std::vector<std::string>> move_block(switch_count, std::vector<std::string>(height));
	for (auto& state : move_block) {
		for (auto& line : state) {
			std::cin >> line;
		}
	}
	const auto initial_floor = [&](const int x, const int y) {
		if (maze[x][y] == '^') return 1;
		if (std::isupper(maze[x][y])) return 1;
		return 0;
	};
	std::vector<std::vector<short>> floor_pos(height, std::vector<short>(width, 0));
	for (auto i = 0; i < move_block.size(); ++i) {
		for (auto x = 0; x < height; ++x) {
			for (auto y = 0; y < width; ++y) {
				if (move_block[i][x][y] == '*') {
					floor_pos[x][y] += 1 << i;
				}
			}
		}
	}
	const auto current_floor = [&](const short switch_state, const char x, const char y) {
		auto result = initial_floor(x, y);
		auto flip = floor_pos[x][y] & switch_state;
		while (flip > 0) {
			result ^= 1;
			flip ^= flip & -flip;
		}
		return result;
	};
	const auto next_state = [&](const State state) {
		const auto [switch_state, x, y, floor] = state;
		std::vector<State> result;
		if (maze[x][y] == '|') {
			result.push_back(State{ switch_state, x, y, !floor });
		}
		else if (std::isalpha(maze[x][y])) {
			const auto switch_type = std::isupper(maze[x][y]) ? maze[x][y] - 'A' : maze[x][y] - 'a';
			const auto moved = move_block[switch_type][x][y] == '*' ? !floor : floor;
			result.push_back(State{ short(switch_state ^ (1 << switch_type)),  x, y, moved });
		}
		for (auto d = 0; d < 4; ++d) {
			const char nx = x + diff[d];
			const char ny = y + diff[(d + 1) & 3];
			if (maze[nx][ny] == '#') continue;
			if (maze[nx][ny] == '|' || current_floor(switch_state, nx, ny) == floor) {
				result.push_back(State{ switch_state, nx, ny, floor });
			}
		}
		return result;
	};
	std::vector<std::vector<std::vector<std::array<char, 2>>>> visit(height, std::vector<std::vector<std::array<char, 2>>>(width, std::vector<std::array<char, 2>>(1 << switch_count, std::array<char, 2>{false, false})));
	std::queue<State> queue;
	int goal_x{ -1 }, goal_y{ -1 };
	for (char x = 0; x < height; ++x) {
		for (char y = 0; y < width; ++y) {
			if (maze[x][y] == '%') {
				queue.push(State{ 0, x, y, 0 });
				visit[x][y][0][0] = true;
			}
			else if (maze[x][y] == '&') {
				goal_x = x;
				goal_y = y;
			}
		}
	}
	int result{ -1 };
	bool reach_to_goal{ false };
	while (!reach_to_goal && !queue.empty()) {
		++result;
		for (int count = queue.size(); count > 0; --count) {
			const auto state = queue.front(); queue.pop();
			if (state.x == goal_x && state.y == goal_y) {
				reach_to_goal = true;
				break;
			}
			for (const auto next : next_state(state)) {
				if (visit[next.x][next.y][next.switch_state][next.floor]) continue;
				visit[next.x][next.y][next.switch_state][next.floor] = true;
				queue.push(next);
			}
		}
	}
	if (!reach_to_goal) {
		result = -1;
	}
	std::cout << result << '\n';
}
accuracy: 1
time_ms: 220
memory_kb: 8868
final_rank: 1

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

const int INF = 1e9;
const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
const int MAX_H = 55, MAX_S = 10;
int dp[MAX_H][MAX_H][2][1 << MAX_S];

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int W, H;
    cin >> W >> H;
    vector<string> M(H);
    int sx, sy, gx, gy;
    for (int i = 0; i < H; i++) {
        cin >> M[i];
        for (int j = 0; j < W; j++) {
            if (M[i][j] == '%') {
                sx = i;
                sy = j;
            } else if (M[i][j] == '&') {
                gx = i, gy = j;
            }
        }
    }
    int S;
    cin >> S;
    vector<vector<string>> MS(S, vector<string>(H));
    for (int k = 0; k < S; k++) {
        for (int i = 0; i < H; i++) {
            cin >> MS[k][i];
        }
    }

    vector<vector<vector<int>>> floor(1 << S, vector<vector<int>>(H, vector<int>(W)));
    for (int mask = 0; mask < (1 << S); mask++) {
        for (int i = 0; i < H; i++) {
            for (int j = 0; j < W; j++) {
                if (M[i][j] == '#') continue;
                if (M[i][j] == '|') continue;
                if (M[i][j] == '^') floor[mask][i][j] ^= 1;
                if ('A' <= M[i][j] && M[i][j] <= 'J') floor[mask][i][j] ^= 1;
                for (int k = 0; k < S; k++) {
                    if ((mask >> k & 1) && (MS[k][i][j] == '*')) {
                        floor[mask][i][j] ^= 1;
                    }
                }
            }
        }
    }

    for (int i = 0; i < H; i++) {
        for (int j = 0; j < W; j++) {
            for (int k = 0; k < 2; k++) {
                for (int mask = 0; mask < (1 << S); mask++) {
                    dp[i][j][k][mask] = INF;
                }
            }
        }
    }
    queue<tuple<int, int, int, int>> que;
    dp[sx][sy][0][0] = 0;
    que.emplace(sx, sy, 0, 0);

    while (!que.empty()) {
        auto t = que.front();
        que.pop();
        int x, y, f, mask;
        tie(x, y, f, mask) = t;
        int val = dp[x][y][f][mask];
        for (int i = 0; i < 4; i++) {
            int nx = x + dx[i], ny = y + dy[i];
            if (nx < 0 || H <= nx || ny < 0 || W <= ny) continue;
            if (M[nx][ny] == '#') continue;
            if (M[nx][ny] != '|' && f != floor[mask][nx][ny]) continue;
            if (dp[nx][ny][f][mask] < INF) continue;
            dp[nx][ny][f][mask] = val + 1;
            que.emplace(nx, ny, f, mask);
        }
        if (M[x][y] == '|' && dp[x][y][f ^ 1][mask] == INF) {
            dp[x][y][f ^ 1][mask] = val + 1;
            que.emplace(x, y, f ^ 1, mask);
        }
        if (('a' <= M[x][y] && M[x][y] <= 'j') || ('A' <= M[x][y] && M[x][y] <= 'J')) {
            int s = ('a' <= M[x][y] && M[x][y] <= 'j' ? M[x][y] - 'a' : M[x][y] - 'A');
            int nmask = mask ^ (1 << s);
            if (dp[x][y][floor[nmask][x][y]][nmask] == INF) {
                dp[x][y][floor[nmask][x][y]][nmask] = val + 1;
                que.emplace(x, y, floor[nmask][x][y], nmask);
            }
        }
    }

    int ans = INF;
    for (int mask = 0; mask < (1 << S); mask++) ans = min(ans, dp[gx][gy][floor[mask][gx][gy]][mask]);
    cout << (ans == INF ? -1 : ans) << '\n';
    return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 38096
final_rank: 13

code_snippet: #define LOCAL
#include <bits/stdc++.h>
using namespace std;
#pragma region Macros
typedef long long ll;
typedef __int128_t i128;
typedef unsigned int uint;
typedef unsigned long long ull;
#define ALL(x) (x).begin(), (x).end()

template <typename T> istream& operator>>(istream& is, vector<T>& v) {
    for (T& x : v) is >> x;
    return is;
}
template <typename T> ostream& operator<<(ostream& os, const vector<T>& v) {
    for (int i = 0; i < (int)v.size(); i++) {
        os << v[i] << (i + 1 == (int)v.size() ? "" : " ");
    }
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const pair<T, U>& p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const map<T, U>& m) {
    os << '{';
    for (auto itr = m.begin(); itr != m.end();) {
        os << '(' << itr->first << ',' << itr->second << ')';
        if (++itr != m.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const unordered_map<T, U>& m) {
    os << '{';
    for (auto itr = m.begin(); itr != m.end();) {
        os << '(' << itr->first << ',' << itr->second << ')';
        if (++itr != m.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const set<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const multiset<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const unordered_set<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const deque<T>& v) {
    for (int i = 0; i < (int)v.size(); i++) {
        os << v[i] << (i + 1 == (int)v.size() ? "" : " ");
    }
    return os;
}

template <int i, typename T> void print_tuple(ostream&, const T&) {}
template <int i, typename T, typename H, class... Args> void print_tuple(ostream& os, const T& t) {
    if (i) os << ',';
    os << get<i>(t);
    print_tuple<i + 1, T, Args...>(os, t);
}
template <typename... Args> ostream& operator<<(ostream& os, const tuple<Args...>& t) {
    os << '{';
    print_tuple<0, tuple<Args...>, Args...>(os, t);
    return os << '}';
}

void debug_out() { cerr << '\n'; }
template <class Head, class... Tail> void debug_out(Head&& head, Tail&&... tail) {
    cerr << head;
    if (sizeof...(Tail) > 0) cerr << ", ";
    debug_out(move(tail)...);
}
#ifdef LOCAL
#define debug(...)                                                                   \
    cerr << " ";                                                                     \
    cerr << #__VA_ARGS__ << " :[" << __LINE__ << ":" << __FUNCTION__ << "]" << '\n'; \
    cerr << " ";                                                                     \
    debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

template <typename T> T gcd(T x, T y) { return y != 0 ? gcd(y, x % y) : x; }
template <typename T> T lcm(T x, T y) { return x / gcd(x, y) * y; }

int topbit(signed t) { return t == 0 ? -1 : 31 - __builtin_clz(t); }
int topbit(long long t) { return t == 0 ? -1 : 63 - __builtin_clzll(t); }
int botbit(signed a) { return a == 0 ? 32 : __builtin_ctz(a); }
int botbit(long long a) { return a == 0 ? 64 : __builtin_ctzll(a); }
int popcount(signed t) { return __builtin_popcount(t); }
int popcount(long long t) { return __builtin_popcountll(t); }
bool ispow2(int i) { return i && (i & -i) == i; }

template <class T> T ceil(T x, T y) {
    assert(y >= 1);
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <class T> T floor(T x, T y) {
    assert(y >= 1);
    return (x > 0 ? x / y : (x - y + 1) / y);
}

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

const int INF = 1e9;
const long long IINF = 1e18;
const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
const char dir[4] = {'D', 'R', 'U', 'L'};
const long long MOD = 1000000007;
// const long long MOD = 998244353;

const int MAX_H = 55, MAX_S = 10;
int dp[MAX_H][MAX_H][2][1 << MAX_S];

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int W, H;
    cin >> W >> H;
    vector<string> M(H);
    int sx, sy, gx, gy;
    for (int i = 0; i < H; i++) {
        cin >> M[i];
        for (int j = 0; j < W; j++) {
            if (M[i][j] == '%') {
                sx = i;
                sy = j;
            } else if (M[i][j] == '&') {
                gx = i, gy = j;
            }
        }
    }
    int S;
    cin >> S;
    vector<vector<string>> MS(S, vector<string>(H));
    for (int k = 0; k < S; k++) {
        for (int i = 0; i < H; i++) {
            cin >> MS[k][i];
        }
    }

    vector<vector<vector<int>>> floor(1 << S, vector<vector<int>>(H, vector<int>(W)));
    for (int mask = 0; mask < (1 << S); mask++) {
        for (int i = 0; i < H; i++) {
            for (int j = 0; j < W; j++) {
                if (M[i][j] == '#') continue;
                if (M[i][j] == '|') continue;
                if (M[i][j] == '^') floor[mask][i][j] ^= 1;
                if ('A' <= M[i][j] && M[i][j] <= 'J') floor[mask][i][j] ^= 1;
                for (int k = 0; k < S; k++) {
                    if ((mask >> k & 1) && (MS[k][i][j] == '*')) {
                        floor[mask][i][j] ^= 1;
                    }
                }
            }
        }
    }

    for (int i = 0; i < H; i++) {
        for (int j = 0; j < W; j++) {
            for (int k = 0; k < 2; k++) {
                for (int mask = 0; mask < (1 << S); mask++) {
                    dp[i][j][k][mask] = INF;
                }
            }
        }
    }
    queue<tuple<int, int, int, int>> que;
    dp[sx][sy][0][0] = 0;
    que.emplace(sx, sy, 0, 0);

    while (!que.empty()) {
        auto t = que.front();
        que.pop();
        int x, y, f, mask;
        tie(x, y, f, mask) = t;
        int val = dp[x][y][f][mask];
        for (int i = 0; i < 4; i++) {
            int nx = x + dx[i], ny = y + dy[i];
            if (nx < 0 || H <= nx || ny < 0 || W <= ny) continue;
            if (M[nx][ny] == '#') continue;
            if (M[nx][ny] != '|' && f != floor[mask][nx][ny]) continue;
            if (dp[nx][ny][f][mask] < INF) continue;
            dp[nx][ny][f][mask] = val + 1;
            que.emplace(nx, ny, f, mask);
        }
        if (M[x][y] == '|' && dp[x][y][f ^ 1][mask] == INF) {
            dp[x][y][f ^ 1][mask] = val + 1;
            que.emplace(x, y, f ^ 1, mask);
        }
        if (('a' <= M[x][y] && M[x][y] <= 'j') || ('A' <= M[x][y] && M[x][y] <= 'J')) {
            int s = ('a' <= M[x][y] && M[x][y] <= 'j' ? M[x][y] - 'a' : M[x][y] - 'A');
            int nmask = mask ^ (1 << s);
            if (dp[x][y][floor[nmask][x][y]][nmask] == INF) {
                dp[x][y][floor[nmask][x][y]][nmask] = val + 1;
                que.emplace(x, y, floor[nmask][x][y], nmask);
            }
        }
    }

    int ans = INF;
    for (int mask = 0; mask < (1 << S); mask++) ans = min(ans, dp[gx][gy][floor[mask][gx][gy]][mask]);
    cout << (ans == INF ? -1 : ans) << '\n';
    return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 38120
final_rank: 14

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}

int dp[51][51][2][1<<10];

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

struct State{
    int x,y,f,sw;
    State(int _x,int _y,int _f,int _sw){
        x=_x; y=_y; f=_f; sw=_sw;
    }
};

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int w,h; cin >> w >> h;
    vector<vector<vector<int>>> stage(2,vector<vector<int>>(h,vector<int>(w,-1)));
    int sx,sy,gx,gy;
    for(int i=0;i<h;i++){
        string s; cin >> s;
        for(int j=0;j<w;j++){
            if(s[j]=='%'){
                sx=i,sy=j; s[j] = '_';
            }
            if(s[j]=='&'){
                gx=i,gy=j; s[j] = '_';
            }
            if(s[j]=='_'){
                stage[0][i][j] = 11;
            }
            else if(s[j]=='^'){
                stage[1][i][j] = 11;
            }
            else if(s[j]=='|'){
                stage[0][i][j] = stage[1][i][j] = 10;
            }
            else if('a'<=s[j] and s[j]<='z'){
                stage[0][i][j] = s[j]-'a';
            }
            else if('A'<=s[j] and s[j]<='Z'){
                stage[1][i][j] = s[j]-'A';
            }
        }
    }
    vector<vector<int>> swi(h,vector<int>(w));
    int cnt; cin >> cnt;
    for(int _=0;_<cnt;_++){
        for(int i=0;i<h;i++){
            string s; cin >> s;
            for(int j=0;j<w;j++){
                if(s[j]=='*')swi[i][j]|=(1<<_);
            }
        }
    }
    queue<State> q;
    q.push(State(sx,sy,0,0));
    for(int i=0;i<h;i++){
        for(int j=0;j<w;j++){
            for(int k=0;k<(1<<cnt);k++){
                dp[i][j][0][k]=dp[i][j][1][k] = -1;
            }
        }
    }
    dp[sx][sy][0][0] = 0;
    while(q.size()){
        auto p=q.front(); q.pop();
        int x=p.x,y=p.y,f=p.f,sw=p.sw;

        // use stairs
        if(stage[f][x][y] == 10){
            if(dp[x][y][f^1][sw] == -1){
                dp[x][y][f^1][sw] = dp[x][y][f][sw] + 1;
                q.push(State(x,y,f^1,sw));
            }
        }

        // use switch
        int cf = (f + __builtin_popcount(swi[x][y] & sw)) % 2;
        if(0 <= stage[cf][x][y] and stage[cf][x][y] < cnt){
            int nsw = (sw ^ (1<<stage[cf][x][y]));
            int nf = f;
            if(swi[x][y] & (1<<stage[cf][x][y])){
                nf ^= 1;
            }
            if(dp[x][y][nf][nsw] == -1){
                dp[x][y][nf][nsw] = dp[x][y][f][sw] + 1;
                q.push(State(x,y,nf,nsw));
            }
        }

        // move
        for(int i=0;i<4;i++){
            int nx=x+dx[i],ny=y+dy[i];
            if(0<=nx and nx<h and 0<=ny and ny<w){
                int nf = (f + __builtin_popcount(swi[nx][ny] & sw)) % 2;
                if(0 <= stage[nf][nx][ny] and dp[nx][ny][f][sw] == -1){
                    dp[nx][ny][f][sw] = dp[x][y][f][sw] + 1;
                    q.push(State(nx,ny,f,sw));
                }
            }
        }
    }
    int res = 1e9;
    for(int i=0;i<(1<<cnt);i++){
        int f = (__builtin_popcount(swi[gx][gy] & i)) % 2;
        if(dp[gx][gy][f][i] != -1){
            res = min(res,dp[gx][gy][f][i]);
        }
    }
    if(res == 1e9)res = -1;
    printf("%d\n",res);
}
accuracy: 1
time_ms: 100
memory_kb: 24764
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define repi(i,a,b) for(int i = (int)(a); i < (int)(b); i++)
#define rep(i,a) repi(i,0,a)
const int di[] = {1,0,-1,0}, dj[] = {0,1,0,-1};
struct state{ int i, j, f, used;};
int stage[2][64][64], sw[64][64];
int si, sj, ti, tj, W, H, S;
int dist[64][64][2][1024];

int solve(){
    memset(dist, -1, sizeof(dist));
    queue<state> q;
    q.push((state){si,sj,0,0});
    dist[si][sj][0][0] = 0;
    while(!q.empty()){
        state s = q.front(); q.pop();
        int dis = dist[s.i][s.j][s.f][s.used];
        if(s.i == ti and s.j == tj
           ) return dis;

        if(stage[0][s.i][s.j] == 10 and dist[s.i][s.j][s.f^1][s.used] < 0){
            dist[s.i][s.j][s.f^1][s.used] = dis+1;
            q.push((state){s.i,s.j,s.f^1,s.used});
        }
        int cf = (s.f+__builtin_popcount(sw[s.i][s.j]&s.used))%2;
        if(0 <= stage[cf][s.i][s.j] and stage[cf][s.i][s.j] < 10){
            int nu = s.used ^ (1<<stage[cf][s.i][s.j]), nf = s.f;
            if(sw[s.i][s.j] & (1<<stage[cf][s.i][s.j])) nf ^= 1;
            if(dist[s.i][s.j][nf][nu] < 0){
                dist[s.i][s.j][nf][nu] = dis+1;
                q.push((state){s.i,s.j,nf,nu});
            }
        }
        rep(d,4){
            int ni = s.i+di[d], nj = s.j+dj[d];
            int f = (s.f+__builtin_popcount(sw[ni][nj]&s.used))%2;
            if(stage[f][ni][nj]>=0 and dist[ni][nj][s.f][s.used] < 0){
                dist[ni][nj][s.f][s.used] = dis+1;
                q.push((state){ni,nj,s.f,s.used});
            }
        }
    }
    return -1;
}

void input(){
    cin >> W >> H;
    string s;
    memset(stage,-1,sizeof(stage));
    rep(i,H){
        cin >> s;
        rep(j,W){
            if(s[j] == '%') si = i, sj = j, stage[0][i][j] = 11;
            else if(s[j] == '&') ti = i, tj = j, stage[0][i][j] = 11;
            else if(s[j] == '_') stage[0][i][j] = 11;
            else if(s[j] == '^') stage[1][i][j] = 11;
            else if(s[j] == '|') stage[0][i][j] = stage[1][i][j] = 10;
            else if('a' <= s[j] and s[j] <= 'j') stage[0][i][j] = s[j] - 'a';
            else if('A' <= s[j] and s[j] <= 'J') stage[1][i][j] = s[j] - 'A';
        }
    }
    cin >> S;
    rep(k,S) rep(i,H){
        cin >> s;
        rep(j,W) if(s[j] == '*') sw[i][j] |= 1<<k;
    }
}
int main(){
    input();
    cout << solve() << endl;
    return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 36900
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define repi(i,a,b) for(int i = (int)(a); i < (int)(b); i++)
#define rep(i,a) repi(i,0,a)
const int di[] = {1,0,-1,0}, dj[] = {0,1,0,-1};
struct state{ int i, j, f, used;};
int stage[2][64][64], sw[64][64];
int si, sj, ti, tj, W, H, S;
int dist[64][64][2][1024];

int solve(){
    memset(dist, -1, sizeof(dist));
    queue<state> q;
    q.push((state){si,sj,0,0});
    dist[si][sj][0][0] = 0;
    while(!q.empty()){
        state s = q.front(); q.pop();
        int dis = dist[s.i][s.j][s.f][s.used];
        if(s.i == ti and s.j == tj and
           s.f == __builtin_popcount(sw[s.i][s.j]&s.used)%2) return dis;

        if(stage[0][s.i][s.j] == 10 and dist[s.i][s.j][s.f^1][s.used] < 0){
            dist[s.i][s.j][s.f^1][s.used] = dis+1;
            q.push((state){s.i,s.j,s.f^1,s.used});
        }
        int cf = (s.f+__builtin_popcount(sw[s.i][s.j]&s.used))%2;
        if(0 <= stage[cf][s.i][s.j] and stage[cf][s.i][s.j] < 10){
            int nu = s.used ^ (1<<stage[cf][s.i][s.j]), nf = s.f;
            if(sw[s.i][s.j] & (1<<stage[cf][s.i][s.j])) nf ^= 1;
            if(dist[s.i][s.j][nf][nu] < 0){
                dist[s.i][s.j][nf][nu] = dis+1;
                q.push((state){s.i,s.j,nf,nu});
            }
        }
        rep(d,4){
            int ni = s.i+di[d], nj = s.j+dj[d];
            int f = (s.f+__builtin_popcount(sw[ni][nj]&s.used))%2;
            if(stage[f][ni][nj]>=0 and dist[ni][nj][s.f][s.used] < 0){
                dist[ni][nj][s.f][s.used] = dis+1;
                q.push((state){ni,nj,s.f,s.used});
            }
        }
    }
    return -1;
}

void input(){
    cin >> W >> H;
    string s;
    memset(stage,-1,sizeof(stage));
    rep(i,H){
        cin >> s;
        rep(j,W){
            if(s[j] == '%') si = i, sj = j, stage[0][i][j] = 11;
            else if(s[j] == '&') ti = i, tj = j, stage[0][i][j] = 11;
            else if(s[j] == '_') stage[0][i][j] = 11;
            else if(s[j] == '^') stage[1][i][j] = 11;
            else if(s[j] == '|') stage[0][i][j] = stage[1][i][j] = 10;
            else if('a' <= s[j] and s[j] <= 'j') stage[0][i][j] = s[j] - 'a';
            else if('A' <= s[j] and s[j] <= 'J') stage[1][i][j] = s[j] - 'A';
        }
    }
    cin >> S;
    rep(k,S) rep(i,H){
        cin >> s;
        rep(j,W) if(s[j] == '*') sw[i][j] |= 1<<k;
    }
}
int main(){
    input();
    cout << solve() << endl;
    return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 37016
final_rank: 12

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
//#include <atcoder/all>
using namespace std;
//using namespace atcoder;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 510000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
const double pi = acos(-1);
const double eps = 1e-9;
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
const int mod = 1e9 + 7;
//const int mod = 998244353;

bool in(ll y, ll x, ll h, ll w){
    return 0 <= y && y < h && 0 <= x && x < w;
}

int d[55][55][1<<10][2];

int main(){
    int w,h; cin >> w >> h;
    vs s(h); rep(i,h) cin >> s[i];
    int n; cin >> n;
    vector<vs> t(n,vs(h));
    rep(i,n) rep(j,h) cin >> t[i][j];
    rep(i,h) rep(j,w) rep(k,1<<n) rep(l,2) d[i][j][k][l] = inf;
    queue<tuple<int,int,int,int>> q;
    rep(i,h) rep(j,w) if(s[i][j] == '%'){
        d[i][j][0][0] = 0;
        q.emplace(i,j,0,0);
    }
    while(!q.empty()){
        int y,x,bit,floor;
        tie(y,x,bit,floor) = q.front(); q.pop();
        int c = d[y][x][bit][floor];
        if(s[y][x] == '|'){
            if(chmin(d[y][x][bit][1-floor], c+1)){
                q.emplace(y,x,bit,1-floor);
            }
        }
        if(islower(s[y][x])){
            int nf = (floor + (t[s[y][x]-'a'][y][x] == '*')) % 2;
            if(chmin(d[y][x][bit^(1<<s[y][x]-'a')][nf], c+1)){
                q.emplace(y,x,bit^(1<<s[y][x]-'a'),nf);
            }
        }
        if(isupper(s[y][x])){
            int nf = (floor + (t[s[y][x]-'A'][y][x] == '*')) % 2;
            if(chmin(d[y][x][bit^(1<<s[y][x]-'A')][nf], c+1)){
                q.emplace(y,x,bit^(1<<s[y][x]-'A'),nf);
            }
        }
        rep(i,4){
            int ny = y + dy[i];
            int nx = x + dx[i];
            if(!in(ny,nx,h,w) || s[ny][nx] == '#') continue;
            int rev = 0;
            rep(j,n) if((bit>>j & 1) && t[j][ny][nx] == '*') rev = 1-rev;
            int f = (floor+rev)%2;
            if(f==0){
                if(isupper(s[ny][nx]) || s[ny][nx] == '^') continue;
                if(chmin(d[ny][nx][bit][floor],c+1)){
                    q.emplace(ny,nx,bit,floor);
                }
            }else{
                if(islower(s[ny][nx]) || s[ny][nx] == '_') continue;
                if(s[ny][nx] == '%' || s[ny][nx] == '&') continue;
                if(chmin(d[ny][nx][bit][floor],c+1)){
                    q.emplace(ny,nx,bit,floor);
                }
            }
        }
    }
    int ans = inf;
    rep(i,h) rep(j,w){
        if(s[i][j] == '&'){
            rep(bit,1<<n) rep(k,2){
                int f = k;
                rep(l,n) if((bit>>l & 1) && t[l][i][j] == '*') f = 1-f;
                if(f==0) chmin(ans, d[i][j][bit][k]);
            }
        }
    }
    if(ans == inf) ans = -1;
    cout << ans << endl;
}
accuracy: 1
time_ms: 170
memory_kb: 26468
final_rank: 5

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



int main(){
	
	int w,h;
	cin>>w>>h;
	
	vector<string> s(h);
	rep(i,h)cin>>s[i];
	
	int n;
	cin>>n;
	
	vector<vector<string>> t(n,vector<string>(h));
	rep(i,n){
		rep(j,h){
			cin>>t[i][j];
		}
	}
	
	vector isWall(1<<n,vector(2,vector(h,vector<bool>(w,false))));
	
	rep(i,h){
		rep(j,w){
			if(s[i][j]=='#'){
				isWall[0][0][i][j] = true;
				isWall[0][1][i][j] = true;
			}
			else{
				if(s[i][j]=='_'||s[i][j]=='%'||s[i][j]=='&'||islower(s[i][j])){
					isWall[0][1][i][j] = true;
				}
				if(s[i][j]=='^'||isupper(s[i][j])){
					isWall[0][0][i][j] = true;
				}
				
			}
		}
	}
	
	rep(i,1<<n){
		if(i==0)continue;
		
		isWall[i] = isWall[0];
		
		rep(j,n){
			if((i>>j)&1){
				rep(k,h){
					rep(l,w){
						if(t[j][k][l]=='*'){
							swap(isWall[i][0][k][l],isWall[i][1][k][l]);
						}
					}
				}
			}
		}
		
	}
	
	int sy,sx,gy,gx;
	
	rep(i,h){
		rep(j,w){
			if(s[i][j]=='%'){
				sy = i,sx = j;
			}
			if(s[i][j]=='&'){
				gy = i,gx = j;
			}
		}
	}
	
	vector<int> dx = {0,0,1,-1},dy = {1,-1,0,0};
	vector dis(1<<n,vector(2,vector(h,vector<int>(w,Inf))));
	queue<array<int,4>> Q;
	Q.push({0,0,sy,sx});
	dis[0][0][sy][sx] = 0;
	
	while(Q.size()>0){
		int a = Q.front()[0],b = Q.front()[1],c = Q.front()[2],d = Q.front()[3];
		Q.pop();
		
		rep(i,4){
			int cc = c+dy[i],dd = d+dx[i];
			if(cc<0||cc>=h||dd<0||dd>=w)continue;
			if(dis[a][b][cc][dd]!=Inf)continue;
			if(isWall[a][b][cc][dd])continue;
			dis[a][b][cc][dd] = dis[a][b][c][d] + 1;
			Q.push({a,b,cc,dd});
		}
		
		if(s[c][d]=='|'){
			int bb = b^1;
			if(dis[a][bb][c][d]!=Inf)continue;
			dis[a][bb][c][d] = dis[a][b][c][d] + 1;
			Q.push({a,bb,c,d});
		}
		
		if(isalpha(s[c][d])){
			int aa = a;
			if(islower(s[c][d])){
				aa ^= 1 << (s[c][d]-'a');
			}
			else{
				aa ^= 1 << (s[c][d]-'A');
			}
			int bb = b;
			if(isWall[aa][b][c][d]){
				bb ^= 1;
			}
			if(dis[aa][bb][c][d]!=Inf)continue;
			
			dis[aa][bb][c][d] = dis[a][b][c][d] + 1;
			Q.push({aa,bb,c,d});
		}
		
	}
	
	int ans = Inf;
	
	rep(i,1<<n){
		ans = min(ans,dis[i][0][gy][gx]);
		ans = min(ans,dis[i][1][gy][gx]);
	}
	
	if(ans==Inf)ans = -1;
	
	cout<<ans<<endl;
	
	return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 34808
final_rank: 10

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



int main(){
	
	int w,h;
	cin>>w>>h;
	
	vector<string> s(h);
	rep(i,h)cin>>s[i];
	
	int n;
	cin>>n;
	
	vector<vector<string>> t(n,vector<string>(h));
	rep(i,n){
		rep(j,h){
			cin>>t[i][j];
		}
	}
	
	vector isWall(1<<n,vector(2,vector(h,vector<bool>(w,false))));
	
	rep(i,h){
		rep(j,w){
			if(s[i][j]=='#'){
				isWall[0][0][i][j] = true;
				isWall[0][1][i][j] = true;
			}
			else{
				if(s[i][j]=='_'||s[i][j]=='%'||s[i][j]=='&'||islower(s[i][j])){
					isWall[0][1][i][j] = true;
				}
				if(s[i][j]=='^'||isupper(s[i][j])){
					isWall[0][0][i][j] = true;
				}
				
			}
		}
	}
	
	rep(i,1<<n){
		if(i==0)continue;
		
		isWall[i] = isWall[0];
		
		rep(j,n){
			if((i>>j)&1){
				rep(k,h){
					rep(l,w){
						if(t[j][k][l]=='*'){
							swap(isWall[i][0][k][l],isWall[i][1][k][l]);
						}
					}
				}
			}
		}
		
	}
	
	int sy,sx,gy,gx;
	
	rep(i,h){
		rep(j,w){
			if(s[i][j]=='%'){
				sy = i,sx = j;
			}
			if(s[i][j]=='&'){
				gy = i,gx = j;
			}
		}
	}
	
	vector<int> dx = {0,0,1,-1},dy = {1,-1,0,0};
	vector dis(1<<n,vector(2,vector(h,vector<int>(w,Inf))));
	queue<array<int,4>> Q;
	Q.push({0,0,sy,sx});
	dis[0][0][sy][sx] = 0;
	
	while(Q.size()>0){
		int a = Q.front()[0],b = Q.front()[1],c = Q.front()[2],d = Q.front()[3];
		Q.pop();
		
		rep(i,4){
			int cc = c+dy[i],dd = d+dx[i];
			if(cc<0||cc>=h||dd<0||dd>=w)continue;
			if(dis[a][b][cc][dd]!=Inf)continue;
			if(isWall[a][b][cc][dd])continue;
			dis[a][b][cc][dd] = dis[a][b][c][d] + 1;
			Q.push({a,b,cc,dd});
		}
		
		if(s[c][d]=='|'){
			int bb = b^1;
			if(dis[a][bb][c][d]!=Inf)continue;
			if(isWall[a][bb][c][d])continue;
			dis[a][bb][c][d] = dis[a][b][c][d] + 1;
			Q.push({a,bb,c,d});
		}
		
		if(isalpha(s[c][d])){
			int aa = a;
			if(islower(s[c][d])){
				aa ^= 1 << (s[c][d]-'a');
			}
			else{
				aa ^= 1 << (s[c][d]-'A');
			}
			int bb = b;
			if(isWall[aa][b][c][d]){
				bb ^= 1;
			}
			if(dis[aa][bb][c][d]!=Inf)continue;
			
			dis[aa][bb][c][d] = dis[a][b][c][d] + 1;
			Q.push({aa,bb,c,d});
		}
		
	}
	
	int ans = Inf;
	
	rep(i,1<<n){
		ans = min(ans,dis[i][0][gy][gx]);
	}
	
	if(ans==Inf)ans = -1;
	
	cout<<ans<<endl;
	
	return 0;
}
accuracy: 0.05555555555555555
time_ms: 10
memory_kb: 5780
final_rank: 20

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

#define For(i, a, b) for (int i = (int)(a); i < (int)(b); ++i)
#define rFor(i, a, b) for (int i = (int)(a)-1; i >= (int)(b); --i)
#define rep(i, n) For((i), 0, (n))
#define rrep(i, n) rFor((i), (n), 0)
#define fi first
#define se second

using namespace std;

typedef long long lint;
typedef unsigned long long ulint;
typedef pair<int, int> pii;
typedef pair<lint, lint> pll;

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 (a > b) {
        a = b;
        return true;
    }
    return false;
}

template <class T>
T div_floor(T a, T b) {
    if (b < 0) a *= -1, b *= -1;
    return a >= 0 ? a / b : (a + 1) / b - 1;
}
template <class T>
T div_ceil(T a, T b) {
    if (b < 0) a *= -1, b *= -1;
    return a > 0 ? (a - 1) / b + 1 : a / b;
}

template <typename T>
struct coord_comp {
    vector<T> v;
    bool sorted = false;

    coord_comp() {}

    int size() { return v.size(); }

    void add(T x) { v.push_back(x); }

    void build() {
        sort(v.begin(), v.end());
        v.erase(unique(v.begin(), v.end()), v.end());
        sorted = true;
    }

    int get_idx(T x) {
        assert(sorted);
        return lower_bound(v.begin(), v.end(), x) - v.begin();
    }

    T &operator[](int i) { return v[i]; }
};

constexpr lint mod = 1000000007;
constexpr lint INF = mod * mod;
constexpr int MAX = 200010;

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

int h, w, s, sx, sy;
char c[2][50][50][1 << 10], sw[10][50][50];
int d[2][50][50][1 << 10];

int main() {
    scanf("%d%d", &w, &h);
    rep(t, 2) rep(i, h) rep(j, w) rep(S, 1 << 10) {
        c[t][i][j][S] = '#';
        d[t][i][j][S] = mod;
    }
    rep(i, h) rep(j, w) {
        char tmp;
        scanf(" %c", &tmp);
        if (tmp == '|')
            c[0][i][j][0] = c[1][i][j][0] = tmp;
        else if (tmp == '^' || ('A' <= tmp && tmp <= 'Z'))
            c[1][i][j][0] = tmp ^ 32;
        else if (tmp != '#')
            c[0][i][j][0] = tmp;
        if (tmp == '%') sx = i, sy = j;
    }
    scanf("%d", &s);
    rep(t, s) rep(i, h) rep(j, w) scanf(" %c", &sw[t][i][j]);

    For(S, 1, 1 << s) {
        rep(t, 2) rep(i, h) rep(j, w) c[t][i][j][S] = c[t][i][j][0];
        rep(t, s) if (S >> t & 1) {
            rep(i, h) rep(j, w) if (sw[t][i][j] == '*') {
                swap(c[0][i][j][S], c[1][i][j][S]);
            }
        }
    }

    queue<tuple<int, int, int, int>> que;
    d[0][sx][sy][0] = 0;
    que.push({0, sx, sy, 0});
    while (!que.empty()) {
        auto [t, x, y, S] = que.front();
        que.pop();
        char tc = c[t][x][y][S];
        int td = d[t][x][y][S];
        if (tc == '|') {
            if (chmin(d[t ^ 1][x][y][S], td + 1)) {
                que.push({t ^ 1, x, y, S});
            }
        }
        if ('a' <= tc && tc <= 'z') {
            int T = S ^ (1 << (tc - 'a'));
            int nt = t ^ (sw[tc - 'a'][x][y] == '*');
            if (chmin(d[nt][x][y][T], td + 1)) {
                que.push({nt, x, y, T});
            }
        }
        rep(i, 4) {
            int nx = x + dx[i], ny = y + dy[i];
            if (c[t][nx][ny][S] != '#') {
                if (c[t][nx][ny][S] == '&') {
                    printf("%d\n", td + 1);
                    return 0;
                }
                if (chmin(d[t][nx][ny][S], td + 1)) {
                    que.push({t, nx, ny, S});
                }
            }
        }
    }
    puts("-1");
}
accuracy: 1
time_ms: 180
memory_kb: 28964
final_rank: 9