Problem:
Problem F:
Mysterious Dungeons
The Kingdom of Aqua Canora Mystica is a very affluent and peaceful country, but around the
kingdom, there are many evil monsters that kill people. So the king gave an order to you to kill
the master monster.
You came to the dungeon where the monster lived. The dungeon consists of a grid of square
cells. You explored the dungeon moving up, down, left and right. You finally found, fought
against, and killed the monster.
Now, you are going to get out of the dungeon and return home. However, you found strange
carpets and big rocks are placed in the dungeon, which were not there until you killed the
monster. They are caused by the final magic the monster cast just before its death! Every rock
occupies one whole cell, and you cannot go through that cell. Also, each carpet covers exactly
one cell. Each rock is labeled by an uppercase letter and each carpet by a lowercase. Some of
the rocks and carpets may have the same label.
While going around in the dungeon, you observed the following behaviors. When you enter
into the cell covered by a carpet, all the rocks labeled with the corresponding letter (e.g., the
rocks with ‘A’ for the carpets with ‘a’) disappear. After the disappearance, you can enter the
cells where the rocks disappeared, but if you enter the same carpet cell again or another carpet
cell with the same label, the rocks revive and prevent your entrance again. After the revival,
you have to move on the corresponding carpet cell again in order to have those rocks disappear
again.
Can you exit from the dungeon? If you can, how quickly can you exit? Your task is to write
a program that determines whether you can exit the dungeon, and computes the minimum
required time.
Input
The input consists of some data sets.
Each data set begins with a line containing two integers,
W
and
H
(3 ≤
W
,
H
≤ 30). In each
of the following
H
lines, there are
W
characters, describing the map of the dungeon as
W
×
H
grid of square cells. Each character is one of the following:
‘@’ denoting your current position,
‘<’ denoting the exit of the dungeon,
A lowercase letter denoting a cell covered by a carpet with the label of that letter,
An uppercase letter denoting a cell occupied by a rock with the label of that letter,
‘#’ denoting a wall, and
‘.’ denoting an empty cell.
Every dungeon is surrounded by wall cells (‘#’), and has exactly one ‘@’ cell and one ‘<’ cell.
There can be up to eight distinct uppercase labels for the rocks and eight distinct lowercase
labels for the carpets.
You can move to one of adjacent cells (up, down, left, or right) in one second. You cannot move
to wall cells or the rock cells.
A line containing two zeros indicates the end of the input, and should not be processed.
Output
For each data set, output the minimum time required to move from the ‘@’ cell to the ‘<’ cell,
in seconds, in one line. If you cannot exit, output -1.
Sample Input
8 3
########
#<A.@.a#
########
8 3
########
#<AaAa@#
########
8 4
########
#<
...(truncated)

Submitted solutions:

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>

int solve(std::vector<std::string> state) {
	const int height = state.size();
	const int width = state[0].size();
	std::string lowercase, uppercase;
	std::pair<int, int> start, goal;
	for (auto i = 0; i < height; ++i) {
		for (auto j = 0; j < width; ++j) {
			const auto c = state[i][j];
			if ('a' <= c && c <= 'z') {
				lowercase.push_back(c);
			}
			else if ('A' <= c && c <= 'Z') {
				uppercase.push_back(c);
			}
			else if (c == '@') {
				start = std::make_pair(i, j);
			}
			else if (c == '<') {
				goal = std::make_pair(i, j);
			}
		}
	}
	std::sort(lowercase.begin(), lowercase.end());
	std::sort(uppercase.begin(), uppercase.end());
	lowercase.erase(std::unique(lowercase.begin(), lowercase.end()), lowercase.end());
	uppercase.erase(std::unique(uppercase.begin(), uppercase.end()), uppercase.end());
	std::unordered_map<char, int> to_i;
	for (auto i = 0; i < lowercase.size(); ++i) {
		to_i[lowercase[i]] = i;
		to_i['A' + (lowercase[i] - 'a')] = i;
	}
	for (auto i = 0; i < uppercase.size(); ++i) {
		if (to_i.find(uppercase[i]) == to_i.end()) {
			to_i[uppercase[i]] = lowercase.size();
		}
	}
	std::vector<std::vector<std::vector<int>>> min_step(height, std::vector<std::vector<int>>(width, std::vector<int>(1 << lowercase.size(), INT_MAX)));
	std::queue<std::pair<std::pair<int, int>, int>> queue;
	min_step[start.first][start.second][0] = 0;
	queue.emplace(start, 0);
	while (!queue.empty()) {
		const auto [pos, pattern] = queue.front(); queue.pop();
		const auto [x, y] = pos;
		if (x == goal.first && y == goal.second) break;
		for (auto nx = x - 1; nx <= x + 1; ++nx) {
			if (nx < 0 || height <= nx) continue;
			for (auto ny = y - 1; ny <= y + 1; ++ny) {
				if (ny < 0 || width <= ny) continue;
				if (nx == x && ny == y) continue;
				if (nx != x && ny != y) continue;
				const auto c = state[nx][ny];
				if (c == '#') continue;
				if ('a' <= c && c <= 'z') {
					const auto next = pattern ^ (1 << to_i[c]);
					if (min_step[nx][ny][next] == INT_MAX) {
						min_step[nx][ny][next] = min_step[x][y][pattern] + 1;
						queue.emplace(std::make_pair(nx, ny), next);
					}
				}
				else if ('A' <= c && c <= 'Z') {
					const auto can_move = (pattern & (1 << to_i[c])) != 0;
					if (can_move && min_step[nx][ny][pattern] == INT_MAX) {
						min_step[nx][ny][pattern] = min_step[x][y][pattern] + 1;
						queue.emplace(std::make_pair(nx, ny), pattern);
					}
				}
				else {
					if (min_step[nx][ny][pattern] == INT_MAX) {
						min_step[nx][ny][pattern] = min_step[x][y][pattern] + 1;
						queue.emplace(std::make_pair(nx, ny), pattern);
					}
				}
			}
		}
	}
	const auto min = *std::min_element(min_step[goal.first][goal.second].begin(), min_step[goal.first][goal.second].end());
	return min == INT_MAX ? -1 : min;
}

int main() {
	while (true) {
		int width, height; std::cin >> width >> height;
		if (width == 0 && height == 0) break;
		std::vector<std::string> state(height);
		for (auto& line : state) std::cin >> line;
		std::cout << solve(state) << '\n';
	}
}
accuracy: 1
time_ms: 140
memory_kb: 4080
final_rank: 9

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


struct Info{
	Info(int arg_row,int arg_col,int arg_state,int arg_total_time){
		row = arg_row;
		col = arg_col;
		state = arg_state;
		total_time = arg_total_time;
	}
	int row,col,state,total_time;
};


int W,H;
int POW[17],index_table[26];
int min_Time[30][30][256],diff_row[4] = {-1,0,0,1},diff_col[4] = {0,-1,1,0};
char base_map[30][31];

void func(){

	for(int i = 0; i < 26; i++)index_table[i] = -1;

	int start_row,start_col,index = 0;

	for(int row = 0; row < H; row++){

		scanf("%s",base_map[row]);

		for(int col = 0; col < W; col++){
			if(base_map[row][col] == '@'){
				start_row = row;
				start_col = col;
				base_map[row][col] = '.';
			}else if(base_map[row][col] >= 'a' && base_map[row][col] <= 'z'){
				if(index_table[base_map[row][col]-'a'] == -1){
					index_table[base_map[row][col]-'a'] = index;
					index++;
				}
			}
		}
	}

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			for(int state = 0; state < POW[index]; state++)min_Time[row][col][state] = BIG_NUM;
		}
	}

	queue<Info> Q;
	min_Time[start_row][start_col][0] = 0;
	Q.push(Info(start_row,start_col,0,0));

	int next_row,next_col,next_state,loc;

	while(!Q.empty()){

		if(base_map[Q.front().row][Q.front().col] == '<'){
			printf("%d\n",Q.front().total_time);
			return;
		}else if(Q.front().total_time > min_Time[Q.front().row][Q.front().col][Q.front().state]){
			Q.pop();
		}else{

			for(int i = 0; i < 4; i++){
				next_row = Q.front().row + diff_row[i];
				next_col = Q.front().col + diff_col[i];

				if(base_map[next_row][next_col] == '#')continue;

				if(base_map[next_row][next_col] == '.' || base_map[next_row][next_col] == '<'){
					if(min_Time[next_row][next_col][Q.front().state] > Q.front().total_time+1){
						min_Time[next_row][next_col][Q.front().state] = Q.front().total_time+1;
						Q.push(Info(next_row,next_col,Q.front().state,Q.front().total_time+1));
					}
				}else if(base_map[next_row][next_col] >= 'a' && base_map[next_row][next_col] <= 'z'){
					loc = index_table[base_map[next_row][next_col]-'a'];

					if(Q.front().state&(1 << loc)){
						next_state = Q.front().state-POW[loc];
					}else{
						next_state = Q.front().state+POW[loc];
					}

					if(min_Time[next_row][next_col][next_state] > Q.front().total_time+1){
						min_Time[next_row][next_col][next_state] = Q.front().total_time+1;
						Q.push(Info(next_row,next_col,next_state,Q.front().total_time+1));
					}
				}else if(base_map[next_row][next_col] >= 'A' && base_map[next_row][next_col] <= 'Z'){
					loc = index_table[base_map[next_row][next_col]-'A'];

					if((Q.front().state&(1 << loc)) == 0)continue;

					if(min_Time[next_row][next_col][Q.front().state] > Q.front().total_time+1){
						min_Time[next_row][next_col][Q.front().state] = Q.front().total_time+1;
						Q.push(Info(next_row,next_col,Q.front().state,Q.front().total_time+1));
					}
				}
			}
			Q.pop();
		}
	}

	printf("-1\n");
}

