Problem:
方向音痴のトナカイ
問題
今年も JOI 町にサンタクロースが空からやってきた．JOI 町にある全ての家には子供がいるので，このサンタクロースは JOI 町の全ての家にプレゼントを配ってまわらなければならない．しかし，今年は連れているトナカイが少々方向音痴であり，また建物の上以外に降りることができないため，全ての家にプレゼントを配るためには少々道順を工夫しなければならないようだ．
JOI 町は東西南北に区画整理されており，各区画は家，教会，空き地のいずれかである．JOI 町には 1 つだけ教会がある．次のルールに従い，サンタクロースとトナカイは教会から出発し，全ての家に 1 回ずつプレゼントを配った後，教会に戻る．
今年のトナカイは少々方向音痴であるため，東西南北いずれかの方向にまっすぐ飛ぶことしかできず，空中では方向転換できない．
まだプレゼントを配っていない家の上は自由に通過できる．まだプレゼントを配っていない家には降りることができる．家に降りた時は必ずプレゼントを配り，その後は東西南北いずれかの方向に飛び立つ．
JOI 町の家では，クリスマスの夜はサンタクロースが来るまでは暖炉をつけずに過ごしているが，サンタクロースが飛び立った後は暖炉をつける．暖炉をつけると煙突から煙が出るので，プレゼントを配り終えた家の上を通過することはできない．
教会の上は自由に通過することができる．しかし，教会では礼拝が行われているので，全てのプレゼントを配り終えるまで教会に降りることはできない．
空き地の上は自由に通過することができるが，空き地に降りることはできない．
入力として町の構造が与えられたとき，サンタクロースとトナカイがプレゼントを配る道順が何通りあるかを求めるプログラムを作成せよ．
入力
入力は複数のデータセットからなる．各データセットは以下の形式で与えられる．
各データセットは n+1 行ある．
1 行目には整数 m (1 ≤ m ≤ 10) と整数 n (1 ≤ n ≤ 10) が空白で区切られて書かれている．
2 行目から n+1 行目までの各行には，0，1，2 のいずれかが，
空白で区切られて m 個書かれており，各々が各区画の状態を表している．
北から i 番目，西から j 番目の区画を (i,j) と記述することにすると
(1 ≤ i ≤ n, 1 ≤ j ≤ m)，
第 i+1 行目の j 番目の値は，
区画 (i,j) が空き地である場合は 0 となり，
家である場合は 1 となり，
教会である場合は 2 となる．
教会の個数は 1 であり，家の個数は 1 以上 23 以下である．
ただし，採点用入力データでは配る道順が 2000000 通りをこえることはない．
m, n がともに 0 のとき入力の終了を示す.データセットの数は 5 を超えない．
出力
データセットごとに,プレゼントを配る道順が何通りあるかを表す整数を1 行に出力する．
入出力例
入力例
3 2
1 0 1
1 0 2
3 3
1 1 1
1 0 1
1 1 2
0 0
出力例
2
6
図: 2つ目の入力例 に対する 6 通り全ての道順
（数字は配る順序を表す）
上記問題文と自動審判に使われるデータは、
情報オリンピック日本委員会
が作成し公開している問題文と採点用テストデータです。

Submitted solutions:

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


int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    while(1){
    ll N, M;
    cin >> M >> N;
    if(N+M==0)return 0;
    vector<pair<ll, ll>> P;
    ll Y, X;
    vector<vector<ll>> A(N, vector<ll>(M, -1));
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            ll a;
            cin >> a;
            if (a == 0)continue;
            else if (a == 1) {
                A[i][j] = P.size();
                P.push_back({ i,j });
            }
            else {
                A[i][j] = -2;
                Y = i;
                X = j;
            }
        }
    }
    ll PN = P.size();
    vector<vector<int>> U(PN, vector<int>(PN, 0));
    for (int j = 0; j < PN; j++) {
        for (int k = 0; k < PN; k++) {
            if (P[j].first != P[k].first && P[j].second != P[k].second)continue;
            if (P[j].first == P[k].first) {
                ll L = min(P[j].second, P[k].second);
                ll R = max(P[j].second, P[k].second);
                bool OK = 1;
                for (ll x = L + 1; x < R; x++) {
                    ll d = A[P[j].first][x];
                    if (d >= 0)U[j][k] += (1 << d);
                }
            }
            else {
                ll L = min(P[j].first, P[k].first);
                ll R = max(P[j].first, P[k].first);
                bool OK = 1;
                for (ll x = L + 1; x < R; x++) {
                    ll d = A[x][P[j].second];
                    if (d >= 0)U[j][k] += (1 << d);
                }
            }
        }
    }

    vector<vector<int>> DP;
    unordered_map<int, int> idx;
    for (int i = 0; i < PN; i++) {
        if (P[i].first == Y || P[i].second == X) {
            bool OK = 1;
            if (P[i].first == Y) {
                ll L = min(P[i].second, X);
                ll R = max(P[i].second, X);
                for (int j = L + 1; j < R; j++)if (A[Y][j] >= 0)OK = 0;
            }
            if (P[i].second == X) {
                ll L = min(P[i].first, Y);
                ll R = max(P[i].first, Y);
                for (int j = L + 1; j < R; j++)if (A[j][X] >= 0)OK = 0;
            }
            if (!OK)continue;
            if (!idx.count(1 << i)) {
                idx[1 << i] = DP.size();
                DP.push_back(vector<int>(PN, 0));
            }
            int id = idx[1 << i];
            DP[id][i] = 1;
        }
    }
    int bitcnnt = 0;
    for (ll bt = 0; bt < (1 << PN) - 1; bt++) {
        if (!idx.count(bt))continue;
        int bit = idx[bt];
        if (DP[bit].size() == 0)continue;
        bitcnnt++;
        for (int j = 0; j < PN; j++) {
            if (DP[bit][j] == 0)continue;
            for (ll k = 0; k < PN; k++) {
                if (bt & (1 << k))continue;
                if (P[j].first != P[k].first && P[j].second != P[k].second)continue;
                if (((1 << PN) - bt - 1) & U[j][k])continue;
                if (!idx.count(bt + (1 << k))) {
                    idx[bt + (1 << k)] = DP.size();
                    DP.push_back(vector<int>(PN, 0));
                }
                int kid = idx[bt + (1 << k)];
                DP[kid][k] += DP[bit][j];
            }
        }
        DP[bit].clear();
        DP[bit].shrink_to_fit();
    }
    ll an = 0;
    if (!idx.count((1 << PN) - 1)) {
        cout << 0 << endl;
        continue;;
    }
    int fb = idx[(1 << PN) - 1];
    for (ll j = 0; j < PN; j++) {
        if (P[j].first != Y && P[j].second != X)continue;
        an += DP[fb][j];
    }
    cout << an << endl;
    // cout << bitcnnt << endl;}
}}
accuracy: 1
time_ms: 680
memory_kb: 36228
final_rank: 2

code_snippet: #include<bits/stdc++.h>
using namespace std;
int m, n, masu[11][11];
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
int dfs(int x, int y, int cnt){
    int res = 0;
    for(int i=0;i<4;i++){
        int nx = x+dx[i];
        int ny = y+dy[i];
        while(nx>=0 && nx<m && ny>=0 && ny<n && masu[ny][nx]!=1){
            if(cnt == 0 && masu[ny][nx] == 2) return 1;
            nx += dx[i];
            ny += dy[i];
        }
        if(cnt == 0 || !(nx>=0 && nx<m && ny>=0 && ny<n)) continue;
        masu[ny][nx] = 0;
        res += dfs(nx, ny, cnt-1);
        masu[ny][nx] = 1;
    }
    return res;
}
int main(){
    int sx, sy, sum;
    while(cin >> m >> n, m!=0){
        sum = 0;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
               cin >> masu[i][j];
               if(masu[i][j] == 1){
                   sum++;
               } else if(masu[i][j] == 2){
                   sx = j;
                   sy = i;
               }
            }
        }
        cout << dfs(sx, sy, sum) << endl;
    }
    return(0);
}
accuracy: 1
time_ms: 6330
memory_kb: 3036
final_rank: 14

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;


const int house = 1;
const int church = 2;
const int dx[] = { 1, 0, -1, 0 };
const int dy[] = { 0, 1, 0, -1 };
int width = -1;
int height = -1;
vector<vector<char>> index_grid;
int church_x = -1;
int church_y = -1;
unsigned char num_houses = -1;
unordered_map<int, int> dp;


inline bool is_inside(int x, int y) {
	return 0 <= x && x < width && 0 <= y && y < height;
}

inline bool is_visited(char house_idx, const int& visited_houses) {
	return (visited_houses & (1 << house_idx)) > 0;
}

inline void add_house(unsigned char house_idx, int& visited_houses) {
	visited_houses |= (1 << house_idx);
	return;
}

inline int count_visited_houses(const int& visited_houses) {
	int counter = 0;
	int v = visited_houses;

	for (int i = 0; i < num_houses; i++) {
		counter += v & 1;
		v >>= 1;
		if (v == 0) { break; }
	}

	return counter;
}

