#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <map>
#include <utility>
#include <ctime>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <cstring>
#include <numeric>
#include <cassert>
using namespace std;
static const double EPS = 1e-10;
typedef long long ll;
#define rep(i,n) for(int i=0;i<n;i++)
#define rev(i,n) for(int i=n-1;i>=0;i--)
#define all(a) a.begin(),a.end()
#define mp(a,b,c) make_pair(make_pair(a,b),c)
#define pb(a) push_back(a)
#define SS stringstream
#define DBG1(a) rep(_X,sz(a)){printf("%d ",a[_X]);}puts("");
#define DBG2(a) rep(_X,sz(a)){rep(_Y,sz(a[_X]))printf("%d ",a[_X][_Y]);puts("");}
#define bitcount(b) __builtin_popcount(b)
#define EACH(i,c) for(typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)

#define delete(a,n) a.erase(remove(all(a),n),a.end())
template<typename T, typename S> vector<T>& operator<<(vector<T>& a, S b) { a.push_back(b); return a; }
template<typename T> void operator>>(vector<T>& a, int b) {while(b--)if(!a.empty())a.pop_back();}
bool isprime(int n){ if(n<2)return false;  for(int i=2;i*i<=n;i++)if(n%i==0)return false;  return true;} 
ll b_pow(ll x,ll n){return n ? b_pow(x*x,n/2)*(n%2?x:1) : 1ll;}
string itos(int n){stringstream ss;ss << n;return ss.str();}


int cur = 0;

struct T{
	short id,flag;
	T *next[26];
	T(){ id = flag=0;for(int i = 0 ; i < 26 ; i++) next[i] = NULL; }
};

T *rope[1000];
int bad[1000];

string ttt[1000];

int n,m,K;
void add(T *root,string s){
	//cout << "[" << s << "]" << endl;
	for(int i = 0 ; i < s.size() ; i++){
		if( root->next[s[i]-'a'] ){
			root = root->next[s[i]-'a'];
		}else{
			root = root->next[s[i]-'a'] = new T();
			rope[cur] = root;
			root->id = cur++;
			for(int j = 0 ; j < K ; j++){
				if( ttt[j].size() <= (i+1) ){
					if( s.substr(i+1-ttt[j].size(),ttt[j].size()) == ttt[j] ){
						root->flag++;
					}
				}
			}
		}
	}
}

bool done[1000];

int tmp;
int exists(T *root,string s){
	for(int i = 0 ; i < s.size() ; i++){
		if( root->next[s[i]-'a'] ){
			root = root->next[s[i]-'a'];
			tmp += root->flag;
		}else{
			return -1;
		}
	}
	return root->id;
}
void failed_generate(T *root,string c,T *src){
	if( done[root->id] ) return;
	else done[root->id] = true;
	//cout << root->id << ": " << c << " " << root->flag << endl;
	for(int i = 0 ; i < 26 ; i++){
		if( root->next[i] ){
			failed_generate(root->next[i],c+(char)(i+'a'),src);
		}else{
			
			string w = c + (char)(i+'a');
			int idx = 0;
			for(int j = 0 ; j < w.size() ; j++){
				int r = exists(src,w.substr(j));
				if( r != -1 ){
					idx = r;
					break;
				}
			}
			root->next[i] = rope[idx];
		}
	}
}


map<string,int> dic;
string ln[500];

vector<int> connect[500];

int mem[610][500];
int mem2[610][500];

map<pair<pair<int,int>,int>,int>  dp[21];

/*
map< pair< pair<int,int> , pair<int,int> >, int > memo;
int dfs(int pos,int word,int info,int ok){
	if( ok > 1 ) return 0;
	pair< pair<int,int>, pair<int,int> > key = make_pair( make_pair(pos,word) , make_pair(info,ok) );
	//cout << ln[pos] << " " << word << " " << info << " " << ok << endl;
	if( memo.count(key) ) return memo[key];
	if( word < 0 ) return 0;
	if( word == 0 ) return ok == 1;
	int ans = 0;
	for(int i = 0 ; i < connect[pos].size() ; i++){
		ans += dfs(connect[pos][i],word - ln[connect[pos][i]].size() , mem[info][connect[pos][i]],ok+mem2[info][connect[pos][i]]);
		if( ans >= 1000000007 ) ans -= 1000000007;
	}
	return memo[key] = ans;
}
*/
int main(){
	while(cin >> n >> m >> K && n){
		dic.clear();
		
		for(int i = 0 ; i < 1000 ; i++) done[i] = 0;
		for(int i = 0 ; i < 500 ; i++) ln[i] = "", connect[i].clear();
		for(int i = 0 ; i < 1000 ; i++) rope[i] = NULL;
		for(int i = 0 ; i < 1000 ; i++)bad[i] = 0;
		for(int i = 0 ; i < n ; i++){
			string a,b;
			cin >> a >> b;
			if( dic.count(a) == 0 ){ int k = dic.size(); dic[a] = k; ln[k] = a;}
			if( dic.count(b) == 0 ){ int k = dic.size(); dic[b] = k; ln[k] = b;}
			connect[dic[a]].push_back(dic[b]);
			
		}
		T *root = new T();
		rope[0] = root;
		cur = 1;
		for(int i = 0 ; i < K ; i++){
			string l;
			cin >> l;
			ttt[i] = l;
			//cout << l << endl;
		}
		for(int i = 0 ; i < K ; i++){
			add(root,ttt[i]);
		}
		
		failed_generate(root,"",root);
		
		for(int i = 0 ; i < cur ; i++){
			for(int k = 0 ; k < dic.size() ; k++){
				tmp = 0;
				mem[i][k] = exists(rope[i],ln[k]);
				mem2[i][k] = tmp;
				//cout << i << " " << ln[k] << " " << tmp << " " << mem[i][k] << " " << mem2[i][k] << endl;
			}
		}
		int ans = 0;
		for(int i = 0 ; i < 21 ; i++) dp[i].clear();
		for(int i = 0 ; i < dic.size() ; i++){
			if( mem2[0][i] < 2 ) dp[ln[i].size()][mp(i,mem[0][i],mem2[0][i])] = 1;
		}
	
		for(int i = 0 ; i < m ; i++){
			EACH(it,dp[i%21]){
				int j = it->first.first.first;
				int k = it->first.first.second;
				int f = it->first.second;
				int v = it->second;
				for(int l = 0 ; l < connect[j].size() ; l++){
					if( i + ln[connect[j][l]].size() <= m && f+mem2[k][connect[j][l]] < 2 ){
						dp[(i+ln[connect[j][l]].size())%21][mp(connect[j][l],mem[k][connect[j][l]],f+mem2[k][connect[j][l]])] += v;
						if( dp[(i+ln[connect[j][l]].size())%21][mp(connect[j][l],mem[k][connect[j][l]],f+mem2[k][connect[j][l]])] >= 1000000007 ){
							dp[(i+ln[connect[j][l]].size())%21][mp(connect[j][l],mem[k][connect[j][l]],f+mem2[k][connect[j][l]])] -= 1000000007;
						}
					}
				}
			}
			dp[i%21].clear();
		}
		EACH(it,dp[m%21]){
			int j = it->first.first.first;
			int k = it->first.first.second;
			int f = it->first.second;
			int v = it->second;
			if( f == 1 ) ans += v;
			if( ans >= 1000000007 ) ans -= 1000000007;
			
		}
		cout << ans << endl;
		
	}
	
}

Measured memory_bytes: 6748