#include <bits/stdc++.h>
using namespace std;

template<int MOD>
class mod_int {
	unsigned x;
public:
	mod_int() : x(0) { }
	mod_int(int sig) { int sigt = sig % MOD; if (sigt < 0) sigt += MOD; x = sigt; }
	mod_int(long long sig) { int sigt = sig % MOD; if (sigt < 0) sigt += MOD; x = sigt; }
	int get() const { return (int)x; }

	mod_int &operator+=(mod_int that) { if ((x += that.x) >= MOD) x -= MOD; return *this; }
	mod_int &operator-=(mod_int that) { if ((x += MOD - that.x) >= MOD) x -= MOD; return *this; }
	mod_int &operator*=(mod_int that) { x = (unsigned long long)x * that.x % MOD; return *this; }
	mod_int &operator/=(mod_int that) { return *this *= that.inverse(); }

	mod_int operator+(mod_int that) const { return mod_int(*this) += that; }
	mod_int operator-(mod_int that) const { return mod_int(*this) -= that; }
	mod_int operator*(mod_int that) const { return mod_int(*this) *= that; }
	mod_int operator/(mod_int that) const { return mod_int(*this) /= that; }

	bool operator==(const mod_int& that) const { return x == that.x; }

	mod_int inverse() const {
		long long a = x, b = MOD, u = 1, v = 0;
		while (b) {
			long long t = a / b;
			a -= t * b; swap(a, b);
			u -= t * v; swap(u, v);
		}
		return mod_int(u);
	}
};

template<int MOD>
istream& operator >> (istream& is, mod_int<MOD>& val) {
	long long x;
	is >> x; val = x;
	return is;
}

template<int MOD>
ostream& operator << (ostream& os, const mod_int<MOD>& val) {
	os << val.get();
	return os;
}

const int mod = 1e9 + 7;
using mint = mod_int<mod>;

const int var = 26;

int trans(char c) {
	return c - 'a';
}

class aho_corasick {
	struct ac_node {
		int fail;
		int next[var];
		vector<int> ok;
		ac_node() : fail(-1) {
			for (int i = 0; i < var; i++) next[i] = -1;
		}
	};
	vector<int> unite(const vector<int>& a, const vector<int>& b) {
		vector<int> res;
		set_union(a.begin(), a.end(), b.begin(), b.end(), back_inserter(res));
		return move(res);
	}
	int n;
	vector<ac_node> dat;
public:
	aho_corasick(const vector<string>& Ts) : n(Ts.size()), dat(1) {
		int now;
		dat[0].fail = 0;
		for (int i = 0; i < n; i++) {
			auto &T = Ts[i];
			now = 0;
			for (auto c : T) {
				if (dat[now].next[trans(c)] == -1) {
					dat[now].next[trans(c)] = dat.size();
					dat.emplace_back();
				}
				now = dat[now].next[trans(c)];
			}
			dat[now].ok.push_back(i);
		}
		queue<int> q;
		for (int i = 0; i < var; i++) {
			if (dat[0].next[i] == -1) {
				dat[0].next[i] = 0;
			}
			else {
				dat[dat[0].next[i]].fail = 0;
				q.push(dat[0].next[i]);
			}
		}
		while (!q.empty()) {
			now = q.front(); q.pop();
			for (int i = 0; i < var; i++) {
				if (dat[now].next[i] != -1) {
					int nx = dat[now].fail;
					while (dat[nx].next[i] == -1) {
						nx = dat[nx].fail;
					}
					int nex = dat[now].next[i];
					dat[nex].fail = dat[nx].next[i];
					dat[nex].ok = unite(dat[nex].ok, dat[dat[nx].next[i]].ok);
					q.push(nex);
				}
			}
		}
	}
	int size() const {
		return dat.size();
	}
	bool is_ok(int id) const {
		return !dat[id].ok.empty();
	}
	int ok_cnt(int id) const {
		return dat[id].ok.size();
	}
	int get_next(int id, char c) const {
		while (dat[id].next[trans(c)] == -1) id = dat[id].fail;
		return dat[id].next[trans(c)];
	}
	vector<int> count(const string& S) const {
		vector<int> res(n);
		int now = 0;
		for (auto c : S) {
			now = get_next(now, c);
			for (auto k : dat[now].ok) res[k]++;
		}
		return res;
	}
	vector<vector<int>> all_count(const string& S) const {
		int N = S.size();
		vector<vector<int>> res(N);
		int now = 0;
		for (int i = 0; i < N; i++) {
			now = get_next(now, S[i]);
			res[i] = dat[now].ok;
		}
		return res;
	}
};

unordered_map<int, mint> dp[501][500][2];

int main()
{
	int N, M, K;
	while (cin >> N >> M >> K, N | M | K) {
		vector<string> f(N), t(N);
		vector<string> word;
		map<string, int> dic;
		vector<vector<int>> g(500);
		for (int i = 0; i < N; i++) {
			cin >> f[i] >> t[i];
			if (!dic.count(f[i])) dic[f[i]] = word.size(), word.push_back(f[i]);
			if (!dic.count(t[i])) dic[t[i]] = word.size(), word.push_back(t[i]);
			int fid = dic[f[i]], tid = dic[t[i]];
			g[fid].push_back(tid);
		}
		N = word.size();
		g.resize(N);
		vector<string> ss(K);
		for (int i = 0; i < K; i++) {
			cin >> ss[i];
		}
		aho_corasick ac(ss);
		int sz = ac.size();
		vector<vector<pair<int, int>>> nex(N, vector<pair<int, int>>(sz));
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < sz; j++) {
				int cnt = 0;
				int it = j;
				for (auto c : word[i]) {
					it = ac.get_next(it, c);
					cnt += ac.ok_cnt(it);
				}
				nex[i][j] = make_pair(cnt, it);
			}
		}
		for (int i = 0; i <= M; i++) {
			for (int j = 0; j < N; j++) {
				for (int k = 0; k < 2; k++) {
					dp[i][j][k].clear();
				}
			}
		}
		for (int i = 0; i < N; i++) {
			auto &p = nex[i][0];
			int pos = word[i].size();
			if (pos <= M && p.first < 2) dp[pos][i][p.first][p.second] += 1;
		}
		for (int i = 1; i < M; i++) {
			for (int j = 0; j < N; j++) {
				for (auto to : g[j]) {
					for (int b = 0; b < 2; b++) {
						for (auto kv : dp[i][j][b]) {
							int k;
							mint val;
							tie(k, val) = kv;
							auto &p = nex[to][k];
							int pos = i + word[to].size(), c = b + p.first;
							if (pos <= M && c < 2) {
								dp[pos][to][c][p.second] += val;
							}
						}
					}
				}
			}
		}
		mint res = 0;
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < sz; j++) {
				res += dp[M][i][1][j];
			}
		}
		cout << res << endl;
	}
	return 0;
}



Measured memory_bytes: 167296