bool can_go_ahead(int x, int y, int visited_houses, int num_visited_houses) {
	char c_idx = -1;

	if (x == church_x && y == church_y) {
		if (num_visited_houses < num_houses) {
			return true;
		}
		else {
			return false;
		}
	}

	c_idx = index_grid[y][x];
	if (c_idx < 0) {
		return true;
	}
	
	return is_visited(c_idx, visited_houses);
}

int dfs(int dp_state, int x, int y) {
	int num_visited_houses = count_visited_houses(dp_state);
	unsigned char c_idx = index_grid[y][x];
	int num_paths = 0;

	if (num_visited_houses >= num_houses) {
		if (x == church_x and y == church_y) {
			return 1;
		}
	}

	dp_state = dp_state & ((1 << num_houses) - 1) | (c_idx << num_houses);
	if (dp.count(dp_state) > 0) {
		return dp[dp_state];
	}

	for (int i = 0; i < 4; i++) {
		int nx = x + dx[i];
		int ny = y + dy[i];
		char n_idx = -1;
		int n_dp_state = dp_state;

		while (is_inside(nx, ny) && can_go_ahead(nx, ny, dp_state, num_visited_houses)) {
			nx += dx[i];
			ny += dy[i];
		}

		if (!is_inside(nx, ny)) {
			continue;
		}
		
		n_idx = index_grid[ny][nx];
		if (n_idx >= 0) { add_house(n_idx, n_dp_state); }
		num_paths += dfs(n_dp_state, nx, ny);
	}

	dp[dp_state] = num_paths;
	return num_paths;
}



int main(int argc, char** argv) {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif

	while (true) {
		vector<vector<int>> grid;

		cin >> width >> height;
		if (width == 0 && height == 0) {
			break;
		}

		grid = vector<vector<int>>(height, vector<int>(width, 0));
		index_grid = vector<vector<char>>(height, vector<char>(width, -1));
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				cin >> grid[y][x];
			}
		}
		
		num_houses = 0;
		church_x = -1;
		church_y = -1;
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				if (grid[y][x] == house) {
					index_grid[y][x] = num_houses;
					num_houses++;
				}
				else if (grid[y][x] == church) {
					church_x = x;
					church_y = y;
				}
			}
		}

		dp.clear();
		dp[0] = 0;
		cout << dfs(0, church_x, church_y) << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 700
memory_kb: 52628
final_rank: 3

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;


const int house = 1;
const int church = 2;
const int dx[] = { 1, 0, -1, 0 };
const int dy[] = { 0, 1, 0, -1 };
int width = -1;
int height = -1;
vector<vector<char>> index_grid;
int church_x = -1;
int church_y = -1;
unsigned char num_houses = -1;
unordered_map<int, int> dp;


inline bool is_inside(int x, int y) {
	return 0 <= x && x < width && 0 <= y && y < height;
}

inline bool is_visited(char house_idx, const int& visited_houses) {
	return (visited_houses & (1 << house_idx)) > 0;
}

inline void add_house(unsigned char house_idx, int& visited_houses) {
	visited_houses |= (1 << house_idx);
	return;
}

inline int count_visited_houses(const int& visited_houses) {
	int counter = 0;
	int v = visited_houses;

	for (int i = 0; i < num_houses; i++) {
		counter += v & 1;
		v >>= 1;
		if (v == 0) { break; }
	}

	return counter;
}

bool can_go_ahead(int x, int y, int visited_houses, int num_visited_houses) {
	char c_idx = -1;

	if (x == church_x && y == church_y) {
		if (num_visited_houses < num_houses) {
			return true;
		}
		else {
			return false;
		}
	}

	if (index_grid[y][x] < 0) {
		return true;
	}
	
	c_idx = index_grid[y][x];
	return is_visited(c_idx, visited_houses);
}

int dfs(int dp_state, int x, int y) {
	int num_visited_houses = count_visited_houses(dp_state);
	unsigned char c_idx = index_grid[y][x];
	int num_paths = 0;

	if (num_visited_houses >= num_houses) {
		if (x == church_x and y == church_y) {
			return 1;
		}
	}

	dp_state = dp_state & ((1 << num_houses) - 1) | (c_idx << num_houses);
	if (dp.count(dp_state) > 0) {
		return dp[dp_state];
	}

	for (int i = 0; i < 4; i++) {
		int nx = x + dx[i];
		int ny = y + dy[i];
		char n_idx = -1;
		int n_dp_state = dp_state;

		while (is_inside(nx, ny) && can_go_ahead(nx, ny, dp_state, num_visited_houses)) {
			nx += dx[i];
			ny += dy[i];
		}

		if (!is_inside(nx, ny)) {
			continue;
		}
		
		n_idx = index_grid[ny][nx];
		if (n_idx >= 0) { add_house(n_idx, n_dp_state); }
		num_paths += dfs(n_dp_state, nx, ny);
	}

	dp[dp_state] = num_paths;
	return num_paths;
}



int main(int argc, char** argv) {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif

	while (true) {
		vector<vector<int>> grid;

		cin >> width >> height;
		if (width == 0 && height == 0) {
			break;
		}

		grid = vector<vector<int>>(height, vector<int>(width, 0));
		index_grid = vector<vector<char>>(height, vector<char>(width, -1));
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				cin >> grid[y][x];
			}
		}
		
		num_houses = 0;
		church_x = -1;
		church_y = -1;
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				if (grid[y][x] == house) {
					index_grid[y][x] = num_houses;
					num_houses++;
				}
				else if (grid[y][x] == church) {
					church_x = x;
					church_y = y;
				}
			}
		}

		dp.clear();
		dp[0] = 0;
		cout << dfs(0, church_x, church_y) << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 690
memory_kb: 52748
final_rank: 4

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;


const int house = 1;
const int church = 2;
const int dx[] = { 1, 0, -1, 0 };
const int dy[] = { 0, 1, 0, -1 };
int width = -1;
int height = -1;
vector<vector<char>> index_grid;
int church_x = -1;
int church_y = -1;
unsigned char num_houses = -1;
unordered_map<int, int> dp;


inline bool is_inside(int x, int y) {
	return 0 <= x && x < width && 0 <= y && y < height;
}

inline int count_visited_houses(const int& visited_houses) {
	int counter = 0;
	int v = visited_houses;

	for (int i = 0; i < num_houses; i++) {
		counter += v & 1;
		v >>= 1;
		if (v == 0) { break; }
	}

	return counter;
}

inline bool is_visited(char house_idx, const int& visited_houses) {
	return (visited_houses & (1 << house_idx)) > 0;
}

inline bool can_go_ahead(int x, int y, int visited_houses, int num_visited_houses) {
	char c_idx = -1;

	if (x == church_x && y == church_y) {
		if (num_visited_houses < num_houses) {
			return true;
		}
		else {
			return false;
		}
	}

	if (index_grid[y][x] < 0) {
		return true;
	}
	
	c_idx = index_grid[y][x];
	return is_visited(c_idx, visited_houses);
}

inline void add_house(unsigned char house_idx, int& visited_houses) {
	visited_houses |= (1 << house_idx);
	return;
}

int dfs(int dp_state, int x, int y) {
	int num_visited_houses = count_visited_houses(dp_state);
	unsigned char c_idx = index_grid[y][x];
	int num_paths = 0;

	if (num_visited_houses >= num_houses) {
		if (x == church_x and y == church_y) {
			return 1;
		}
	}

	dp_state = dp_state & ((1 << num_houses) - 1) | (c_idx << num_houses);
	if (dp.count(dp_state) > 0) {
		return dp[dp_state];
	}

	for (int i = 0; i < 4; i++) {
		int nx = x + dx[i];
		int ny = y + dy[i];
		char n_idx = -1;
		int n_dp_state = dp_state;

		while (is_inside(nx, ny) && can_go_ahead(nx, ny, dp_state, num_visited_houses)) {
			nx += dx[i];
			ny += dy[i];
		}

		if (!is_inside(nx, ny)) {
			continue;
		}
		
		n_idx = index_grid[ny][nx];
		if (n_idx >= 0) { add_house(n_idx, n_dp_state); }
		num_paths += dfs(n_dp_state, nx, ny);
	}

	dp[dp_state] = num_paths;
	return num_paths;
}



int main(int argc, char** argv) {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif

	while (true) {
		vector<vector<int>> grid;

		cin >> width >> height;
		if (width == 0 && height == 0) {
			break;
		}

		grid = vector<vector<int>>(height, vector<int>(width, 0));
		index_grid = vector<vector<char>>(height, vector<char>(width, -1));
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				cin >> grid[y][x];
			}
		}
		
		num_houses = 0;
		church_x = -1;
		church_y = -1;
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				if (grid[y][x] == house) {
					index_grid[y][x] = num_houses;
					num_houses++;
				}
				else if (grid[y][x] == church) {
					church_x = x;
					church_y = y;
				}
			}
		}

		dp.clear();
		dp[0] = 0;
		cout << dfs(0, church_x, church_y) << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 690
memory_kb: 52764
final_rank: 6

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <unordered_map>
#include <vector>

using namespace std;

