#include <iostream>
#include <cassert>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <utility>

using namespace std;

const int MAXN = 5;
const int MAXM = MAXN;
const int MAXH = MAXN;
const int MAXW = MAXN;
const int MAXK = 12;

typedef long long i64;

struct Pair {
	int x, y;
	bool operator<(const Pair &w) const {
		return (x < w.x) || ((x == w.x) && (y < w.y));
	}
	bool operator!=(const Pair &w) const {
		return (x != w.x) || (y != w.y);
	}
};

struct P {
	int n, c, i, vc;
	struct Q {
		int h, w;
		Pair v[10];
		bool operator==(const Q &x) const {
			return (h == x.h) && (w == x.w) && (v == x.v);
		}
	} q[4];
	bool operator<(const P& w) const {
		return vc > w.vc;
	}
} p[MAXK];
char s[MAXN][MAXM + 1];
int n, m, k;
i64 result;
int u[MAXN][MAXM];
int uu[MAXN];
i64 f[MAXK];
int q[1 << MAXM];
int h, nx[MAXK];

bool cmp(Pair *a, int ac, Pair *b, int bc) {
	if (ac != bc) return false;
	for (int i = 0; i < ac; ++i)
		if (a[i] != b[i]) return false;
	return true;
}

void print() {
	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < m; ++j)
			cout << (char)('A' - 1 + u[i][j]);
		cout << endl;
	}
	cout << endl;
}

void solve(int x, int y) {
	if (h == -1) {
		++result;
		return;
	}
	if (x == n) return;
	for (int i = h, pi = -1; i != -1; pi = i, i = nx[i]) {
		for (int j = 0; j < p[i].c; ++j) {
			bool f = true;
			Pair *v = p[i].q[j].v;
			for (int t = 0; t < p[i].vc; ++t) {
				int xx = x + v[t].x - v[0].x, yy = y + v[t].y - v[0].y;
				if ((xx >= n) || (xx < 0) || (yy >= m) || (yy < 0) || (uu[xx] & (1 << yy))) {
					f = false;
					break;
				}
			}
			if (!f) continue;
			++p[i].i;
			if (p[i].i == p[i].n) {
				if (pi != -1) nx[pi] = nx[i];
				else h = nx[i];
			}
			for (int t = 0; t < p[i].vc; ++t) {
				uu[x + v[t].x - v[0].x] |= 1 << (y + v[t].y - v[0].y);
				u[x + v[t].x - v[0].x][y + v[t].y - v[0].y] = i + 1;
			}
			int xx = x, yy;
			while (xx < n)
				if (q[uu[xx]] == m) ++xx;
				else break;
			if (xx < n) yy = q[uu[xx]];
			else yy = 0;
			solve(xx, yy);
			for (int t = 0; t < p[i].vc; ++t) {
				uu[x + v[t].x - v[0].x] ^= 1 << (y + v[t].y - v[0].y);
				u[x + v[t].x - v[0].x][y + v[t].y - v[0].y] = 0;
			}
			if (p[i].i == p[i].n) {
				if (pi != -1) nx[i] = nx[pi], nx[pi] = i;
				else h = i;
			}
			--p[i].i;
		}
	}
}

int main() {
//	freopen("G.in", "r", stdin);
//	freopen("G.out", "w", stdout);

	cin >> n >> m >> k;
	assert((1 <= n) && (n <= MAXN) && (1 <= m) && (m <= MAXM) && (1 <= k) && (k <= MAXK));
	int t = 0;
	for (int q = 0; q < k; ++q) {
		int h, w; cin >> h >> w;
		assert((1 <= h) && (h <= 5) && (1 <= w) && (w <= 5));
		Pair v[10];
		int vc = 0;
		for (int i = 0; i < h; ++i) {
			cin >> s[i];
			for (int j = 0; j < w; ++j) {
				if (s[i][j] != '.')
					v[vc].x = i, v[vc].y = j, ++vc;
			}
		}
		sort(v, v + vc);
		bool f = false;
		for (int i = 0; i < t; ++i) {
			if (cmp(v, vc, p[i].q[0].v, p[i].vc) ||
				cmp(v, vc, p[i].q[1].v, p[i].vc) ||
				cmp(v, vc, p[i].q[2].v, p[i].vc) ||
				cmp(v, vc, p[i].q[3].v, p[i].vc)) {
				++p[i].n;
				f = true;
				break;
			}
		}
		if (f) continue;
		p[t].vc = vc;
		for (int r = 0; r < 4; ++r) {
			bool f = true;
			for (int y = 0; y < p[t].c; ++y) {
				if (cmp(v, vc, p[t].q[y].v, p[t].vc)) {
					f = false;
					break;
				}
			}
			if (f) {
				p[t].q[p[t].c].h = h; p[t].q[p[t].c].w = w;
				for (int i = 0; i < vc; ++i)
					p[t].q[p[t].c].v[i] = v[i];
				++p[t].c;
			}
			for (int i = 0; i < vc; ++i) {
				swap(v[i].x, v[i].y);
				v[i].x = w - 1 - v[i].x;
			}
			w ^= h; h ^= w; w ^= h;
			sort(v, v + vc);
		}
		++p[t++].n;
	}
	k = t;

	for (int i = 0; i < 1 << m; ++i) {
		::q[i] = m;
		for (int j = 0; j < m; ++j)
			if (!(i & (1 << j))) {
				::q[i] = j;
				break;
			}
	}
	
	sort(p, p + k);
	
	for (int i = 0; i < k; ++i) nx[i] = i + 1;
	nx[k - 1] = -1;
	h = 0;
	
	solve(0, 0);
	f[0] = 1;
	for (int i = 1; i < 20; ++i) f[i] = f[i - 1] * i;
	for (int i = 0; i < k; ++i) {
		result *= f[p[i].n];
	}
	if (result <= 10000)
		cout << result << endl;
	else
		cout << "TOO MANY" << endl;
	return 0;
}
