#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<map>
#include<list>
#include<cctype>
#include<climits>
#include<bitset>
#include<stack>

using namespace std;

typedef long long ll;

const int dx[4] = { 1, 0, -1, 0 }, dy[4] = { 0, 1, 0, -1 };
const int MAX = 19;
int W, H, fld[10][10];
int P, sx, sy;
map<pair<pair<int, int>, int>, int> memo;

inline int CountBit(int s)
{
	int res = 0;
	for (int i = 0; i < P; i++) res += (s >> i) & 1;
	return res;
}

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

inline bool CanDown(int x, int y, int s, int noBits)
{
	if (x == sx && y == sy && noBits == P) return true;
	if (fld[y][x] == -1) return false;
	return ((s >> fld[y][x]) & 1) == 0;
}

int DFS(int x, int y, int s)
{
	int cnt = CountBit(s);
	if (x == sx && y == sy && cnt == P) return 1;
	pair<pair<int, int>, int> state = make_pair(make_pair(x, y), s);
	if (cnt < MAX)
	{
		map<pair<pair<int, int>, int>, int>::iterator itr = memo.find(state);
		if (itr != memo.end()) return itr->second;
	}
	int sum = 0;
	for (int i = 0; i < 4; i++)
	{
		int nx = x + dx[i], ny = y + dy[i];
		while (IsInside(nx, ny) && !CanDown(nx, ny, s, cnt))
			nx += dx[i], ny += dy[i];
		if (!IsInside(nx, ny)) continue;
		sum += DFS(nx, ny, s | (1 << fld[ny][nx]));
	}
	if (cnt < MAX && !(cnt >= 16 && sum == 0)) memo[state] = sum;
	return sum;
}

signed main()
{
	while (cin >> W >> H, W || H)
	{
		memo.clear();
		P = 0;
		for (int i = 0; i < H; i++)
		{
			for (int j = 0; j < W; j++)
			{
				cin >> fld[i][j];
				if (fld[i][j] == 0) fld[i][j] = -1;
				else if (fld[i][j] == 1) fld[i][j] = P++;
				else sx = j, sy = i, fld[i][j] = -1;
			}
		}
		printf("%d\n", DFS(sx, sy, 0));
	}
	return 0;
}