const int house = 1;
const int church = 2;
const int dx[] = { 1, 0, -1, 0 };
const int dy[] = { 0, 1, 0, -1 };
int width = -1;
int height = -1;
vector<vector<char>> index_grid;
int church_x = -1;
int church_y = -1;
unsigned char num_houses = -1;
unordered_map<int, int> dp;


inline bool is_inside(int x, int y) {
	return 0 <= x && x < width && 0 <= y && y < height;
}

inline int count_visited_houses(const int& visited_houses) {
	int counter = 0;
	int v = visited_houses;

	for (int i = 0; i < num_houses; i++) {
		counter += v & 1;
		v >>= 1;
		if (v == 0) { break; }
	}

	return counter;
}

inline bool is_visited(char house_idx, const int& visited_houses) {
	return (visited_houses & (1 << house_idx)) > 0;
}

bool can_go_ahead(int x, int y, int visited_houses, int num_visited_houses) {
	char c_idx = -1;

	if (x == church_x && y == church_y) {
		if (num_visited_houses < num_houses) {
			return true;
		}
		else {
			return false;
		}
	}

	if (index_grid[y][x] < 0) {
		return true;
	}
	
	c_idx = index_grid[y][x];
	return is_visited(c_idx, visited_houses);
}

inline void add_house(unsigned char house_idx, int& visited_houses) {
	visited_houses|= (1 << house_idx);
	return;
}

int dfs(int dp_state, int x, int y) {
	int num_visited_houses = count_visited_houses(dp_state);
	unsigned char c_idx = index_grid[y][x];
	int num_paths = 0;

	if (num_visited_houses >= num_houses) {
		if (x == church_x and y == church_y) {
			return 1;
		}
	}

	dp_state = dp_state & ((1 << num_houses) - 1) | (c_idx << num_houses);
	if (dp.count(dp_state) > 0) {
		return dp[dp_state];
	}

	for (int i = 0; i < 4; i++) {
		int nx = x + dx[i];
		int ny = y + dy[i];
		char n_idx = -1;
		int n_dp_state = dp_state;

		while (is_inside(nx, ny) && can_go_ahead(nx, ny, dp_state, num_visited_houses)) {
			nx += dx[i];
			ny += dy[i];
		}

		if (!is_inside(nx, ny)) {
			continue;
		}
		
		n_idx = index_grid[ny][nx];
		if (n_idx >= 0) { add_house(n_idx, n_dp_state); }
		num_paths += dfs(n_dp_state, nx, ny);
	}

	dp[dp_state] = num_paths;
	return num_paths;
}



int main(int argc, char** argv) {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif

	while (true) {
		vector<vector<int>> grid;

		cin >> width >> height;
		if (width == 0 && height == 0) {
			break;
		}

		grid = vector<vector<int>>(height, vector<int>(width, 0));
		index_grid = vector<vector<char>>(height, vector<char>(width, -1));
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				cin >> grid[y][x];
			}
		}
		
		num_houses = 0;
		church_x = -1;
		church_y = -1;
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				if (grid[y][x] == house) {
					index_grid[y][x] = num_houses;
					num_houses++;
				}
				else if (grid[y][x] == church) {
					church_x = x;
					church_y = y;
				}
			}
		}

		dp.clear();
		dp[0] = 0;
		cout << dfs(0, church_x, church_y) << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 690
memory_kb: 52796
final_rank: 8

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <unordered_map>
#include <vector>

using namespace std;

const int house = 1;
const int church = 2;
const int dx[] = { 1, 0, -1, 0 };
const int dy[] = { 0, 1, 0, -1 };
int width = -1;
int height = -1;
vector<vector<char>> index_grid;
int church_x = -1;
int church_y = -1;
unsigned char num_houses = -1;
unordered_map<int, int> dp;


inline bool is_inside(int x, int y) {
	return 0 <= x && x < width && 0 <= y && y < height;
}

int count_visited_houses(const int& visited_houses) {
	int counter = 0;
	int v = visited_houses;

	for (int i = 0; i < num_houses; i++) {
		counter += v & 1;
		v >>= 1;
		if (v == 0) { break; }
	}

	return counter;
}

inline bool is_visited(char house_idx, const int& visited_houses) {
	return (visited_houses & (1 << house_idx)) > 0;
}

bool can_go_ahead(int x, int y, int visited_houses, int num_visited_houses) {
	char c_idx = -1;

	if (x == church_x && y == church_y) {
		if (num_visited_houses < num_houses) {
			return true;
		}
		else {
			return false;
		}
	}

	if (index_grid[y][x] < 0) {
		return true;
	}
	
	c_idx = index_grid[y][x];
	return is_visited(c_idx, visited_houses);
}

inline void add_house(unsigned char house_idx, int& visited_houses) {
	visited_houses|= (1 << house_idx);
	return;
}

int dfs(int dp_state, int x, int y) {
	int num_visited_houses = count_visited_houses(dp_state);
	unsigned char c_idx = index_grid[y][x];
	int num_paths = 0;

	if (num_visited_houses >= num_houses) {
		if (x == church_x and y == church_y) {
			return 1;
		}
	}

	dp_state = dp_state & ((1 << num_houses) - 1) | (c_idx << num_houses);
	if (dp.count(dp_state) > 0) {
		return dp[dp_state];
	}

	for (int i = 0; i < 4; i++) {
		int nx = x + dx[i];
		int ny = y + dy[i];
		char n_idx = -1;
		int n_dp_state = dp_state;

		while (is_inside(nx, ny) && can_go_ahead(nx, ny, dp_state, num_visited_houses)) {
			nx += dx[i];
			ny += dy[i];
		}

		if (!is_inside(nx, ny)) {
			continue;
		}
		
		n_idx = index_grid[ny][nx];
		if (n_idx >= 0) { add_house(n_idx, n_dp_state); }
		num_paths += dfs(n_dp_state, nx, ny);
	}

	dp[dp_state] = num_paths;
	return num_paths;
}



int main(int argc, char** argv) {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif

	while (true) {
		vector<vector<int>> grid;

		cin >> width >> height;
		if (width == 0 && height == 0) {
			break;
		}

		grid = vector<vector<int>>(height, vector<int>(width, 0));
		index_grid = vector<vector<char>>(height, vector<char>(width, -1));
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				cin >> grid[y][x];
			}
		}
		
		num_houses = 0;
		church_x = -1;
		church_y = -1;
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				if (grid[y][x] == house) {
					index_grid[y][x] = num_houses;
					num_houses++;
				}
				else if (grid[y][x] == church) {
					church_x = x;
					church_y = y;
				}
			}
		}

		dp.clear();
		dp[0] = 0;
		cout << dfs(0, church_x, church_y) << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 700
memory_kb: 52764
final_rank: 9

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <unordered_map>
#include <vector>

using namespace std;

const int house = 1;
const int church = 2;
const int dx[] = { 1, 0, -1, 0 };
const int dy[] = { 0, 1, 0, -1 };
int width = -1;
int height = -1;
vector<vector<char>> index_grid;
int church_x = -1;
int church_y = -1;
unsigned char num_houses = -1;
unordered_map<int, int> dp;


inline bool is_inside(int x, int y) {
	return 0 <= x && x < width && 0 <= y && y < height;
}

int count_visited_houses(const int& visited_houses) {
	int counter = 0;
	int v = visited_houses;

	for (int i = 0; i < num_houses; i++) {
		counter += v & 1;
		v >>= 1;
	}

	return counter;
}

inline bool is_visited(char house_idx, const int& visited_houses) {
	return (visited_houses & (1 << house_idx)) > 0;
}

bool can_go_ahead(int x, int y, int visited_houses, int num_visited_houses) {
	char c_idx = -1;

	if (x == church_x && y == church_y) {
		if (num_visited_houses < num_houses) {
			return true;
		}
		else {
			return false;
		}
	}

	if (index_grid[y][x] < 0) {
		return true;
	}
	
	c_idx = index_grid[y][x];
	return is_visited(c_idx, visited_houses);
}

inline void add_house(unsigned char house_idx, int& visited_houses) {
	visited_houses|= (1 << house_idx);
	return;
}

int dfs(int dp_state, int x, int y) {
	int num_visited_houses = count_visited_houses(dp_state);
	unsigned char c_idx = index_grid[y][x];
	int num_paths = 0;

	if (num_visited_houses >= num_houses) {
		if (x == church_x and y == church_y) {
			return 1;
		}
	}

	dp_state = dp_state & ((1 << num_houses) - 1) | (c_idx << num_houses);
	if (dp.count(dp_state) > 0) {
		return dp[dp_state];
	}

	for (int i = 0; i < 4; i++) {
		int nx = x + dx[i];
		int ny = y + dy[i];
		char n_idx = -1;
		int n_dp_state = dp_state;

		while (is_inside(nx, ny) && can_go_ahead(nx, ny, dp_state, num_visited_houses)) {
			nx += dx[i];
			ny += dy[i];
		}

		if (!is_inside(nx, ny)) {
			continue;
		}
		
		n_idx = index_grid[ny][nx];
		if (n_idx >= 0) { add_house(n_idx, n_dp_state); }
		num_paths += dfs(n_dp_state, nx, ny);
	}

	dp[dp_state] = num_paths;
	return num_paths;
}



