#include <bits/stdc++.h>

class Solve {
private:
	using vi = std::vector<int>;
	using vvi = std::vector<vi>;
	using vvvi = std::vector<vvi>;
	using vvvvi = std::vector<vvvi>;

	using vb = std::vector<bool>;
	using vvb = std::vector<vb>;
	using vvvb = std::vector<vvb>;

	int n, m, r;
	vvvi R;

	vi inputVector(int size)
	{
		std::vector<int> ret(size);
		for (auto& e: ret)
		{
			scanf("%d", &e);
			e--;
		}
		return std::move(ret);
	}
	void inputR()
	{
		R.resize(30);
		for (int i{}; i < r; i++)
		{
			int k;
			scanf("%d", &k);
			std::vector<int> tmp(k);
			for (auto& e: tmp)
			{
				scanf("%d", &e);
				e--;
			}
			int y;
			scanf("%d", &y);
			y--;
			R[y].push_back(tmp);
		}
	}

	void execute(vi& arr, vvvi& charTable, vvvb& canMake)
	{
		int size{(int)arr.size()};
		for (int i{}; i < size; i++)
		{
			charTable[i][arr[i]].push_back((i + 1) % size);
			canMake[i][(i + 1) % size][arr[i]] = true;
		}
		for (int width{2}; width <= size; width++)
			for (int left{}; left < size; left++)
				for (int char_i{}; char_i < 30; char_i++)
					for (auto& e: R[char_i])
						if (e.size() <= width && stringFound(e, 0, left, width, charTable, canMake))
						{
							charTable[left][char_i].push_back((left + width) % size);
							canMake[left][(left + width) % size][char_i] = true;
							break;
						}
	}

	bool stringFound(vi& arr, int arr_i, int left, int width, vvvi& charTable, vvvb& canMake)
	{
		int char_i{arr[arr_i]}, size{(int)charTable.size()};
		if (arr_i + 1 == (int)arr.size())
			return canMake[left][(left + width) % size][char_i];
		for (auto& e: charTable[left][char_i])
		{
			int next_width{e};
			if (e <= left) next_width += size;
			next_width -= left;
			if ((int)arr.size() - (arr_i + 1) > width - next_width) break;
			if (stringFound(arr, arr_i + 1, e, width - next_width, charTable, canMake))
				return true;
		}
		return false;
	}

public:
	bool is_last_query{};
	Solve()
	{
		scanf("%d%d%d", &n, &m, &r);
		if (n == 0)
		{
			is_last_query = true;
			return;
		}
		vi A(inputVector(n)), B(inputVector(m));
		inputR();
		vvvb canMakeA(n, vvb(n, vb(30))), canMakeB(m, vvb(m, vb(30)));
		vvvi charTableA(n, vvi(30)), charTableB(m, vvi(30));
		execute(A, charTableA, canMakeA);
		execute(B, charTableB, canMakeB);
		vvvvi dp(n, vvvi(n, vvi(m, vi(m))));
		for (int la{}; la < n; la++)
			for (int lb{}; lb < m; lb++)
				for (int ra{}; ra < n; ra++)
					for (int rb{}; rb < m; rb++)
						for (int char_i{}; char_i < 30; char_i++)
							if (canMakeA[la][ra][char_i] && canMakeB[lb][rb][char_i])
								dp[la][ra][lb][rb] = 1;
		for (int wa{2}; wa <= n; wa++)
			for (int wb{2}; wb <= m; wb++)
				for (int la{}; la < n; la++)
				{
					int ra{(la + wa) % n};
					for (int lb{}; lb < m; lb++)
					{
						int rb{(lb + wb) % m};
						for (int ma{(la + 1) % n}; ma != ra; ma = (ma + 1) % n)
							for (int mb{(lb + 1) % m}; mb != rb; mb = (mb + 1) % m)
								if (dp[la][ma][lb][mb] > 0 && dp[ma][ra][mb][rb] > 0)
									dp[la][ra][lb][rb] = std::max(dp[la][ra][lb][rb], dp[la][ma][lb][mb] + dp[ma][ra][mb][rb]);
					}
				}
		int max{};

		for (int la{}; la < n; la++)
			for (int lb{}; lb < m; lb++)
				max = std::max(max, dp[la][la][lb][lb]);
		if (max == 0) puts("-1");
		else printf("%d\n", max);
	}
};

int main()
{
	while (!Solve().is_last_query);

	return 0;
}


Measured memory_bytes: 5452