#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

const int N = 55, ST = 1 << 10, dx[] = {0, 0, 1, -1}, dy[] = {1, -1, 0, 0}, INF = 1000000000, Q = ST * N * N / 10;
int n, m, sx, sy, ex, ey, k, qhead, qtail, q[Q][4], dis[N][N][2][ST];
char map[N][N], col[10][N][N], pre[ST][N][N];

void change (char &grid) {
	if (grid == '^') {
		grid = '_';
	} else if (grid == '_') {
		grid = '^';
	}
	if (grid >= 'a' && grid <= 'j') {
		grid = 'A' + grid - 'a';
	} else if (grid >= 'A' && grid <= 'J') {
		grid = 'a' + grid - 'A';
	}
}

int height (const char &a) {
	return a == '_' || a >= 'a' && a <= 'j' ? 0 : 1;
}

int shift (const char &a) {
	if (a >= 'a' && a <= 'j') return a - 'a';
	if (a >= 'A' && a <= 'J') return a - 'A';
	return -1;
}

int main() {
	scanf("%d %d", &m, &n);
	for (int i = 0; i < n; ++i) {
		scanf("%s", map[i]);
	}
	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < m; ++j) {
			if (map[i][j] == '%') {
				sx = i;
				sy = j;
			}
			if (map[i][j] == '&') {
				ex = i;
				ey = j;
			}
		}
	}
	scanf("%d", &k);
	for (int i = 0; i < k; ++i) {
		for (int j = 0; j < n; ++j) {
			scanf("%s", col[i][j]);
		}
	}
	for (int i = 0; i < 1 << k; ++i) {
		for (int r = 0; r < n; ++r) {
			for (int c = 0; c < m; ++c) {
				pre[i][r][c] = map[r][c];
				if (pre[i][r][c] == '%' || pre[i][r][c] == '&') pre[i][r][c] = '_';
			}
		}
		for (int j = 0; j < k; ++j) {
			if (i >> j & 1) {
				for (int r = 0; r < n; ++r) {
					for (int c = 0; c < m; ++c) {
						if (col[j][r][c] == '*') {
							change(pre[i][r][c]);
						}
					}
				}
			}
		}
	}
	for (int x = 0; x < n; ++x) {
		for (int y = 0; y < m; ++y) {
			for (int z = 0; z < 2; ++z) {
				for (int st = 0; st < 1 << k; ++st) {
					dis[x][y][z][st] = INF;
				}
			}
		}
	}
	dis[sx][sy][0][0] = 0;
	qhead = 0; qtail = 1; q[1][0] = sx; q[1][1] = sy; q[1][2] = 0; q[1][3] = 0;
	while (qhead != qtail) {
		++qhead;
		if (qhead == Q) qhead = 0;
		int nx = q[qhead][0], ny = q[qhead][1], nz = q[qhead][2], nst = q[qhead][3];
//cout << nx << ' ' << ny << ' ' << nz << ' ' << pre[nst][nx][ny] << ' ' << height(pre[nst][nx][ny]) << ' ' << shift(pre[nst][nx][ny]) << endl;
		for (int d = 0; d < 4; ++d) {
			int tx = nx + dx[d], ty = ny + dy[d];
			if (tx >= 0 && tx < n && ty >= 0 && ty < m && pre[nst][tx][ty] != '#' && (pre[nst][tx][ty] == '|' || height(pre[nst][tx][ty]) == nz) && dis[tx][ty][nz][nst] == INF) {
				dis[tx][ty][nz][nst] = dis[nx][ny][nz][nst] + 1;
				++qtail; if (qtail == Q) qtail = 0;
				q[qtail][0] = tx; q[qtail][1] = ty; q[qtail][2] = nz; q[qtail][3] = nst;
			}
		}
		if (map[nx][ny] == '|' && dis[nx][ny][nz ^ 1][nst] == INF) {
			dis[nx][ny][nz ^ 1][nst] = dis[nx][ny][nz][nst] + 1;
			++qtail; if (qtail == Q) qtail = 0;
			q[qtail][0] = nx; q[qtail][1] = ny; q[qtail][2] = nz ^ 1; q[qtail][3] = nst;
		}
		if (shift(pre[nst][nx][ny]) != -1) {
			int tst = nst ^ (1 << shift(pre[nst][nx][ny])), tz = nz;
			if (pre[tst][nx][ny] != '|') tz = height(pre[tst][nx][ny]);
			if (dis[nx][ny][tz][tst] == INF) {
				dis[nx][ny][tz][tst] = dis[nx][ny][nz][nst] + 1;
				++qtail; if (qtail == Q) qtail = 0;
				q[qtail][0] = nx; q[qtail][1] = ny; q[qtail][2] = tz; q[qtail][3] = tst;
			}
		}
	}
	int ans = INF;
	for (int z = 0; z < 2; ++z) {
		for (int st = 0; st < 1 << k; ++st) {
			ans = min(ans, dis[ex][ey][z][st]);
		}
	}
	printf("%d\n", ans == INF ? -1 : ans);
	return 0;
}

Measured memory_bytes: 33292