int main(int argc, char** argv) {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif

	while (true) {
		vector<vector<int>> grid;

		cin >> width >> height;
		if (width == 0 && height == 0) {
			break;
		}

		grid = vector<vector<int>>(height, vector<int>(width, 0));
		index_grid = vector<vector<char>>(height, vector<char>(width, -1));
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				cin >> grid[y][x];
			}
		}
		
		num_houses = 0;
		church_x = -1;
		church_y = -1;
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				if (grid[y][x] == house) {
					index_grid[y][x] = num_houses;
					num_houses++;
				}
				else if (grid[y][x] == church) {
					church_x = x;
					church_y = y;
				}
			}
		}

		dp.clear();
		dp[0] = 0;
		cout << dfs(0, church_x, church_y) << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 690
memory_kb: 52760
final_rank: 5

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <unordered_map>
#include <vector>

using namespace std;

const int house = 1;
const int church = 2;
const int dx[] = { 1, 0, -1, 0 };
const int dy[] = { 0, 1, 0, -1 };
int width = -1;
int height = -1;
vector<vector<char>> index_grid;
int church_x = -1;
int church_y = -1;
unsigned char num_houses = -1;
unordered_map<int, int> dp;


inline bool is_inside(int x, int y) {
	return 0 <= x && x < width && 0 <= y && y < height;
}

int count_visited_houses(const int& visited_houses) {
	int counter = 0;
	int v = visited_houses;

	for (int i = 0; i < num_houses; i++) {
		counter += v & 1;
		v >>= 1;
	}

	return counter;
}

inline bool is_visited(char house_idx, const int& visited_houses) {
	return (visited_houses & (1 << house_idx)) > 0;
}

bool can_go_ahead(int x, int y, int visited_houses, int num_visited_houses) {
	char c_idx = -1;

	if (x == church_x && y == church_y) {
		if (num_visited_houses < num_houses) {
			return true;
		}
		else {
			return false;
		}
	}

	if (index_grid[y][x] < 0) {
		return true;
	}
	
	c_idx = index_grid[y][x];
	return is_visited(c_idx, visited_houses);
}

inline void add_house(unsigned char house_idx, int& visited_houses) {
	visited_houses|= (1 << house_idx);
	return;
}

int dfs(int dp_state, int x, int y) {
	int num_visited_houses = count_visited_houses(dp_state);
	unsigned char c_idx = index_grid[y][x];
	int num_paths = 0;

	if (num_visited_houses >= num_houses) {
		if (x == church_x and y == church_y) {
			return 1;
		}
	}

	dp_state = dp_state & ((1 << num_houses) - 1) | (c_idx << num_houses);
	if (dp.count(dp_state) > 0) {
		return dp[dp_state];
	}

	for (int i = 0; i < 4; i++) {
		int nx = x + dx[i];
		int ny = y + dy[i];
		char n_idx = -1;
		int n_dp_state = dp_state;

		while (is_inside(nx, ny) && can_go_ahead(nx, ny, dp_state, num_visited_houses)) {
			nx += dx[i];
			ny += dy[i];
		}

		if (!is_inside(nx, ny)) {
			continue;
		}
		
		n_idx = index_grid[ny][nx];
		add_house(n_idx, n_dp_state);
		num_paths += dfs(n_dp_state, nx, ny);
	}

	dp[dp_state] = num_paths;
	return num_paths;
}



int main(int argc, char** argv) {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif

	while (true) {
		vector<vector<int>> grid;

		cin >> width >> height;
		if (width == 0 && height == 0) {
			break;
		}

		grid = vector<vector<int>>(height, vector<int>(width, 0));
		index_grid = vector<vector<char>>(height, vector<char>(width, -1));
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				cin >> grid[y][x];
			}
		}
		
		num_houses = 0;
		church_x = -1;
		church_y = -1;
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				if (grid[y][x] == house) {
					index_grid[y][x] = num_houses;
					num_houses++;
				}
				else if (grid[y][x] == church) {
					church_x = x;
					church_y = y;
				}
			}
		}

		dp.clear();
		dp[0] = 0;
		cout << dfs(0, church_x, church_y) << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 700
memory_kb: 52696
final_rank: 7

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <unordered_map>
#include <vector>

using namespace std;

const int house = 1;
const int church = 2;
const int dx[] = { 1, 0, -1, 0 };
const int dy[] = { 0, 1, 0, -1 };
int width = -1;
int height = -1;
vector<vector<char>> index_grid;
int church_x = -1;
int church_y = -1;
unsigned char num_houses = -1;
unordered_map<int, int> dp;


inline bool is_inside(int x, int y) {
	return 0 <= x && x < width && 0 <= y && y < height;
}

int count_visited_houses(const int& visited_houses) {
	int counter = 0;
	int v = visited_houses;

	for (int i = 0; i < num_houses; i++) {
		counter += v & 1;
		v >>= 1;
	}

	return counter;
}

inline bool is_visited(char house_idx, const int& visited_houses) {
	return (visited_houses & (1 << house_idx)) > 0;
}

bool can_go_ahead(int x, int y, const int& visited_houses) {
	int num_visited_houses = count_visited_houses(visited_houses);
	char c_idx = -1;

	if (x == church_x && y == church_y) {
		if (num_visited_houses < num_houses) {
			return true;
		}
		else {
			return false;
		}
	}

	if (index_grid[y][x] < 0) {
		return true;
	}
	
	c_idx = index_grid[y][x];
	return is_visited(c_idx, visited_houses);
}

inline void add_house(unsigned char house_idx, int& visited_houses) {
	visited_houses|= (1 << house_idx);
	return;
}

int dfs(int dp_state, int x, int y) {
	int num_visited_houses = count_visited_houses(dp_state);
	unsigned char c_idx = index_grid[y][x];
	int num_paths = 0;

	if (num_visited_houses >= num_houses) {
		if (x == church_x and y == church_y) {
			return 1;
		}
	}

	dp_state = dp_state & ((1 << num_houses) - 1) | (c_idx << num_houses);
	if (dp.count(dp_state) > 0) {
		return dp[dp_state];
	}

	for (int i = 0; i < 4; i++) {
		int nx = x + dx[i];
		int ny = y + dy[i];
		char n_idx = -1;
		int n_dp_state = dp_state;

		while (is_inside(nx, ny) && can_go_ahead(nx, ny, dp_state)) {
			nx += dx[i];
			ny += dy[i];
		}

		if (!is_inside(nx, ny)) {
			continue;
		}
		
		n_idx = index_grid[ny][nx];
		add_house(n_idx, n_dp_state);
		num_paths += dfs(n_dp_state, nx, ny);
	}

	dp[dp_state] = num_paths;
	return num_paths;
}



int main(int argc, char** argv) {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif

	while (true) {
		vector<vector<int>> grid;

		cin >> width >> height;
		if (width == 0 && height == 0) {
			break;
		}

		grid = vector<vector<int>>(height, vector<int>(width, 0));
		index_grid = vector<vector<char>>(height, vector<char>(width, -1));
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				cin >> grid[y][x];
			}
		}
		
		num_houses = 0;
		church_x = -1;
		church_y = -1;
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				if (grid[y][x] == house) {
					index_grid[y][x] = num_houses;
					num_houses++;
				}
				else if (grid[y][x] == church) {
					church_x = x;
					church_y = y;
				}
			}
		}

		dp.clear();
		dp[0] = 0;
		cout << dfs(0, church_x, church_y) << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 1020
memory_kb: 52728
final_rank: 12

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <unordered_map>
#include <vector>

using namespace std;

const int house = 1;
const int church = 2;
const int dx[] = { 1, 0, -1, 0 };
const int dy[] = { 0, 1, 0, -1 };
int width = -1;
int height = -1;
vector<vector<char>> index_grid;
int church_x = -1;
int church_y = -1;
unsigned char num_houses = -1;
unordered_map<int, int> dp;


inline bool is_inside(int x, int y) {
	return 0 <= x && x < width && 0 <= y && y < height;
}

int count_visited_houses(const int& visited_houses) {
	int counter = 0;
	int v = visited_houses;

	for (int i = 0; i < num_houses; i++) {
		counter += v & 1;
		v >>= 1;
	}

	return counter;
}

inline bool is_visited(char idx, const int& visited_houses) {
	return (visited_houses & (1 << idx)) > 0;
}

bool can_go_ahead(int x, int y, const int& visited_houses) {
	int num_visited_houses = count_visited_houses(visited_houses);
	char c_idx = -1;

	if (x == church_x && y == church_y) {
		if (num_visited_houses < num_houses) {
			return true;
		}
		else {
			return false;
		}
	}

	if (index_grid[y][x] < 0) {
		return true;
	}
	
	c_idx = index_grid[y][x];
	return is_visited(c_idx, visited_houses);
}

inline void add_house(unsigned char house_idx, int& visited_houses) {
	visited_houses|= (1 << house_idx);
	return;
}

