#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <unordered_map>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );

template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000007;


struct AhoCorasick{
	static const int MAXCHAR = 'z'+1;
	struct State{
		int next[MAXCHAR], failure;
		vi accepts;
		State():failure(0){memset(next, 0, sizeof(next));}
	};
	vector<State> states;
	int pats;
	
	AhoCorasick(vector<string> patterns):states(1),pats(patterns.size()){
		REP(i, pats){	// make trie
			int p = 0;
			FOR(c, patterns[i]){
				if(states[p].next[*c] <= 0){
					states[p].next[*c] = states.size();
					states.emplace_back();
				}
				p = states[p].next[*c];
			}
			states[p].accepts.push_back(i);
		}
		
		queue<int> q;	// make failure link
		q.push(0);
		while(!q.empty()){
			const int p = q.front();q.pop();
			for(int i='a';i<='z';i++){
				const int dst = states[p].next[i];
				if(!dst){
					// 大量に呼び出す時はnextを全部埋めとくといい
					int q=p;
					while(q && !states[q].next[i]) q = states[q].failure;
					states[p].next[i] = states[q].next[i];
				}else{
					q.push(dst);
					int f = states[p].failure;
					while(f && states[f].next[i] <= 0) f = states[f].failure;
					if(p){
						states[dst].failure = states[f].next[i];
						states[dst].accepts.insert(states[dst].accepts.end(), ALL(states[states[f].next[i]].accepts));
					}
				}
			}
		}
	}
	
	int go_next(int p, const int &c){
		// nextが埋まってるならここはいらない
		// while(p && !states[p].next[c]) p = states[p].failure;
		return states[p].next[c];
	}
	pair<int, int> apply(const string &s, int p=0){
		int res=0;
		REP(i, s.size()){
			p = go_next(p, s[i]);
			res += states[p].accepts.size();
		}
		return make_pair(p, res);
	}
};


int N, M, K;


inline void add(int &a, int b){
	a += b;
	if(a >= MOD) a-= MOD;
}

unordered_map<int, int> dp[32][2][500];
main(){
	ios::sync_with_stdio(false);
	while(cin >> N >> M >> K, N){
		map<string, int> StI;
		vector<string> strs(1, "");
		vector<vi> g(2*N+2);
		REP(i, N){
			string from, to;
			int u, v;
			cin >> from >> to;
			auto it = StI.find(from);
			if(it == StI.end()){
				u = StI[from] = strs.size();
				strs.push_back(from);
			}else u = it->second;
			it = StI.find(to);
			if(it == StI.end()){
				v = StI[to] = strs.size();
				strs.push_back(to);
			}else v = it->second;
			g[u].push_back(v);
		}
		REP(i, (int)strs.size() - 1) g[0].push_back(i+1);
		vector<string> pat(K);
		REP(i, K) cin >> pat[i];
		AhoCorasick ahc(pat);
		dp[0][0][0][0] = 1;
		REP(i, M)REP(f, 2)REP(u, strs.size()){
			FOR(p_, dp[i&31][f][u]){
				const ll t = p_->second;
				const int p = p_->first;
				FOR(v, g[u]){
					const string &s = strs[*v];
					if(i+s.size() > M) continue;
					auto res = ahc.apply(s, p);
					if(f + res.second > 1) continue;
					add(dp[(i+s.size())&31][f + res.second][*v][res.first], t);
				}
			}
			dp[i&31][f][u].clear();
		}
		ll ans = 0;
		REP(u, strs.size()){
			FOR(p_, dp[M&31][1][u])ans += p_->second;
			dp[M&31][0][u].clear();
			dp[M&31][1][u].clear();
		}
		cout << ans % MOD << endl;
	}
	return 0;
}

Measured memory_bytes: 10804