int main(){

	for(int i = 0; i < 17; i++)POW[i] = pow(2,i);

	while(true){
		scanf("%d %d",&W,&H);
		if(W == 0 && H == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 4456
final_rank: 8

code_snippet: #include<iostream>
#include<vector>
#include<string>
#include<algorithm>	
#include<map>
#include<set>
#include<utility>
#include<cmath>
#include<cstring>
#include<queue>
#include<cstdio>
#include<sstream>
#include<iomanip>
#define loop(i,a,b) for(int i=a;i<b;i++) 
#define rep(i,a) loop(i,0,a)
#define pb push_back
#define mp make_pair
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
using namespace std;
//kaewasuretyuui
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef pair<int,pii> pip;
typedef vector<pip>vip;
const double PI=acos(-1);
const double EPS=1e-8;
const int inf=1e8;
int main(){
	int n,m;
	while(cin>>m>>n,n+m){
		vector<string>in(n);
		rep(i,n)cin>>in[i];
		int q[256]={0};
		int sx,sy;
		int co=1;
		rep(i,n)rep(j,m){
			char c=in[i][j];
			c=tolower(c);
			if(c=='@')sx=i,sy=j;
			if(islower(c)&&q[c]==0){
				q[c]=co;
				q[toupper(c)]=co;
				co++;
			}
		}
		
		queue<pair<pii,pii> >w;
		w.push(pair<pii,pii>(pii(sx,sy),pii(0,0)));
		int dx[]={0,0,1,-1};
		int dy[]={1,-1,0,0};
		co=0;
		map<int,map<int,map<int,bool> > >M;
		while(!w.empty()){
			co++;
			pair<pii,pii>e=w.front();
			w.pop();
			pii a=e.first,b=e.second;
			if(M[a.first][a.second][b.second])continue;
			M[a.first][a.second][b.second]=true;
			rep(i,4){
				int nx=a.first+dx[i];
				int ny=a.second+dy[i];
				int t=b.second;
				if(in[nx][ny]=='#')continue;
//				if(isalpha(in[nx][ny])&&q[tolower(in[nx][ny])]==0)continue;
				if(in[nx][ny]=='<'){
					cout<<b.first+1<<endl;
					goto end;
				}
				if(isupper(in[nx][ny])&&!(t&1<<(q[in[nx][ny]]-1)))continue;
				if(islower(in[nx][ny]))t^=1<<(q[in[nx][ny]]-1);
				w.push(pair<pii,pii>(pii(nx,ny),pii(b.first+1,t)));
			}		
		}
		cout<<-1<<endl;
		end:;
	}
}
accuracy: 1
time_ms: 1350
memory_kb: 10748
final_rank: 14

code_snippet: #include <bits/stdc++.h>
 
using namespace std;
 
#define MAX 30
#define INF (1<<29)
typedef pair<int,int> pii;
typedef pair<pii,int> piii;
 
int H,W,sx,sy,gx,gy,cnt;
char field[MAX][MAX];
const int dx[] = {-1,0,0,1};
const int dy[] = {0,-1,1,0};
 
struct State{
    int x,y,S;
    State(){}
    State(int x,int y,int S) : x(x),y(y),S(S) {}
};
 
bool isValid(int x,int y){
    if(x < 0 || x >= W || y < 0 || y >= H) return false;
    if(field[y][x] == '#') return false;
    return true;
}
 
int solve(){
    queue<State> Q;
    Q.push(State(sx,sy,0));
    map<piii,int> dist;
    dist[piii(pii(sx,sy),0)] = 0;
 
    while(!Q.empty()){
	State now = Q.front(); Q.pop();
	int x = now.x, y = now.y, S = now.S;
	piii pp = piii(pii(x,y),S);
     
	if(x == gx && y == gy){
	    return dist[pp];
	}
	for(int i = 0 ; i < 4 ; i++){
	    int nx = x + dx[i], ny = y + dy[i];
	    if(!isValid(nx,ny)) continue;
	    piii cp = piii(pii(nx,ny),S);
 
	    if(islower(field[ny][nx])){
		int p = field[ny][nx]-'a';
		int nS = S;
		if((S >> p) & 1){
		    nS -= (1<<p);
		}else{
		    nS |= (1<<p);
		}
		cp.second = nS;
		if(dist[pp] + 1 < dist[cp] || dist[cp] == 0){
		    dist[cp] = dist[pp] + 1;
		    Q.push(State(nx,ny,nS));
		}
	    }else if(isupper(field[ny][nx])){
		int p = field[ny][nx]-'A';
		if((S >> p) & 1){
		    if(dist[pp] + 1 < dist[cp] || dist[cp] == 0){
			dist[cp] = dist[pp] + 1;
			Q.push(State(nx,ny,S));
		    }
		}
	    }else{
		if(dist[pp] + 1 < dist[cp] || dist[cp] == 0){
		    dist[cp] = dist[pp] + 1;
		    Q.push(State(nx,ny,S));
		}
	    } 
	}
    }
    return -1;
}
 
int main(){
    while(cin >> W >> H,(W | H)){
	for(int i = 0 ; i < H ; i++){
	    for(int j = 0 ; j < W ; j++){
		cin >> field[i][j];
		if(field[i][j] == '@'){
		    field[i][j] = '.';
		    sx = j; sy = i;
		}else if(field[i][j] == '<'){
		    gx = j; gy = i;
		    field[i][j] = '.';
		}
	    }     
	}
	cout << solve() << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 2750
memory_kb: 15516
final_rank: 19

code_snippet: #include <algorithm>
#include <cmath>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#include <cassert>
#include <functional>

using namespace std;

#define LOG(...) printf(__VA_ARGS__)
//#define LOG(...)
#define FOR(i,a,b) for(int i=(int)(a);i<(int)(b);++i)
#define REP(i,n) for(int i=0;i<(int)(n);++i)
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define SORT(c) sort((c).begin(),(c).end())
#define RSORT(c) sort((c).rbegin(),(c).rend())
#define CLR(a) memset((a), 0 ,sizeof(a))

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int dx[] = { -1, 0, 1, 0 }; const int dy[] = { 0, 1, 0, -1 };
struct pos{
	int x;
	int y;
	int s;//0-25 a-z
	int step;
};
struct po{
	int x;
	int y;
	int s;//0-25 a-z
};

bool operator<(const po left, const po right){
	return left.x == right.x ? left.y == right.y ?left.s<right.s : left.y < right.y : left.x < right.x;
}
bool operator==(const po left, const po right){
	return left.x == right.x&&left.y == right.y&&left.s == right.s;
}

int main() {
	int w, h;
	while (cin >> w >> h, w){
		vector<vector<char>> cell(h, vector<char>(w));
		set<char> sc;
		int sx;
		int sy;
		int gx;
		int gy;
		REP(i, h){
			REP(j, w){
				cin >> cell[i][j];
				//if ('a' <= cell[i][j] && cell[i][j]<='z')
				if (cell[i][j] == '@'){
					sy = i;
					sx = j;
					cell[i][j] = '.';
				}
				if (cell[i][j] == '<'){
					gy = i;
					gx = j;
					cell[i][j] = '.';
				}
			}
		}
		set<po> G;
		queue<pos> Q;
		int ans = -1;
		G.insert({ sx, sy, 0 });
		Q.push({ sx, sy, 0, 0 });

		while (!Q.empty()){
			pos p = Q.front(); Q.pop();
			if (p.x == gx&&p.y == gy){
				ans = p.step;
				break;
			}

			REP(i, 4){
				if (((('A' <= cell[p.y + dy[i]][p.x + dx[i]] && cell[p.y + dy[i]][p.x + dx[i]]<='Z') && (1 << (cell[p.y + dy[i]][p.x + dx[i]] - 'A'))  & p.s)) || (cell[p.y + dy[i]][p.x + dx[i]] == '.') || ('a' <= cell[p.y + dy[i]][p.x + dx[i]] && cell[p.y + dy[i]][p.x + dx[i]] <= 'z')){
					po c;
					c.x = p.x + dx[i];
					c.y = p.y + dy[i];
					c.s = p.s;
					if ('a' <= cell[p.y + dy[i]][p.x + dx[i]] && cell[p.y + dy[i]][p.x + dx[i]] <= 'z')
						c.s ^= 1 << (cell[p.y + dy[i]][p.x + dx[i]] - 'a');
					if (G.find(c) == G.end()){
						G.insert(c);
						Q.push({ c.x, c.y, c.s, p.step + 1 });
					}
				}
			}
		}
		cout << ans << endl;
	}
}
accuracy: 1
time_ms: 1360
memory_kb: 15568
final_rank: 17

code_snippet: /*
 * Mysterious Dungeons
 * http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2089
 */

 #include <bits/stdc++.h>

using namespace std;

#define LOG(...) fprintf(stderr, __VA_ARGS__)
//#define LOG(...)
#define FOR(i, a, b) for(int i = (int)(a); i < (int)(b); ++i)
#define REP(i, n) for(int i = 0; i < (int)(n); ++i)
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort(ALL(c))
#define RSORT(c) sort(RALL(c))
#define SQ(n) (n) * (n)

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

char field[30][30];

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


struct P {
  int x, y, cost;
  long c;
};

int main() {
  int w, h;
  while(cin >> w >> h, w | h) {
    vector<vector<set<long>>> G(h, vector<set<long>>(w));
    // map<char, int> id;
    fill_n((char*)field, 30 * 30, '#');
    int sx, sy;
    int gx, gy;
    REP(y, h){
      REP(x, w){
        cin >> field[y][x];
        switch (field[y][x]) {
        case '<':
          gx = x;
          gy = y;
          break;
        case '@':
          sx = x;
          sy = y;
          break;
        case '.':
        case '#':
          break;
        default:
          // {
          //   char c = tolower(field[y][x]);
          //   if (!EXIST(id, c)) {
          //     id[c] = id.size();
          //   }
          // }
          break;
        }
      }
    }

    queue<P> que;
    G[sy][sx].insert(0);
    que.push({sx, sy, 0, 0});
    int res = -1;
    while(!que.empty()) {
      P p = que.front(); que.pop();
      // LOG("%d %d %d %d\n", p.x, p.y, p.c, p.cost);
      if (p.x == gx && p.y == gy) {
        res = p.cost;
        break;
      }

      REP(i, 4){
        int nx = p.x + dx[i];
        int ny = p.y + dy[i];
        int ncost = p.cost + 1;
        long nc = p.c;
        if (field[ny][nx] == '#') continue;
        if (islower(field[ny][nx])) {
          nc ^= 1 << (field[ny][nx] - 'a');
        } else if (isupper(field[ny][nx])) {
          if(!(nc & (1 << (field[ny][nx] - 'A')))) continue;
        }
        if (!EXIST(G[ny][nx], nc)) {
          G[ny][nx].insert(nc);
          que.push({nx, ny, ncost, nc});
        }
      }
    }

    cout << res << endl;
  }
}
accuracy: 1
time_ms: 730
memory_kb: 12572
final_rank: 12

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

using namespace std;

#define LOG(...) fprintf(stderr, __VA_ARGS__)
//#define LOG(...)
#define FOR(i, a, b) for(int i = (int)(a); i < (int)(b); ++i)
#define REP(i, n) for(int i = 0; i < (int)(n); ++i)
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort(ALL(c))
#define RSORT(c) sort(RALL(c))
#define SQ(n) (n) * (n)

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

char field[30][30];

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


struct P {
  int x, y, cost;
  long c;
};

int main() {
  int w, h, swn;
  while(cin >> w >> h, w | h) {
    vector<vector<set<long>>> G(h, vector<set<long>>(w));
    map<char, int> id;
    fill_n((char*)field, 30 * 30, '#');
    int sx, sy;
    int gx, gy;
    REP(y, h){
      REP(x, w){
        cin >> field[y][x];
        switch (field[y][x]) {
        case '<':
          gx = x;
          gy = y;
          break;
        case '@':
          sx = x;
          sy = y;
          break;
        case '.':
        case '#':
          break;
        default:
        {
          char c = tolower(field[y][x]);
          if (!EXIST(id, c)) {
            id[c] = id.size();
          }
        }
        break;
        }
      }
    }
    swn = id.size();

    queue<P> que;
    G[sy][sx].insert(0);
    que.push({sx, sy, 0, 0});
    int res = -1;
    while(!que.empty()) {
      P p = que.front(); que.pop();
      // LOG("%d %d %d %d\n", p.x, p.y, p.c, p.cost);
      if (p.x == gx && p.y == gy) {
        res = p.cost;
        break;
      }

      REP(i, 4){
        int nx = p.x + dx[i];
        int ny = p.y + dy[i];
        int ncost = p.cost + 1;
        long nc = p.c;
        if (field[ny][nx] == '#') continue;
        if ('a' <= field[ny][nx] && field[ny][nx] <= 'z') {
          nc ^= 1 << (field[ny][nx] - 'a');
        }
        if ('A' <= field[ny][nx] && field[ny][nx] <= 'Z') {
          if(!(nc & (1 << (field[ny][nx] - 'A')))) continue;
        }
        if (!EXIST(G[ny][nx],nc)) {
          G[ny][nx].insert(nc);
          que.push({nx, ny, ncost, nc});
        }
      }
    }

    cout << res << endl;
  }
}
accuracy: 1
time_ms: 740
memory_kb: 12680
final_rank: 13

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

using namespace std;

#define LOG(...) fprintf(stderr,__VA_ARGS__)
//#define LOG(...)
#define FOR(i,a,b) for(int i=(int)(a);i<(int)(b);++i)
#define REP(i,n) for(int i=0;i<(int)(n);++i)
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define SORT(c) sort(ALL(c))
#define RSORT(c) sort(RALL(c))

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

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

char field[30][30];

struct P {
    int x, y;
    int cnt;
    int pressed;
};

int main() {
    int w, h;
    while (cin >> w >> h, w|h) {
        int x, y, gx, gy;
        map<tuple<int, int, int>, bool> G;
        map<int, int> id;
        REP(i, h) {
            REP(j, w) {
                cin >> field[i][j];
                switch (field[i][j]) {
                case '@':
                    field[i][j] = '.';
                    x = j;
                    y = i;
                    break;
                case '<':
                    field[i][j] = '.';
                    gx = j;
                    gy = i;
                    break;
                case '#':
                    break;
                default: {
                    char c = tolower(field[i][j]);
                    if (!EXIST(id, c)) {
                        id[c] = id.size();
                    }
                }
                }
            }
        }
        REP(i, h) {
            REP(j, w) {
                char c = field[i][j];
                if ('a' <= c && c <= 'z') {
                    field[i][j] = id[c] + 'a';
                } else if ('A' <= c && c <= 'Z') {
                    field[i][j] = id[c+0x20] + 'A';
                }
            }
        }
//        REP(i, h) {
//            REP(j, w) {
//                char c = field[i][j];
//                LOG("%c", c);
//            }
//            LOG("\n");
//        }

        queue<P> que;
        que.push({x, y, 0, 0});
        while (!que.empty()) {
            P p = que.front(); que.pop();
            int x = p.x, y = p.y;

            if (x == gx && y == gy) {
                cout << p.cnt << endl;
                goto NEXT;
            }

            REP(i, 4) {
                int sx = x + dx[i], sy = y + dy[i];
                if (field[sy][sx] == '#') {
                    continue;
                } else if (field[sy][sx] == '.') {
                    tuple<int, int, int> k = make_tuple(sx, sy, p.pressed);
                    if (!EXIST(G, k)) {
                        G[k] = true;
                        que.push({sx, sy, p.cnt+1, p.pressed});
                    }
                } else if ('a' <= field[sy][sx] && field[sy][sx] <= 'z') {
                    int pressed = p.pressed ^ (1 << (field[sy][sx] - 'a'));
                    tuple<int, int, int> k = make_tuple(sx, sy, pressed);
                    if (!EXIST(G, k)) {
                        G[k] = true;
                        que.push({sx, sy, p.cnt+1, pressed});
                    }
                } else if ((1 << (field[sy][sx] - 'A')) & p.pressed) {
                    tuple<int, int, int> k = make_tuple(sx, sy, p.pressed);
                    if (!EXIST(G, k)) {
                        G[k] = true;
                        que.push({sx, sy, p.cnt+1, p.pressed});
                    }
                }
            }
        }
        cout << -1 << endl;
NEXT: {}
    }
}
accuracy: 1
time_ms: 1360
memory_kb: 15504
final_rank: 16

code_snippet: #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

const int MAX_W = 30;
const int MAX_H = 30;
const int MAX_HW = MAX_H * MAX_W;
const int SWBITS = 8;
const int MAX_SW = 1 << SWBITS;

const int INF = 1 << 30;

/* typedef */

typedef pair<int,int> pii;

enum { F_EMPTY, F_WALL };

/* global variables */

int w, h, hw, nsw;
int spos, gpos;
int flds[MAX_HW], swtbl[26];
int dists[MAX_HW][MAX_SW];
int dpos[4];

/* subroutines */

/* main */

int main() {
  for (;;) {
    int w, h;
    cin >> w >> h;
    if (w == 0) break;

    hw = w * h;
    dpos[0] = 1, dpos[1] = -w, dpos[2] = -1, dpos[3] = w;
    nsw = 0;
    
    memset(flds, 0, sizeof(flds));
    memset(swtbl, -1, sizeof(swtbl));
    
    for (int y = 0; y < h; y++) {
      string line;
      cin >> line;
      for (int x = 0; x < w; x++) {
	int pos = y * w + x;
	int ch = line[x];

	if (ch == '@') spos = pos;
	else if (ch == '<') gpos = pos;
	else if (ch == '#') flds[pos] = F_WALL;
	else if (ch >= 'a' && ch <= 'z') {
	  int id = ch - 'a';
	  if (swtbl[id] < 0) swtbl[id] = nsw++;
	  flds[pos] = 10 + swtbl[id];
	}
	else if (ch >= 'A' && ch <= 'Z')
	  flds[pos] = 20 + (ch - 'A');
      }
    }

    if (nsw > 8) {
      printf("Error: nsw=%d\n", nsw); exit(0);
    }
    
    for (int i = 0; i < MAX_HW; i++)
      for (int j = 0; j < MAX_SW; j++) dists[i][j] = INF;
    dists[spos][0] = 0;

    queue<pii> q;
    q.push(pii(spos, 0));

    int min_d = INF;
    
    while (! q.empty()) {
      pii u = q.front(); q.pop();

      int upos = u.first;
      int usw = u.second;
      int ud = dists[upos][usw];

      if (upos == gpos) {
	min_d = ud;
	break;
      }
      
      for (int di = 0; di < 4; di++) {
	int vpos = upos + dpos[di];
	int vsw = usw;
	int vfld = flds[vpos];

	if (vfld == F_WALL) continue;
	else if (vfld >= 10 && vfld <= 19) {	// sw
	  int sw = vfld - 10;
	  vsw ^= (1 << sw);
	}
	else if (vfld >= 20) {	// rock
	  int sw = swtbl[vfld - 20];
	  if (sw < 0 || ! (vsw & (1 << sw))) continue;
	}

	if (dists[vpos][vsw] >= INF) {
	  dists[vpos][vsw] = ud + 1;
	  q.push(pii(vpos, vsw));
	}
      }
    }

    if (min_d >= INF) cout << -1 << endl;
    else cout << min_d << endl;
  }

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

code_snippet: #include<stdio.h>
#include<queue>
#include<algorithm>
using namespace std;
char str[40][40];
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
int bfs[40][40][1<<8];
int con[30];
int main(){
	int a,b;
	while(scanf("%d%d",&b,&a),a){
		for(int i=0;i<a;i++)scanf("%s",str[i]);
		for(int i=0;i<a;i++)for(int j=0;j<b;j++)for(int k=0;k<(1<<8);k++)
			bfs[i][j][k]=999999999;
		int sr,sc,gr,gc;
		int sz=0;
		for(int i=0;i<30;i++)con[i]=-1;
		for(int i=0;i<a;i++)for(int j=0;j<b;j++){
			if('A'<=(str[i][j])&&(str[i][j])<='Z'&&!~con[(str[i][j])-'A']){
				con[(str[i][j])-'A']=sz++;
			}
		}
		for(int i=0;i<a;i++)for(int j=0;j<b;j++){
			if(str[i][j]=='@'){sr=i;sc=j;}
			if(str[i][j]=='<'){gr=i;gc=j;}
		}
		queue<pair<pair<int,int>,int> > Q;
		Q.push(make_pair(make_pair(sr,sc),0));
		bfs[sr][sc][0]=0;
		while(Q.size()){
			int row=Q.front().first.first;
			int col=Q.front().first.second;
			int st=Q.front().second;
			int cost=bfs[row][col][st];
			Q.pop();
			for(int i=0;i<4;i++){
				int tr=row+dx[i];
				int tc=col+dy[i];
				if(str[tr][tc]=='#')continue;
				if('A'<=str[tr][tc]&&str[tr][tc]<='Z'){
					int bit=con[str[tr][tc]-'A'];
					if((st&(1<<bit))&&bfs[tr][tc][st]>cost+1){
						bfs[tr][tc][st]=cost+1;
						Q.push(make_pair(make_pair(tr,tc),st));
					}
				}else if('a'<=str[tr][tc]&&str[tr][tc]<='z'&&~con[str[tr][tc]-'a']){
					int bit=con[str[tr][tc]-'a'];
					if(bfs[tr][tc][st^(1<<bit)]>cost+1){
						bfs[tr][tc][st^(1<<bit)]=cost+1;
						Q.push(make_pair(make_pair(tr,tc),st^(1<<bit)));
					}
				}else{
					if(bfs[tr][tc][st]>cost+1){
						bfs[tr][tc][st]=cost+1;
						Q.push(make_pair(make_pair(tr,tc),st));
					}
				}
			}
		}
		int ret=999999999;
		for(int i=0;i<(1<<8);i++)ret=min(ret,bfs[gr][gc][i]);
		if(ret<99999)printf("%d\n",ret);
		else printf("-1\n");
	}
}
accuracy: 1
time_ms: 90
memory_kb: 2128
final_rank: 2

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

using namespace std;

#define MAX 30
#define INF (1<<29)
typedef pair<int,int> pii;
typedef pair<pii,int> piii;

int H,W,sx,sy,gx,gy,cnt;
char field[MAX][MAX];
const int dx[] = {-1,0,0,1};
const int dy[] = {0,-1,1,0};

struct State{
  int x,y,S;
  State(){}
  State(int x,int y,int S) : x(x),y(y),S(S) {}
};

bool isValid(int x,int y){
  if(x < 0 || x >= W || y < 0 || y >= H) return false;
  if(field[y][x] == '#') return false;
  return true;
}

int solve(){
  queue<State> Q;
  Q.push(State(sx,sy,0));
  map<piii,int> dist;
  dist[piii(pii(sx,sy),0)] = 0;

  while(!Q.empty()){
    State now = Q.front(); Q.pop();
    int x = now.x, y = now.y, S = now.S;
    piii pp = piii(pii(x,y),S);
    
    if(x == gx && y == gy){
      return dist[pp];
    }
    for(int i = 0 ; i < 4 ; i++){
      int nx = x + dx[i], ny = y + dy[i];
      if(!isValid(nx,ny)) continue;
      piii cp = piii(pii(nx,ny),S);

      if(islower(field[ny][nx])){
        int p = field[ny][nx]-'a';
        int nS = S;
        if((S >> p) & 1){
          nS -= (1<<p);
        }else{
          nS |= (1<<p);
        }
        cp.second = nS;
        if(dist[pp] + 1 < dist[cp] || dist[cp] == 0){
          dist[cp] = dist[pp] + 1;
          Q.push(State(nx,ny,nS));
        }
      }else if(isupper(field[ny][nx])){
        int p = field[ny][nx]-'A';
        if((S >> p) & 1){
          if(dist[pp] + 1 < dist[cp] || dist[cp] == 0){
            dist[cp] = dist[pp] + 1;
            Q.push(State(nx,ny,S));
          }
        }
      }else{
        if(dist[pp] + 1 < dist[cp] || dist[cp] == 0){
          dist[cp] = dist[pp] + 1;
          Q.push(State(nx,ny,S));
        }
      } 
    }
  }
  return -1;
}

int main(){
  while(cin >> W >> H,(W | H)){
    for(int i = 0 ; i < H ; i++){
      for(int j = 0 ; j < W ; j++){
        cin >> field[i][j];
        if(field[i][j] == '@'){
          field[i][j] = '.';
          sx = j; sy = i;
        }else if(field[i][j] == '<'){
          gx = j; gy = i;
          field[i][j] = '.';
        }
      }     
    }
    cout << solve() << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 3100
memory_kb: 13720
final_rank: 20

code_snippet: #include<iostream>
#include<queue>
#include<cctype>
#include<map>

using namespace std;

struct S{
  int y,x,t,b;
};

int main(){
  for(int W,H;cin>>W>>H,W;){
    char g[30][31];
    map<char,int> m;
    queue<S> que;
    for(int i=0;i<H;i++){
      cin>>g[i];
      for(int j=0;j<W;j++){
	if(g[i][j]=='@'){
	  que.push({i,j,0,0});
	}else if(islower(g[i][j])){
	  if(!m.count(g[i][j])){
	    int s=m.size();
	    m[g[i][j]]=s;
	  }
	}
      }
    }
    bool p[30][30][1<<8]={};
    while(!que.empty()){
      S cs=que.front();
      if(g[cs.y][cs.x]=='<')break;
      que.pop();
      if(p[cs.y][cs.x][cs.b]++)continue;
      for(int i=0;i<4;i++){
	int ny=cs.y+(~i&i-1);
	int nx=cs.x+(i?2-i:0);
	char c=g[cs.y][cs.x];
	if(c!='#'&&!(isupper(c)&&(!m.count(tolower(c))||!(cs.b>>m[tolower(c)]&1)))){
	  int nb=cs.b;
	  if(islower(c)){
	    nb^=1<<m[c];
	  }
	  que.push({ny,nx,cs.t+1,nb});
	}
      }
    }
    cout<<(que.empty()?-1:que.front().t)<<endl;
  }
}
accuracy: 1
time_ms: 230
memory_kb: 1952
final_rank: 5

code_snippet: /*
16:54 - 17;14
 */
#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
#include<climits>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define IINF (INT_MAX)
#define MAX 31

using namespace std;

struct Data{
  int cur,state,cost;
  Data(int cur=IINF,int state=IINF,int cost=IINF):cur(cur),state(state),cost(cost){}
  bool operator < (const Data& a)const{ return cost > a.cost; }
};

int H,W,sp,gp;
char G[MAX*MAX];
int mincost[MAX*MAX][(1<<9)];
int dx[] = {0,1,0,-1};
int dy[] = {1,0,-1,0};
int Index[30];

inline bool isValid(int x,int y){ return (0 <= x && x < W && 0 <= y && y < H); }

void compute(){
  rep(i,H)rep(j,W)rep(k,(1<<9))mincost[j+i*W][k] = IINF;
  mincost[sp][0] = 0;
  priority_queue<Data> Q;
  Q.push(Data(sp,0,0));
  while(!Q.empty()){
    Data data = Q.top(); Q.pop();
    int x = data.cur % W, y = data.cur / W;

    if(G[data.cur] == '<'){
      cout << data.cost << endl;
      return;
    }
    rep(i,4){
      int nx = x + dx[i], ny = y + dy[i], nstate = data.state;

      if(!isValid(nx,ny))continue;
      if(G[nx+ny*W] == '#')continue;
      if('a' <= G[nx+ny*W] && G[nx+ny*W] <= 'z'){
	int index = Index[G[nx+ny*W]-'a'];
	if((nstate>>index) & 1)nstate  = nstate & ~(1<<index);
	else                   nstate |= (1<<index);
      } else if('A' <= G[nx+ny*W] && G[nx+ny*W] <= 'Z'){
	int index = Index[G[nx+ny*W]-'A'];
	if(!((data.state>>index) & 1))continue;
      }
      if(mincost[nx+ny*W][nstate] > data.cost+1){
	mincost[nx+ny*W][nstate] = data.cost+1;
	Q.push(Data(nx+ny*W,nstate,data.cost+1));
      }
    }
  }
  cout << -1 << endl;
}

int main(){
  while(cin >> W >> H,W|H){
    int idx = 0;
    rep(i,30)Index[i] = IINF;
    rep(y,H)rep(x,W){
      cin >> G[x+y*W];
      if(G[x+y*W] == '@')sp = x + y * W;
      if('a' <= G[x+y*W] && G[x+y*W] <= 'z')if(Index[G[x+y*W]-'a'] == IINF)Index[G[x+y*W]-'a'] = idx++;
    }
    compute();
  }
  return 0;
}
accuracy: 1
time_ms: 240
memory_kb: 3224
final_rank: 10

code_snippet: #include <iostream>
#include <queue>
#include <map>
using namespace std;
typedef pair<int,int>P;//bit/コストxy


//ここからbit判定
int bit_data[26];
void bit_set(){
	bit_data[0]=1;
	for(int i=1;i<26;i++)bit_data[i]=bit_data[i-1]*2;
}
bool bit(int base,char check){
	if('A'<=check&&check<='Z'){
		int che=check-'A';
		int res=base&bit_data[che];
		if(!res)return 0;
		else return 1;
	}
	else if(check=='#'){
		return 0;
	}
	else{
		return 1;
	}
}
int bit_change(int base,char change){
	int che=change-'a';
	int res=base^bit_data[che];
	return res;
}
//ここまでbit判定

int xv[]={0,1,0,-1};
int yv[]={1,0,-1,0};

int main(){
	bit_set();
	int W,H;
	
	while(cin>>W>>H,H){
		queue<P>Q;
		map<P,int>flag;
		char land[32][32];
		for(int i=0;i<=W+1||i<=H+1;i++)land[i][0]=land[i][H+1]=land[0][i]=land[W+1][i]='#';
		for(int i=1;i<=H;i++){
			for(int j=1;j<=W;j++){
				cin>>land[j][i];
				if(land[j][i]=='@'){
					Q.push(make_pair(0,j*100+i));//どこのフラグも立っていない&0コストxy
					flag[make_pair(0,j*100+i)]=1;
				}
			}
		}
		int end=1;
		for(int b,cost,x,y;!Q.empty();Q.pop()){
			b=Q.front().first;
			cost=Q.front().second/10000;
			x=Q.front().second/100%100;
			y=Q.front().second%100;
			
			//cout<<"#"<<b<<" "<<cost<<" "<<x<<" "<<y<<endl;
			
			if(land[x][y]=='<'){
				cout<<cost<<endl;
				end=0;
				break;
			}
			if('a'<=land[x][y]&&land[x][y]<='z'){
				b=bit_change(b,land[x][y]);
			}
			for(int i=0;i<4;i++){
				x=Q.front().second/100%100+xv[i];
				y=Q.front().second%100+yv[i];
				if(bit(b,land[x][y])&&flag[make_pair(b,x*100+y)]==0){
					flag[make_pair(b,x*100+y)]=1;
					Q.push(make_pair(b,(cost+1)*10000+x*100+y));
				}
				
			}
		}
		if(end)cout<<-1<<endl;
	}
	return 0;
}
accuracy: 1
time_ms: 1450
memory_kb: 13772
final_rank: 15

code_snippet: #include<stdio.h>
#include<string.h>
#include<queue>

struct S{
	int x,y,turn;
	int bits;
};
int memo[260][31][31];
void search(int w,int h){
	char map[32][32];
	
	int toNum[30]={0};
	int bit=1;
	memset(memo,-1,sizeof(memo));
	S s1,nextS;
	std::queue<S> qu;
	for(int i=0;i<h;i++){
		scanf("%s",map[i]);
		for(int j=0;j<w;j++){
			char c1=map[i][j];
			if(c1=='@'){
				s1.x=j;
				s1.y=i;
				s1.turn=0;
				s1.bits=0;
				qu.push(s1);
				map[i][j]='.';
			}else if(c1=='.'||c1=='#'||c1=='<'){
				//何もしない
			}else{
				//アルファベット
				if('a'<=c1&&c1<='z'){
					c1-='a';
					if(toNum[c1]==0){
						toNum[c1]=bit;
						bit*=2;
					}
				}
			}
		}
	}
	int dxs[]={1,0,-1,0};
	int dys[]={0,1,0,-1};
	while(qu.empty()==false){
		nextS=s1=qu.front();
		qu.pop();
		//printf("(%d %d %d %d)",s1.x,s1.y,s1.bits,s1.turn);
		if(map[s1.y][s1.x]=='<'){
			printf("%d\n",s1.turn);
			return ;
		}
		int turn=memo[s1.bits][s1.y][s1.x];
		if(turn!=-1&&turn<=s1.turn)continue;
		memo[s1.bits][s1.y][s1.x]=s1.turn;
		nextS.turn++;
		for(int i=0;i<4;i++){
			nextS.x=s1.x+dxs[i];
			nextS.y=s1.y+dys[i];
			nextS.bits=s1.bits;
			if(nextS.y<0||h<=nextS.y||nextS.x<0||w<=nextS.x)continue;
			char c1=map[nextS.y][nextS.x];
			if(c1=='#')continue;
			if(c1=='.'||c1=='<'){
				//何もしない
			}else if('a'<=c1&&c1<='z'){
				nextS.bits^=toNum[c1-'a'];
			}else if('A'<=c1&&c1<='Z'){
				if((nextS.bits&toNum[c1-'A'])==0)continue;
			}
			int turn=memo[nextS.bits][nextS.y][nextS.x];
			if(turn!=-1&&turn<=nextS.turn)continue;
			qu.push(nextS);
		}
	}
	printf("-1\n");
}

int main(){
	int w,h;
	while(1){
		scanf("%d %d",&w,&h);
		if(w==0&&h==0)break;
		search(w,h);
	}
}
accuracy: 1
time_ms: 130
memory_kb: 2356
final_rank: 4

code_snippet: #include <cstdio>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

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

class Data
{
public:
    int y, x;
    bitset<8> bs;
    Data(int y0, int x0, bitset<8> bs0){
        y = y0;
        x = x0;
        bs = bs0;
    }
};

int h, w;
vector<string> s;
int sy, sx;
int n;
vector<int> index;

int solve()
{
    vector<vector<vector<bool> > > check(h, vector<vector<bool> >(w, vector<bool>(1<<n, false)));
    check[sy][sx][0] = true;
    queue<Data> q;
    q.push(Data(sy, sx, 0));

    int ret = 0;
    while(!q.empty()){
        ++ ret;
        int qNum = q.size();
        while(--qNum >= 0){
            int y0 = q.front().y;
            int x0 = q.front().x;
            bitset<8> bs0 = q.front().bs;
            q.pop();

            for(int i=0; i<4; ++i){
                int y = y0 + dy[i];
                int x = x0 + dx[i];
                bitset<8> bs = bs0;

                if(s[y][x] == '<'){
                    return ret;
                }else if(s[y][x] == '#'){
                    continue;
                }else if(islower(s[y][x])){
                    bs[index[s[y][x]]] = !bs[index[s[y][x]]];
                }else if(isupper(s[y][x])){
                    if(index[s[y][x]] == -1)
                        continue;
                    if(!bs[index[s[y][x]]])
                        continue;
                }

                if(!check[y][x][bs.to_ulong()]){
                    check[y][x][bs.to_ulong()] = true;
                    q.push(Data(y, x, bs));
                }
            }
        }
    }

    return -1;
}

int main()
{
    for(;;){
        cin >> w >> h;
        if(h == 0)
            return 0;

        s.assign(h, string(w, ' '));
        n = 0;
        index.assign(128, -1);
        for(int i=0; i<h; ++i){
            for(int j=0; j<w; ++j){
                cin >> s[i][j];
                if(s[i][j] == '@'){
                    sy = i;
                    sx = j;
                    s[i][j] = '.';
                }else if(islower(s[i][j]) && index[s[i][j]] == -1){
                    index[s[i][j]] = n;
                    index[s[i][j] - 'a' + 'A'] = n;
                    ++ n;
                }
            }
        }

        cout << solve() << endl;
    }
}
accuracy: 1
time_ms: 170
memory_kb: 1448
final_rank: 3

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)n; ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cout<<*i<<" "; cout<<endl; }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
struct State{
  int S;
  int x, y;
  int c;
  State() {}
  State(int S, int x, int y, int c) :
    S(S), x(x), y(y), c(c) {}
  bool operator < (const State& s) const {
    return c > s.c; //reverse
  }
};

int getidx(string s, char c){
  REP(i, s.size())if(s[i] == c) return i;
  assert(false);
  return -1;
}
int dist[1<<13][30][30];
int main(){
  int W, H;
  while(cin>>W>>H && W){
    vector<string> grid(H);
    REP(i, H) cin>>grid[i];
    int sx, sy, gx, gy;
    set<char> rock;
    REP(y, H)REP(x, W){
      if(grid[y][x] == '@'){
        sx = x, sy = y;
      }
      if(grid[y][x] == '<'){
        gx = x, gy = y;
      }
      if(isalpha(grid[y][x])){
        rock.insert(tolower(grid[y][x]));
      }
    }
    string rstr;
    FORIT(it, rock) rstr += *it;
    REP(i, 1<<13)REP(j, 30)REP(k, 30) dist[i][j][k] = INF;
    dist[0][sy][sx] = 0;
    priority_queue<State> que;
    que.push(State(0, sx, sy, 0));
    int ans = -1;
    while(!que.empty()){
      State s = que.top(); que.pop();
      if(dist[s.S][s.y][s.x] < s.c) continue;
      if(s.x == gx && s.y == gy){
        ans = s.c;
        break;
      }
      REP(r, 4){
        int nx = s.x + dx[r];
        int ny = s.y + dy[r];
        if(nx >= 0 && ny >= 0 && nx < W && ny < H && grid[ny][nx] != '#'){
          if(isupper(grid[ny][nx])){
            int idx = getidx(rstr, tolower(grid[ny][nx]));
            if(s.S & 1 << idx && dist[s.S][ny][nx] > s.c + 1){
              dist[s.S][ny][nx] = s.c + 1;
              que.push(State(s.S, nx, ny, s.c + 1));
            }
          }else if(islower(grid[ny][nx])){
            int nS = s.S ^ (1 << getidx(rstr, grid[ny][nx]));
            if(dist[nS][ny][nx] > s.c + 1){
              dist[nS][ny][nx] = s.c + 1;
              que.push(State(nS, nx, ny, s.c + 1));
            }
          }else if(dist[s.S][ny][nx] > s.c + 1){
            dist[s.S][ny][nx] = s.c + 1;
            que.push(State(s.S, nx, ny, s.c + 1));
          }
        }
      }
    }
    cout<<ans<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 990
memory_kb: 30400
final_rank: 18

code_snippet: #include <iostream>
#include <iomanip>
#include <sstream>
#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cassert>
#include <climits>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
typedef long long ll;
typedef pair<int,int> pii;
const int INF = 1<<29;
const double PI = acos(-1);
const double EPS = 1e-8;

struct P {
  int y, x, S;
  P(int y, int x, int S) : x(x), y(y), S(S) {}
};
char ba[30][30];
int rock[30][30];
int dist[30][30][1<<8];

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

int main() {
  int w,h;
  while(cin>>w>>h,w||h) {
    queue<P> Q;
    memset(dist,-1,sizeof(dist));
    int rocknum = 0;
    memset(rock, -1, sizeof(rock));
    map<char, int> mp;
    REP(i, h) {
      REP(j, w) {
        cin >> ba[i][j];
        if (ba[i][j] == '@') {
          dist[i][j][0] = 0;
          Q.push(P(i,j,0));
        }
        if (isupper(ba[i][j])) {
          if (mp.count(ba[i][j]) == 0) mp[ba[i][j]] = rocknum++;
        }
      }
    }
    int ans = -1;
    while(!Q.empty()) {
      P p = Q.front(); Q.pop();
      //cout << p.y << " " << p.x << " " << p.S << endl;
      //if (dist[p.y][p.x][p.S]>=0) continue;
      if (ba[p.y][p.x] == '<') {
        ans = dist[p.y][p.x][p.S];
        break;
      }
      REP(i, 4) {
        int yy = p.y+dy[i];
        int xx = p.x+dx[i];
        if (yy<0||yy>=h||xx<0||xx>=w) continue;
        if (ba[yy][xx] == '#') continue;
        
        int nS = p.S;
        if (islower(ba[yy][xx])) {
          char c = toupper(ba[yy][xx]);
          if (mp.count(c)) {
            nS ^= 1<<mp[c];
          }
        } else if (isupper(ba[yy][xx])) {
          if (!(nS >> mp[ba[yy][xx]] & 1)) continue;
        }
        //cout << yy  << ":" << xx << ":" << nS << " " << dist[yy][xx][nS] << endl;
        if (dist[yy][xx][nS] == -1) {
          dist[yy][xx][nS] = dist[p.y][p.x][p.S] + 1;
          Q.push(P(yy,xx,nS));
        }
      }
    }
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 240
memory_kb: 1908
final_rank: 6

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <memory.h>
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <map>
#include <cmath>
using namespace std;

#define rep(i, n) for(int i = 0; i< n; i++)
typedef long long ll;
typedef pair<int, int> P;
typedef pair<int, P> state;

int dx[] = {1, 0, -1, 0};
int dy[] = {0, -1, 0, 1};
char field[50][50];
map<int, int> memo[40][40];

int main(){
  int H, W;
  int sx, sy, gx, gy;
  while(cin >> W >> H && (H || W)){
    rep(i, 40)rep(j, 40) memo[i][j].clear();
    fill(&field[0][0], &field[0][0] + 50 * 50, '#');
    rep(i, H)rep(j, W){
      cin >> field[i+1][j+1];
      if(field[i+1][j+1] == '@'){
	sx = j + 1;
	sy = i + 1;
	field[i+1][j+1] = '.';
      }
      if(field[i+1][j+1] == '<'){
	gx = j + 1;
	gy = i + 1;
	field[i+1][j+1] = '.';
      }
    }

    memo[sx][sy][0] = 0;
    queue<state> que;
    que.push(state(0, P(sx, sy)));
    int res = -1;
    while(!que.empty()){
      state s = que.front();
      que.pop();
      int mask = s.first;
      int x = s.second.first;
      int y = s.second.second;
      int c = memo[x][y][mask];
      //      cout << y << " " << x << " " << mask << " " << c << endl;
      if(x == gx && y == gy) {
	res = c;
	break;
      }
      rep(i, 4){
	int x2 = x + dx[i];
	int y2 = y + dy[i];
	if(field[y2][x2] == '.'){
	  if(memo[x2][y2].find(mask) == memo[x2][y2].end()) {
	    memo[x2][y2][mask] = c + 1;
	    que.push(state(mask, P(x2, y2)));
	  }
	}else if(islower(field[y2][x2])){
	  int mask2 = mask ^ (1 << (field[y2][x2] - 'a'));
	  if(memo[x2][y2].find(mask2) == memo[x2][y2].end()){
	    memo[x2][y2][mask2] = c + 1;
	    que.push(state(mask2, P(x2, y2)));
	  }
	}else if(isupper(field[y2][x2])){
	  if((mask & (1 << (field[y2][x2] - 'A')))
	     && memo[x2][y2].find(mask) == memo[x2][y2].end()){
	    memo[x2][y2][mask] = c + 1;
	    que.push(state(mask, P(x2, y2)));
	  }
	}
      }
    }
    cout << res << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 1280
memory_kb: 7220
final_rank: 11

code_snippet: #include <iostream>
#include <set>
#include <cassert>
#include <map>
#include <queue>
#include <algorithm>
#include <cctype>
#include <cstring>
using namespace std;

struct NODE{
	int x,y,cost,bit;
	NODE(int x,int y,int cost,int bit) :  x(x) , y(y) , cost(cost) , bit(bit) {}
};

bool done[30][30][1<<8];


int main(){
	char c[30][30];
	int W,H;
	while(cin >> W >> H && W){
		int sx,sy;
		map<char,int> dd;
		set<char> exist;
		for(int i = 0 ; i < H ; i++)
			for(int j = 0 ; j < W ; j++){
				cin >> c[i][j];
				if(c[i][j] == '@'){
					c[i][j] = '.';
					sx = j , sy = i;
				}
				if(islower(c[i][j])){
					char t = c[i][j] | 32;
					int w = dd.size();
					if(!dd.count(t)) dd[t] = w;
				}
			
				exist.insert(c[i][j]);
			}	
		queue<NODE> Q;
		Q.push(NODE(sx,sy,0,0));
		memset(done,0,sizeof(done));
		while(Q.size()){
			NODE q = Q.front(); Q.pop();
			if(done[q.y][q.x][q.bit]) continue;
			else done[q.y][q.x][q.bit] = true;
			if( c[q.y][q.x] == '<' ){
				cout << q.cost << endl;
				goto end;
			}
			int dx[] = {-1,0,1,0} , dy[] = {0,-1,0,1};
			for(int i = 0 ; i < 4 ; i++){
				int tx = q.x + dx[i] , ty = q.y + dy[i];
				char t = c[ty][tx];
				if(t=='#')continue;
				if(isupper(t) && !exist.count(c[ty][tx]|32)) continue;
				if(isupper(t) ){
					if(!(q.bit&(1<<(dd[t|32]))))continue;
				}
				int bit = q.bit;
				if(islower(t)){
					bit ^= 1<<dd[t|32];
				}
				Q.push(NODE(tx,ty,q.cost+1,bit));
			}
		}
		cout << -1 << endl;
		end:;
		
	}
}
accuracy: 1
time_ms: 370
memory_kb: 1612
final_rank: 7