int dfs(int dp_state, int x, int y) {
	int num_visited_houses = count_visited_houses(dp_state);
	unsigned char c_idx = index_grid[y][x];
	int num_paths = 0;

	dp_state = dp_state & ((1 << num_houses) - 1) | (c_idx << num_houses);
	if (num_visited_houses >= num_houses) {
		if (x == church_x and y == church_y) {
			return 1;
		}
	}

	if (dp.count(dp_state) > 0) {
		return dp[dp_state];
	}

	for (int i = 0; i < 4; i++) {
		int nx = x + dx[i];
		int ny = y + dy[i];
		char n_idx = -1;
		int n_dp_state = dp_state;

		while (is_inside(nx, ny) && can_go_ahead(nx, ny, dp_state)) {
			nx += dx[i];
			ny += dy[i];
		}

		if (!is_inside(nx, ny)) {
			continue;
		}
		
		n_idx = index_grid[ny][nx];
		add_house(n_idx, n_dp_state);
		num_paths += dfs(n_dp_state, nx, ny);
	}

	dp[dp_state] = num_paths;
	return num_paths;
}



int main(int argc, char** argv) {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif

	while (true) {
		vector<vector<int>> grid;

		cin >> width >> height;
		if (width == 0 && height == 0) {
			break;
		}

		grid = vector<vector<int>>(height, vector<int>(width, 0));
		index_grid = vector<vector<char>>(height, vector<char>(width, -1));
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				cin >> grid[y][x];
			}
		}
		
		num_houses = 0;
		church_x = -1;
		church_y = -1;
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				if (grid[y][x] == house) {
					index_grid[y][x] = num_houses;
					num_houses++;
				}
				else if (grid[y][x] == church) {
					church_x = x;
					church_y = y;
				}
			}
		}

		dp.clear();
		dp[0] = 0;
		cout << dfs(0, church_x, church_y) << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 1040
memory_kb: 52584
final_rank: 13

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <unordered_map>
#include <vector>

using namespace std;

const int house = 1;
const int church = 2;
const int dx[] = { 1, 0, -1, 0 };
const int dy[] = { 0, -1, 0, 1 };
int width = -1;
int height = -1;
vector<vector<char>> index_grid;
int church_x = -1;
int church_y = -1;
unsigned char num_houses = -1;
unordered_map<int, int> dp;


inline bool is_inside(int x, int y) {
	return 0 <= x && x < width && 0 <= y && y < height;
}

int count_visited_houses(const int& visited_houses) {
	int counter = 0;
	int v = visited_houses;

	for (int i = 0; i < num_houses; i++) {
		counter += v & 1;
		v >>= 1;
	}


	return counter;
}

bool is_visited(char idx, const int& visited_houses) {
	return (visited_houses & (1 << idx)) > 0;
}

bool can_go_ahead(int x, int y, const int& visited_houses) {
	int num_visited_houses = count_visited_houses(visited_houses);
	char c_idx = -1;

	if (x == church_x && y == church_y) {
		if (num_visited_houses < num_houses) {
			return true;
		}
		else {
			return false;
		}
	}

	if (index_grid[y][x] < 0) {
		return true;
	}
	
	c_idx = index_grid[y][x];
	return is_visited(c_idx, visited_houses);
}

void add_house(unsigned char house_idx, int& visited_houses) {
	visited_houses|= (1 << house_idx);
	return;
}

int dfs(int dp_state, int x, int y) {
	int num_visited_houses = count_visited_houses(dp_state);
	unsigned char c_idx = index_grid[y][x];
	int num_paths = 0;

	dp_state = dp_state & ((1 << num_houses) - 1) | (c_idx << num_houses);
	if (num_visited_houses >= num_houses) {
		if (x == church_x and y == church_y) {
			return 1;
		}
	}

	if (dp.count(dp_state) > 0) {
		return dp[dp_state];
	}

	for (int i = 0; i < 4; i++) {
		int nx = x + dx[i];
		int ny = y + dy[i];
		char n_idx = -1;
		int n_dp_state = dp_state;

		while (is_inside(nx, ny) && can_go_ahead(nx, ny, dp_state)) {
			nx += dx[i];
			ny += dy[i];
		}

		if (!is_inside(nx, ny)) {
			continue;
		}
		
		n_idx = index_grid[ny][nx];
		add_house(n_idx, n_dp_state);
		num_paths += dfs(n_dp_state, nx, ny);
	}

	dp[dp_state] = num_paths;
	return num_paths;
}



int main(int argc, char** argv) {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif

	while (true) {
		vector<vector<int>> grid;

		cin >> width >> height;
		if (width == 0 && height == 0) {
			break;
		}

		grid = vector<vector<int>>(height, vector<int>(width, 0));
		index_grid = vector<vector<char>>(height, vector<char>(width, -1));
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				cin >> grid[y][x];
			}
		}
		
		num_houses = 0;
		church_x = -1;
		church_y = -1;
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				if (grid[y][x] == house) {
					index_grid[y][x] = num_houses;
					num_houses++;
				}
				else if (grid[y][x] == church) {
					church_x = x;
					church_y = y;
				}
			}
		}

		dp.clear();
		dp[0] = 0;
		cout << dfs(0, church_x, church_y) << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 970
memory_kb: 52692
final_rank: 11

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <unordered_map>
#include <vector>

using namespace std;

const int house = 1;
const int church = 2;
const int dx[] = { 1, 0, -1, 0 };
const int dy[] = { 0, -1, 0, 1 };
const int max_num_houses_in_dp = 23;
int width = -1;
int height = -1;
vector<vector<char>> index_grid;
int church_x = -1;
int church_y = -1;
unsigned char num_houses = -1;
int max_num_houses = -1;
unordered_map<int, int> dp;


inline bool is_inside(int x, int y) {
	return 0 <= x && x < width && 0 <= y && y < height;
}

int count_visited_houses(const int& visited_houses) {
	int counter = 0;
	int v = visited_houses;

	for (int i = 0; i < num_houses; i++) {
		counter += v & 1;
		v >>= 1;
	}


	return counter;
}

bool is_visited(char idx, const int& visited_houses) {
	return (visited_houses & (1 << idx)) > 0;
}

bool can_go_ahead(int x, int y, const int& visited_houses) {
	int num_visited_houses = count_visited_houses(visited_houses);
	char c_idx = -1;

	if (x == church_x && y == church_y) {
		if (num_visited_houses < num_houses) {
			return true;
		}
		else {
			return false;
		}
	}

	if (index_grid[y][x] < 0) {
		return true;
	}
	
	c_idx = index_grid[y][x];
	return is_visited(c_idx, visited_houses);
}

void add_house(unsigned char house_idx, int& visited_houses) {
	visited_houses|= (1 << house_idx);
	return;
}

int dfs(int dp_state, int x, int y) {
	int num_visited_houses = count_visited_houses(dp_state);
	unsigned char c_idx = index_grid[y][x];
	int num_paths = 0;

	dp_state = dp_state & ((1 << num_houses) - 1) | (c_idx << num_houses);
	if (num_visited_houses >= num_houses) {
		if (x == church_x and y == church_y) {
			return 1;
		}
	}

	if (num_visited_houses < max_num_houses) {
		if (dp.count(dp_state) > 0) {
			return dp[dp_state];
		}
	}

	for (int i = 0; i < 4; i++) {
		int nx = x + dx[i];
		int ny = y + dy[i];
		char n_idx = -1;
		int n_dp_state = dp_state;

		while (is_inside(nx, ny) && can_go_ahead(nx, ny, dp_state)) {
			nx += dx[i];
			ny += dy[i];
		}

		if (!is_inside(nx, ny)) {
			continue;
		}
		
		n_idx = index_grid[ny][nx];
		add_house(n_idx, n_dp_state);
		num_paths += dfs(n_dp_state, nx, ny);
	}

	if (num_visited_houses < max_num_houses) {
		dp[dp_state] = num_paths;
	}
	return num_paths;
}



int main(int argc, char** argv) {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif

	while (true) {
		vector<vector<char>> grid;

		cin >> width >> height;
		if (width == 0 && height == 0) {
			break;
		}
		
		index_grid.clear();
		for (int y = 0; y < height; y++) {
			vector<char> row(width, -1);

			index_grid.push_back(row);
			for (int x = 0; x < width; x++) {
				int cell = -1;

				cin >> cell;
				row[x] = cell;
			}
			grid.push_back(row);
		}
		
		num_houses = 0;
		church_x = -1;
		church_y = -1;
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				if (grid[y][x] == house) {
					index_grid[y][x] = num_houses;
					num_houses++;
				}
				else if (grid[y][x] == church) {
					church_x = x;
					church_y = y;
				}
			}
		}

		max_num_houses = min(max_num_houses_in_dp, int(num_houses));
		dp.clear();
		dp[0] = 0;
		cout << dfs(0, church_x, church_y) << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 970
memory_kb: 52616
final_rank: 10

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <map>
#include <vector>

using namespace std;

const int house = 1;
const int church = 2;
const int dx[] = { 1, 0, -1, 0 };
const int dy[] = { 0, -1, 0, 1 };
const int max_num_houses_in_dp = 23;
int width = -1;
int height = -1;
vector<vector<char>> index_grid;
int church_x = -1;
int church_y = -1;
unsigned char num_houses = -1;
int max_num_houses = -1;
map<int, int> dp;


