import std.stdio;
import std.c.stdio;
import std.range;
import std.array;
import std.functional;
import std.algorithm;
import std.conv;
import std.container;
import std.math;
import std.numeric;
import std.string;
import std.c.string;
import std.regex;
import std.typecons;

const M = 10;
alias int[M][M] F;

struct P {
    int y, x;
}

void main() {
    int m, n;
    while (scanf("%d %d\n", &m, &n), m || n) {
        F f;
        int sy, sx;
        int[M][M] id; memset(cast(void*)id, -1, id.sizeof);
        int vCount = 1;
        foreach (i; 0 .. n) {
            foreach (j; 0 .. m) {
                scanf("%d", &f[i][j]);
                if (f[i][j] == 1) {
                    id[i][j] = vCount++;
                }
                if (f[i][j] == 2) {
                    sy = i;
                    sx = j;
                    id[i][j] = 0;
                }
            }
        }
        P[] pos = new P[vCount];
        foreach (i; 0 .. n) {
            foreach (j; 0 .. m) {
                if (id[i][j] >= 0) {
                    pos[id[i][j]] = P(i, j);
                }
            }
        }
        F cur = f;
        int[] next(int v) {
            int[] ret;
            static const dy = [0, 1, 0, -1],
                         dx = [1, 0, -1, 0];
            int sy = pos[v].y, sx = pos[v].x;
            foreach (i; 0 .. 4) {
                int y = sy, x = sx;
                while (true) {
                    y += dy[i];
                    x += dx[i];
                    if (y < 0 || y >= n) break;
                    if (x < 0 || x >= m) break;
                    //if (cur[y][x] == 3) break;
                    //if (cur[y][x] == 1 || cur[y][x] == 2) {
                    if (cur[y][x] == 2) {
                        ret ~= id[y][x];
                    }
                    if (cur[y][x] == 1) {
                        ret ~= id[y][x];
                        break;
                    }
                }
            }
            return ret;
        }
        int[int][24] cache;
        int dfs(int v, int used) {
            if (v == 0 && (used & 1)) {
                foreach (i; 1 .. vCount) {
                    if (!(used & (1 << i))) return 0;
                }
                return 1;
            }
            if (used in cache[v]) return cache[v][used];
            int y = pos[v].y, x = pos[v].x;
            int ans = 0;
            //writeln(pos[v], next(v).map!((i) => pos[i]));
            foreach (i; next(v)) {
                if (used & (1 << i)) continue;
                int ny = pos[i].y,
                    nx = pos[i].x;
                assert(cur[ny][nx] == 1 || cur[ny][nx] == 2);
                if (cur[ny][nx] == 1) {
                    cur[ny][nx] = 3;
                    ans += dfs(i, used | (1 << i));
                    cur[ny][nx] = 1;
                } else {
                    ans += dfs(i, used | (1 << i));
                }
            }
            return cache[v][used] = ans;
        }
        dfs(0, 0).writeln;
    }
}