#include <iostream>
#include <vector>
#include <string>
#include <cstdio>
#include <set>

using namespace std;

int n,m,k,ans;
bool ok[101];

struct Pol
{
	int h,w,l;
	char a[11][11];
	Pol():l(0){}
	Pol(int x,int y)
	{
		h = x, w = x;
		for (int i = 0; i < h; ++i)
			for (int j = 0; j < w; ++j)
				a[i][j] ='.';
	}
	Pol operator=(Pol x)
	{
		h = x.h, w = x.w;
		for (int i = 0; i < h; ++i)
			for (int j = 0; j < w; ++j)
				a[i][j] = x.a[i][j];
		return *this;
	}
	void rotate90()
	{
		char b[11][11];
		for (int i = 0; i < h; ++i)
			for (int j = 0; j < w; ++j)
				b[i][j] = a[i][j];
		for (int i = 0; i < h; ++i)
			for (int j = 0; j < w; ++j)
				a[i][j] = b[j][w-1-i];
	}
	void read()
	{
		scanf("%d%d\n", &h, &w);
		for (int i = 0; i < h; ++i)
		{
			for (int j = 0; j < w; ++j)
				scanf("%c",&a[i][j]);
			scanf("\n");
		}
	}
	void print()
	{
		cout << h << ' ' << w << endl;
		for (int i = 0; i < h; ++i)
		{
			for (int j = 0; j < w; ++j)
				printf("%c", a[i][j]);
			printf("\n");
		}		
		cout << endl;
	}
} a[100][4];

vector <Pol> s;

bool operator==(const Pol& a,const Pol& b)
{
	if (a.h!=b.h || a.w!=b.w) return 0;
	for (int i = 0; i < a.h; ++i)
		for (int j = 0; j < a.w; ++j)
			if (a.a[i][j]!=b.a[i][j]) return 0;
	return 1;
}

bool operator<(const Pol& a,const Pol& b)
{
	if (a.h<b.h || a.w<b.w) return 0;
	for (int i = 0; i < a.h; ++i)
		for (int j = 0; j < a.w; ++j)
			if (a.a[i][j]!=b.a[i][j]) return 0;
	return 1;
}

bool check(const Pol& a,int &x,int &y)
{
	for (int i = 0; i < a.h; ++i)
		for (int j = 0; j < a.w; ++j)
			if (a.a[i][j]=='.') 
			{
				x = i;
				y = j;
				return 0;
			}
	return 1;
}

bool tryPut(int x,int y,Pol& a,Pol& r)
{
	for (int i = 0; i < a.h; ++i)
		for (int j = 0; j < a.w; ++j)
		{
			int sx = x+i, sy = y+j;
			if (sx>=r.h) return 0;
			if (sy>=r.w) return 0;
			if (a.a[i][j]!='.'&&r.a[sx][sy]!='.') return 0;
		}
	for (int i = 0; i < a.h; ++i)
		for (int j = 0; j < a.w; ++j)
			if (a.a[i][j]!='.') r.a[x+i][y+j] = a.a[i][j];
	return 1;
}

void Remove(int x,int y,Pol& a,Pol& r)
{
	for (int i = 0; i < a.h; ++i)
		for (int j = 0; j < a.w; ++j)
			if (r.a[x+i][y+j]==a.a[i][j]) r.a[x+i][y+j] = '.';
}

void rec(Pol r)
{
//	cout << ans << endl;
//	r.print();	
	int x1,y1;
	if (check(r,x1,y1))
	{
		if (find(s.begin(),s.end(),r)==s.end()) ++ans, s.push_back(r);
	} else
	{
		bool tr[101];
		memset(tr,0,sizeof(tr));
		for (int x = 0; x < r.h; ++x)
			for (int y = 0; y < r.w; ++y)
			{
				for (int i = 0; i < k; ++i)
					if (!ok[i]&&!tr[i])
						for (int j = 0; j < a[i][0].l; ++j)
							if (tryPut(x,y,a[i][j],r)) ok[i] = 1, tr[i] = 1, rec(r), ok[i] = 0, Remove(x,y,a[i][j],r);
			}
	}
}

int main()
{
	freopen("G.in","r",stdin);
	freopen("G.out","w",stdout);
	scanf("%d%d\n",&n,&m);
	scanf("%d\n", &k);
	for (int q = 0; q < k; ++q)
	{
		a[q][0].read();
		a[q][0].l = 1;
		Pol t = a[q][0];		
		for (int j = 0; j < 3; ++j)
		{			
			t.rotate90();
			bool e = 1;
			for (int p = a[q][0].l-1; p >= 0; --p)
				if (t==a[q][p]) e = 0;
			if (e) a[q][a[q][0].l++] = t;
		}
	}
/*		for (int j = 0; j < a[i][0].l; ++j)
			a[i][j].print();*/
	
	Pol r(n,m);
	ans = 0;
	memset(ok,0,sizeof(ok));
	rec(r);
	if (ans>10000) cout << "TOO MANY" << endl; else cout << ans << endl;
	return 0;
}