inline bool is_inside(int x, int y) {
	return 0 <= x && x < width && 0 <= y && y < height;
}

int count_visited_houses(const int& visited_houses) {
	int counter = 0;
	int v = visited_houses;

	for (int i = 0; i < num_houses; i++) {
		counter += v & 1;
		v >>= 1;
	}


	return counter;
}

bool is_visited(char idx, const int& visited_houses) {
	return (visited_houses & (1 << idx)) > 0;
}

bool can_go_ahead(int x, int y, const int& visited_houses) {
	int num_visited_houses = count_visited_houses(visited_houses);
	char c_idx = -1;

	if (x == church_x && y == church_y) {
		if (num_visited_houses < num_houses) {
			return true;
		}
		else {
			return false;
		}
	}

	if (index_grid[y][x] < 0) {
		return true;
	}
	
	c_idx = index_grid[y][x];
	return is_visited(c_idx, visited_houses);
}

void add_house(unsigned char house_idx, int& visited_houses) {
	visited_houses|= (1 << house_idx);
	return;
}

int dfs(int dp_state, int x, int y) {
	int num_visited_houses = count_visited_houses(dp_state);
	unsigned char c_idx = index_grid[y][x];
	int num_paths = 0;

	dp_state = dp_state & ((1 << num_houses) - 1) | (c_idx << num_houses);
	if (num_visited_houses >= num_houses) {
		if (x == church_x and y == church_y) {
			return 1;
		}
	}

	if (num_visited_houses < max_num_houses) {
		if (dp.count(dp_state) > 0) {
			return dp[dp_state];
		}
	}

	for (int i = 0; i < 4; i++) {
		int nx = x + dx[i];
		int ny = y + dy[i];
		char n_idx = -1;
		int n_dp_state = dp_state;

		while (is_inside(nx, ny) && can_go_ahead(nx, ny, dp_state)) {
			nx += dx[i];
			ny += dy[i];
		}

		if (!is_inside(nx, ny)) {
			continue;
		}
		
		n_idx = index_grid[ny][nx];
		add_house(n_idx, n_dp_state);
		num_paths += dfs(n_dp_state, nx, ny);
	}

	if (num_visited_houses < max_num_houses) {
		dp[dp_state] = num_paths;
	}
	return num_paths;
}



int main(int argc, char** argv) {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif

	while (true) {
		vector<vector<char>> grid;

		cin >> width >> height;
		if (width == 0 && height == 0) {
			break;
		}
		
		index_grid.clear();
		for (int y = 0; y < height; y++) {
			vector<char> row(width, -1);

			index_grid.push_back(row);
			for (int x = 0; x < width; x++) {
				int cell = -1;

				cin >> cell;
				row[x] = cell;
			}
			grid.push_back(row);
		}
		
		num_houses = 0;
		church_x = -1;
		church_y = -1;
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				if (grid[y][x] == house) {
					index_grid[y][x] = num_houses;
					num_houses++;
				}
				else if (grid[y][x] == church) {
					church_x = x;
					church_y = y;
				}
			}
		}

		max_num_houses = min(max_num_houses_in_dp, int(num_houses));
		dp.clear();
		dp[0] = 0;
		cout << dfs(0, church_x, church_y) << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 1690
memory_kb: 55424
final_rank: 15

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <map>
#include <vector>

using namespace std;

const int house = 1;
const int church = 2;
const int dx[] = { 1, 0, -1, 0 };
const int dy[] = { 0, -1, 0, 1 };
const int max_num_houses_in_dp = 23;
int width = -1;
int height = -1;
vector<vector<char>> index_grid;
int church_x = -1;
int church_y = -1;
unsigned char num_houses = -1;
int max_num_houses = -1;
map<pair<pair<unsigned short, unsigned char>, unsigned char>, int> dp;


inline bool is_inside(int x, int y) {
	return 0 <= x && x < width && 0 <= y && y < height;
}

int count_visited_houses(const pair<unsigned short, unsigned char>& visited_houses) {
	int counter = 0;
	int f = visited_houses.first;
	int s = visited_houses.second;

	while (f > 0) {
		counter += f & 1;
		f >>= 1;
	}

	while (s > 0) {
		counter += s & 1;
		s >>= 1;
	}

	return counter;
}

bool is_visited(char idx, const pair<unsigned short, unsigned char>& visited_houses) {
	if (idx < 16) {
		return (visited_houses.first & (1 << idx)) > 0;
	}
	else {
		idx -= 16;
		return (visited_houses.second & (1 << idx)) > 0;
	}
}

bool can_go_ahead(int x, int y, const pair<unsigned short, unsigned char>& visited_houses) {
	int num_visited_houses = count_visited_houses(visited_houses);
	char c_idx = -1;

	if (x == church_x && y == church_y) {
		if (num_visited_houses < num_houses) {
			return true;
		}
		else {
			return false;
		}
	}

	if (index_grid[y][x] < 0) {
		return true;
	}
	
	c_idx = index_grid[y][x];
	return is_visited(c_idx, visited_houses);
}

void add_house(unsigned char house_idx, pair<unsigned short, unsigned char>& visited_houses) {
	if (house_idx < 16) {
		visited_houses.first |= (1 << house_idx);
	}
	else {
		house_idx -= 16;
		visited_houses.second |= (1 << house_idx);
	}
	return;
}

int dfs(pair<pair<unsigned short, unsigned char>, unsigned char> dp_state, int x, int y) {
	pair<unsigned short, unsigned char> c_visited_houses = dp_state.first;
	int num_visited_houses = count_visited_houses(c_visited_houses);
	unsigned char c_idx = index_grid[y][x];
	int num_paths = 0;

	dp_state = pair<pair<unsigned short, unsigned char>, unsigned char>(c_visited_houses, c_idx);
	if (num_visited_houses >= num_houses) {
		if (x == church_x and y == church_y) {
			return 1;
		}
	}

	if (num_visited_houses < max_num_houses) {
		if (dp.count(dp_state) > 0) {
			return dp[dp_state];
		}
	}

	for (int i = 0; i < 4; i++) {
		int nx = x + dx[i];
		int ny = y + dy[i];
		char n_idx = -1;
		pair<unsigned short, unsigned char> n_visited_houses = c_visited_houses;

		while (is_inside(nx, ny) && can_go_ahead(nx, ny, c_visited_houses)) {
			nx += dx[i];
			ny += dy[i];
		}

		if (!is_inside(nx, ny)) {
			continue;
		}
		
		n_idx = index_grid[ny][nx];
		add_house(n_idx, n_visited_houses);
		num_paths += dfs(pair<pair<unsigned short, unsigned char>, unsigned char>(n_visited_houses, n_idx), nx, ny);
	}

	if (num_visited_houses < max_num_houses) {
		dp[dp_state] = num_paths;
	}
	return num_paths;
}



int main(int argc, char** argv) {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif

	while (true) {
		vector<vector<char>> grid;
		pair<pair<unsigned short, unsigned char>, unsigned char> initial_state(pair<unsigned short, unsigned char>(0, 0), 0);

		cin >> width >> height;
		if (width == 0 && height == 0) {
			break;
		}
		
		index_grid.clear();
		for (int y = 0; y < height; y++) {
			vector<char> row(width, -1);

			index_grid.push_back(row);
			for (int x = 0; x < width; x++) {
				int cell = -1;

				cin >> cell;
				row[x] = cell;
			}
			grid.push_back(row);
		}
		
		num_houses = 0;
		church_x = -1;
		church_y = -1;
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				if (grid[y][x] == house) {
					index_grid[y][x] = num_houses;
					num_houses++;
				}
				else if (grid[y][x] == church) {
					church_x = x;
					church_y = y;
				}
			}
		}

		max_num_houses = min(max_num_houses_in_dp, int(num_houses));
		dp.clear();
		dp[initial_state] = 0;
		cout << dfs(initial_state, church_x, church_y) << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 1720
memory_kb: 72956
final_rank: 17

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <map>
#include <vector>

using namespace std;

const int house = 1;
const int church = 2;
const int dx[] = { 1, 0, -1, 0 };
const int dy[] = { 0, -1, 0, 1 };
const int max_num_houses_in_dp = 23;
int width = -1;
int height = -1;
vector<vector<char>> index_grid;
int church_x = -1;
int church_y = -1;
unsigned char num_houses = -1;
int max_num_houses = -1;
map<pair<pair<unsigned short, unsigned char>, unsigned char>, int> dp;


inline bool is_inside(int x, int y) {
	return 0 <= x && x < width && 0 <= y && y < height;
}

int count_visited_houses(const pair<unsigned short, unsigned char>& visited_houses) {
	int counter = 0;
	int f = visited_houses.first;
	int s = visited_houses.second;

	while (f > 0) {
		counter += f & 1;
		f >>= 1;
	}

	while (s > 0) {
		counter += s & 1;
		s >>= 1;
	}

	return counter;
}

bool is_visited(char idx, const pair<unsigned short, unsigned char>& visited_houses) {
	if (idx < 16) {
		return (visited_houses.first & (1 << idx)) > 0;
	}
	else {
		idx -= 16;
		return (visited_houses.second & (1 << idx)) > 0;
	}
}

bool can_go_ahead(int x, int y, const pair<unsigned short, unsigned char>& visited_houses) {
	int num_visited_houses = count_visited_houses(visited_houses);
	char c_idx = -1;

	if (x == church_x && y == church_y) {
		if (num_visited_houses < num_houses) {
			return true;
		}
		else {
			return false;
		}
	}

	if (index_grid[y][x] < 0) {
		return true;
	}
	
	c_idx = index_grid[y][x];
	return is_visited(c_idx, visited_houses);
}

void add_house(unsigned char house_idx, pair<unsigned short, unsigned char>& visited_houses) {
	if (house_idx < 16) {
		visited_houses.first |= (1 << house_idx);
	}
	else {
		house_idx -= 16;
		visited_houses.second |= (1 << house_idx);
	}
	return;
}

int dfs(pair<pair<unsigned short, unsigned char>, unsigned char> dp_state, int x, int y) {
	pair<unsigned short, unsigned char> c_visited_houses = dp_state.first;
	int num_visited_houses = count_visited_houses(c_visited_houses);
	unsigned char c_idx = index_grid[y][x];
	int num_paths = 0;

	dp_state = pair<pair<unsigned short, unsigned char>, unsigned char>(c_visited_houses, c_idx);
	if (dp.count(dp_state) > 0) {
		return dp[dp_state];
	}

	if (num_visited_houses >= num_houses) {
		if (x == church_x and y == church_y) {
			return 1;
		}
	}

	for (int i = 0; i < 4; i++) {
		int nx = x + dx[i];
		int ny = y + dy[i];
		char n_idx = -1;
		pair<unsigned short, unsigned char> n_visited_houses = c_visited_houses;

		while (is_inside(nx, ny) && can_go_ahead(nx, ny, n_visited_houses)) {
			nx += dx[i];
			ny += dy[i];
		}

		if (!is_inside(nx, ny)) {
			continue;
		}
		
		n_idx = index_grid[ny][nx];
		add_house(n_idx, n_visited_houses);
		num_paths += dfs(pair<pair<unsigned short, unsigned char>, unsigned char>(n_visited_houses, n_idx), nx, ny);
	}

	dp[dp_state] = num_paths;
	return num_paths;
}



int main(int argc, char** argv) {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif

	while (true) {
		vector<vector<char>> grid;
		pair<pair<unsigned short, unsigned char>, unsigned char> initial_state(pair<unsigned short, unsigned char>(0, 0), 0);

		cin >> width >> height;
		if (width == 0 && height == 0) {
			break;
		}
		
		index_grid.clear();
		for (int y = 0; y < height; y++) {
			vector<char> row(width, -1);

			index_grid.push_back(row);
			for (int x = 0; x < width; x++) {
				int cell = -1;

				cin >> cell;
				row[x] = cell;
			}
			grid.push_back(row);
		}
		
		num_houses = 0;
		church_x = -1;
		church_y = -1;
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				if (grid[y][x] == house) {
					index_grid[y][x] = num_houses;
					num_houses++;
				}
				else if (grid[y][x] == church) {
					church_x = x;
					church_y = y;
				}
			}
		}

		max_num_houses = min(max_num_houses_in_dp, int(num_houses));
		dp.clear();
		dp[initial_state] = 0;
		cout << dfs(initial_state, church_x, church_y) << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 1760
memory_kb: 72956
final_rank: 19

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <map>
#include <vector>

using namespace std;

const int house = 1;
const int church = 2;
const int dx[] = { 1, 0, -1, 0 };
const int dy[] = { 0, -1, 0, 1 };
const int max_num_house_in_dp = 23;
int width = -1;
int height = -1;
vector<vector<char>> index_grid;
int church_x = -1;
int church_y = -1;
unsigned char num_house = -1;
int max_num_house = -1;
map<pair<pair<unsigned short, unsigned char>, unsigned char>, int> dp;


inline bool is_inside(int x, int y) {
	return 0 <= x && x < width && 0 <= y && y < height;
}

int count_visited_houses(const pair<unsigned short, unsigned char>& cur_visited_houses) {
	int counter = 0;
	int f = cur_visited_houses.first;
	int s = cur_visited_houses.second;

	while (f > 0) {
		counter += f & 1;
		f >>= 1;
	}

	while (s > 0) {
		counter += s & 1;
		s >>= 1;
	}

	return counter;
}

bool is_visited(char idx, const pair<unsigned short, unsigned char>& cur_visited_houses) {
	if (idx < 16) {
		return (cur_visited_houses.first & (1 << idx)) > 0;
	}
	else {
		idx -= 16;
		return (cur_visited_houses.second & (1 << idx)) > 0;
	}
}

bool can_go_ahead(int x, int y, const pair<unsigned short, unsigned char>& cur_visited_houses) {
	int num_visited_houses = count_visited_houses(cur_visited_houses);
	char c_idx = -1;

	if (x == church_x && y == church_y) {
		if (num_visited_houses < num_house) {
			return true;
		}
		else {
			return false;
		}
	}

	if (index_grid[y][x] < 0) {
		return true;
	}
	
	c_idx = index_grid[y][x];
	return is_visited(c_idx, cur_visited_houses);
}

void add_house(unsigned char house_idx, pair<unsigned short, unsigned char>& visited_houses) {
	if (house_idx < 16) {
		visited_houses.first |= (1 << house_idx);
	}
	else {
		house_idx -= 16;
		visited_houses.second |= (1 << house_idx);
	}
	return;
}

int dfs(pair<pair<unsigned short, unsigned char>, unsigned char> dp_state, int x, int y) {
	pair<unsigned short, unsigned char> cur_visited_houses = dp_state.first;
	int num_visited_houses = count_visited_houses(cur_visited_houses);
	unsigned char c_idx = index_grid[y][x];
	int cur_num_paths = 0;

	dp_state = pair<pair<unsigned short, unsigned char>, unsigned char>(cur_visited_houses, c_idx);

	if (num_visited_houses >= num_house) {
		if (x == church_x and y == church_y) {
			return 1;
		}
	}

	if (num_visited_houses < max_num_house) {
		if (dp.count(dp_state) > 0) {
			return dp[dp_state];
		}
	}

	for (int i = 0; i < 4; i++) {
		int nx = x + dx[i];
		int ny = y + dy[i];
		char n_idx = -1;
		pair<unsigned short, unsigned char> n_visited_houses = cur_visited_houses;

		while (is_inside(nx, ny) && can_go_ahead(nx, ny, cur_visited_houses)) {
			nx += dx[i];
			ny += dy[i];
		}

		if (!is_inside(nx, ny)) {
			continue;
		}
		
		n_idx = index_grid[ny][nx];
		add_house(n_idx, n_visited_houses);
		cur_num_paths += dfs(pair<pair<unsigned short, unsigned char>, unsigned char>(n_visited_houses, n_idx), nx, ny);
	}

	if (num_visited_houses < max_num_house) {
		dp[dp_state] = cur_num_paths;
	}
	return cur_num_paths;
}



int main(int argc, char** argv) {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif

	while (true) {
		vector<vector<char>> grid;
		pair<pair<unsigned short, unsigned char>, unsigned char> initial_state(pair<unsigned short, unsigned char>(0, 0), 0);

		cin >> width >> height;
		if (width == 0 && height == 0) {
			break;
		}
		
		index_grid.clear();
		for (int y = 0; y < height; y++) {
			vector<char> row(width, -1);

			index_grid.push_back(row);
			for (int x = 0; x < width; x++) {
				int cell = -1;

				cin >> cell;
				row[x] = cell;
			}
			grid.push_back(row);
		}
		
		num_house = 0;
		church_x = -1;
		church_y = -1;

		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				if (grid[y][x] == house) {
					index_grid[y][x] = num_house;
					num_house++;
				}
				else if (grid[y][x] == church) {
					church_x = x;
					church_y = y;
				}
			}
		}

		max_num_house = min(max_num_house_in_dp, int(num_house));
		dp.clear();
		dp[initial_state] = 0;
		cout << dfs(initial_state, church_x, church_y) << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 1730
memory_kb: 73172
final_rank: 18

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <map>
#include <vector>

using namespace std;

const int house = 1;
const int church = 2;
const int dx[] = { 1, 0, -1, 0 };
const int dy[] = { 0, -1, 0, 1 };
const int max_num_house_in_dp = 23;
int width = -1;
int height = -1;
vector<vector<char>> index_grid;
int church_x = -1;
int church_y = -1;
unsigned char num_house = -1;
int max_num_house = -1;
map<pair<pair<unsigned short, unsigned char>, unsigned char>, int> dp;


bool is_inside(int x, int y) {
	return 0 <= x && x < width && 0 <= y && y < height;
}

int count_visited_houses(pair<unsigned short, unsigned char> cur_visited_houses) {
	int counter = 0;
	int f = cur_visited_houses.first;
	int s = cur_visited_houses.second;

	while (f > 0) {
		counter += f & 1;
		f >>= 1;
	}

	while (s > 0) {
		counter += s & 1;
		s >>= 1;
	}

	return counter;
}

bool is_visited(char idx, pair<unsigned short, unsigned char> cur_visited_houses) {
	if (idx < 16) {
		return (cur_visited_houses.first & (1 << idx)) > 0;
	}
	else {
		idx -= 16;
		return (cur_visited_houses.second & (1 << idx)) > 0;
	}
}

bool can_go_ahead(int x, int y, pair<unsigned short, unsigned char> cur_visited_houses) {
	int num_visited_houses = count_visited_houses(cur_visited_houses);
	char c_idx = -1;

	if (x == church_x && y == church_y) {
		if (num_visited_houses < num_house) {
			return true;
		}
		else {
			return false;
		}
	}

	if (index_grid[y][x] < 0) {
		return true;
	}
	
	c_idx = index_grid[y][x];
	return is_visited(c_idx, cur_visited_houses);
}

pair<unsigned short, unsigned char> add_house(unsigned char house_idx, pair<unsigned short, unsigned char> visited_houses) {
	if (house_idx < 16) {
		visited_houses.first |= (1 << house_idx);
	}
	else {
		house_idx -= 16;
		visited_houses.second |= (1 << house_idx);
	}
	return visited_houses;
}

int dfs(pair<pair<unsigned short, unsigned char>, unsigned char> dp_state, int x, int y) {
	pair<unsigned short, unsigned char> cur_visited_houses = dp_state.first;
	int num_visited_houses = count_visited_houses(cur_visited_houses);
	unsigned char c_idx = index_grid[y][x];
	int cur_num_paths = 0;

	dp_state = pair<pair<unsigned short, unsigned char>, unsigned char>(cur_visited_houses, c_idx);

	if (num_visited_houses >= num_house) {
		if (x == church_x and y == church_y) {
			return 1;
		}
	}

	if (num_visited_houses < max_num_house) {
		if (dp.count(dp_state) > 0) {
			return dp[dp_state];
		}
	}

	for (int i = 0; i < 4; i++) {
		int nx = x + dx[i];
		int ny = y + dy[i];
		char n_idx = -1;
		pair<unsigned short, unsigned char> n_visited_houses = cur_visited_houses;

		while (is_inside(nx, ny) && can_go_ahead(nx, ny, cur_visited_houses)) {
			nx += dx[i];
			ny += dy[i];
		}

		if (!is_inside(nx, ny)) {
			continue;
		}
		
		n_idx = index_grid[ny][nx];
		n_visited_houses = add_house(n_idx, n_visited_houses);
		cur_num_paths += dfs(pair<pair<unsigned short, unsigned char>, unsigned char>(n_visited_houses, n_idx), nx, ny);
	}

	if (num_visited_houses < max_num_house) {
		dp[dp_state] = cur_num_paths;
	}
	return cur_num_paths;
}



int main(int argc, char** argv) {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif

	while (true) {
		vector<vector<char>> grid;
		pair<pair<unsigned short, unsigned char>, unsigned char> initial_state(pair<unsigned short, unsigned char>(0, 0), 0);

		cin >> width >> height;
		if (width == 0 && height == 0) {
			break;
		}
		
		index_grid.clear();
		for (int y = 0; y < height; y++) {
			vector<char> row(width, -1);

			index_grid.push_back(row);
			for (int x = 0; x < width; x++) {
				int cell = -1;

				cin >> cell;
				row[x] = cell;
			}
			grid.push_back(row);
		}
		
		num_house = 0;
		church_x = -1;
		church_y = -1;

		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				if (grid[y][x] == house) {
					index_grid[y][x] = num_house;
					num_house++;
				}
				else if (grid[y][x] == church) {
					church_x = x;
					church_y = y;
				}
			}
		}

		max_num_house = min(max_num_house_in_dp, int(num_house));
		dp.clear();
		dp[initial_state] = 0;
		cout << dfs(initial_state, church_x, church_y) << endl;
	}

	return 0;
}
accuracy: 1
time_ms: 1770
memory_kb: 73304
final_rank: 20

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

int main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	int h,w; 
	while(cin >> w >> h,w){
	    vector<pair<int,int>> v;
    	int sx,sy;
    	for(int i=0;i<h;i++){
    		for(int j=0;j<w;j++){
    			int a; cin >> a;
    			if(a==2){
    				sx=i,sy=j;
    			}
    			else if(a==1){
    				v.push_back({i,j});
    			}
    		}
    	}
    	v.push_back({sx,sy});
    	int n=v.size();
    	vector<int> l(n,-1),r(n,-1),u(n,-1),d(n,-1);
    	for(int i=0;i<n;i++){
    		int ma,id;
    		ma=-1; id=-1;
    		for(int j=0;j<n;j++){
    			if(v[i].first==v[j].first and ma<v[j].second and v[j].second<v[i].second){
    				ma=v[j].second;
    				id=j;
    			}
    		}
    		l[i]=id;
    		ma=1e9; id=-1;
    		for(int j=0;j<n;j++){
    			if(v[i].first==v[j].first and ma>v[j].second and v[j].second>v[i].second){
    				ma=v[j].second;
    				id=j;
    			}
    		}
    		r[i]=id;
    		ma=-1; id=-1;
    		for(int j=0;j<n;j++){
    			if(v[i].second==v[j].second and v[j].first>ma and v[j].first<v[i].first){
    				ma=v[j].first;
    				id=j;
    			}
    		}
    		u[i]=id;
    		ma=1e9; id=-1;
    		for(int j=0;j<n;j++){
    			if(v[i].second==v[j].second and v[j].first<ma and v[j].first>v[i].first){
    				ma=v[j].first;
    				id=j;
    			}
    		}
    		d[i]=id;
    	}
    	int res=0;
    	auto dfs=[&](auto dfs,int bit,int cur)->void{
    		if(bit==0){
    			if(v[cur].first==v.back().first or v[cur].second==v.back().second)res++;
    			return;
    		}
    		int nx;
    		// left
    		nx=cur;
    		while(1){
    			nx=l[nx];
    			if(nx==-1)break;
    			else{
    				if((1<<nx)&bit){
    					dfs(dfs,bit-(1<<nx),nx);
    					break;
    				}
    			}
    		}
    		// right
    		nx=cur;
    		while(1){
    			nx=r[nx];
    			if(nx==-1)break;
    			else{
    				if((1<<nx)&bit){
    					dfs(dfs,bit-(1<<nx),nx);
    					break;
    				}
    			}
    		}
    		// up
    		nx=cur;
    		while(1){
    			nx=u[nx];
    			if(nx==-1)break;
    			else{
    				if((1<<nx)&bit){
    					dfs(dfs,bit-(1<<nx),nx);
    					break;
    				}
    			}
    		}
    		// down
    		nx=cur;
    		while(1){
    			nx=d[nx];
    			if(nx==-1)break;
    			else{
    				if((1<<nx)&bit){
    					dfs(dfs,bit-(1<<nx),nx);
    					break;
    				}
    			}
    		}
    	};
    	n--;
    	dfs(dfs,(1<<n)-1,n);
    	cout << res << endl;
	}
}
accuracy: 1
time_ms: 2610
memory_kb: 3132
final_rank: 1

code_snippet: #include <iostream>
#include <utility>
#include <tuple>
#include <vector>
#include <string>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <algorithm>
#include <functional>
#include <climits>
#include <numeric>
#include <queue>
#include <cmath>
#include <iomanip>
#include <array>
#include <string>
#include <stack>
#include <cassert>
#include <memory>
struct Coordinate {
	int x, y;
	Coordinate operator+(const Coordinate that) const {
		return Coordinate{ x + that.x, y + that.y };
	}
};

constexpr std::array<Coordinate, 4> direction{ Coordinate{1, 0}, Coordinate{-1, 0}, Coordinate{0, 1}, Coordinate{0, -1} };
int count_route(const Coordinate current, const int delivered, const std::vector<std::vector<int>>& state) {
	int count{ 0 };
	for (const auto dir : direction) {
		for (auto next = current + dir; 0 <= next.x && next.x < state.size() && 0 <= next.y && next.y < state[next.x].size(); next = next + dir) {
			if (state[next.x][next.y] == -1) {
				if (delivered == 0) {
					++count;
				}
			}
			else if (state[next.x][next.y] > 0) {
				if ((delivered & (1 << (state[next.x][next.y] - 1))) != 0) {
					count += count_route(next, delivered ^ (1 << (state[next.x][next.y] - 1)), state);
					break;
				}
			}
		}
	}
	return count;
}
int main() {
	int m, n; std::cin >> m >> n;
	while (m != 0 && n != 0) {
		std::vector<std::vector<int>> state(n, std::vector<int>(m));
		for (auto& line : state) for (auto& cell : line) std::cin >> cell;
		Coordinate start{ -1, -1 };
		int count{ 0 };
		for (auto i = 0; i < n; ++i) {
			for (auto j = 0; j < m; ++j) {
				if (state[i][j] == 2) {
					start = Coordinate{ i, j };
					state[i][j] = -1;
				}
				if (state[i][j] == 1) {
					state[i][j] = ++count;
				}
			}
		}
		std::cout << count_route(start, (1 << count) - 1, state) << '\n';
		std::cin >> m >> n;
	}
}
accuracy: 1
time_ms: 7780
memory_kb: 3152
final_rank: 16