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

#define rep(i,n) for(int i=0;i<(n);i++)
#define pb push_back
#define eb emplace_back
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second
typedef vector<int>vint;
typedef pair<int,int>pint;
typedef vector<pint>vpint;

template<typename A,typename B>inline void chmin(A &a,B b){if(a>b)a=b;}
template<typename A,typename B>inline void chmax(A &a,B b){if(a<b)a=b;}

template<class A,class B>
ostream& operator<<(ostream& ost,const pair<A,B>&p){
	ost<<"{"<<p.first<<","<<p.second<<"}";
	return ost;
}

template<class T>
ostream& operator<<(ostream& ost,const vector<T>&v){
	ost<<"{";
	for(int i=0;i<v.size();i++){
		if(i)ost<<",";
		ost<<v[i];
	}
	ost<<"}";
	return ost;
}


/*
symbol : !"#$%&'()*+,-./
digit : 0~9
symbol2 : :;<=>?@
upper : A~Z
symbol3 : [\]^_`
lower : a~z	
synbol4 : {|}~

don't forget!!!!  :  build  
*/
struct AhoCorasick{
	//  c \in [OFF,OFF+LEN)
	static const int OFF=(int)('a');
	static const int SUP=(int)('z');
	static const int LEN=SUP-OFF+1;
	
	struct Node{
		int nex[LEN];
		int failink;
		vector<int>suflist;
		Node():failink(0){memset(nex,-1,sizeof(nex));}
	};
	vector<Node>nds;

	AhoCorasick():nds(1){}

	int process(int k,int c){
		c-=OFF;
		while(nds[k].nex[c]==-1)k=nds[k].failink;
		return nds[k].nex[c];
	}

	void add(const string &s,int id){
		int k=0;
		for(auto c:s){
			c-=OFF;
			if(nds[k].nex[c]==-1){
				nds[k].nex[c]=nds.size();
				nds.emplace_back();
			}
			k=nds[k].nex[c];
		}
		nds[k].suflist.push_back(id);
	}

	void build(){
		queue<int>que;
		for(int i=0;i<LEN;i++){
			if(nds[0].nex[i]==-1)nds[0].nex[i]=0;
			else que.push(nds[0].nex[i]);
		}
		while(que.size()){
			int k=que.front();
			que.pop();
			for(int i=0;i<LEN;i++){
				if(nds[k].nex[i]==-1)continue;
				int nx=nds[k].nex[i];
				nds[nx].failink=process(nds[k].failink,i+OFF);

				vector<int>&curlist=nds[nds[nx].failink].suflist;
				vector<int>&nexlist=nds[nx].suflist;

				nexlist.insert(nexlist.end(),curlist.begin(),curlist.end());
				que.push(nx);
			}
		}
	}
};

template<uint32_t mod>
struct ModInt{
	uint32_t a;
	ModInt& s(uint32_t vv){
		a=vv<mod?vv:vv-mod;
		return *this;
	}

    ModInt(int64_t x=0){s(x%mod+mod);}

	ModInt& operator+=(const ModInt &x){return s(a+x.a);}
	ModInt& operator-=(const ModInt &x){return s(a+mod-x.a);}
	ModInt& operator*=(const ModInt &x){
		a=uint64_t(a)*x.a%mod;
		return *this;
	}
	ModInt& operator/=(const ModInt &x){
		*this*=x.inv();
		return *this;
	}

	ModInt operator+(const ModInt &x)const{return ModInt(*this)+=x;}
	ModInt operator-(const ModInt &x)const{return ModInt(*this)-=x;}
	ModInt operator*(const ModInt &x)const{return ModInt(*this)*=x;}
	ModInt operator/(const ModInt &x)const{return ModInt(*this)/=x;}
	bool operator==(const ModInt &x)const{return a==x.a;}
	bool operator!=(const ModInt &x)const{return a!=x.a;}
	bool operator<(const ModInt &x)const{return a<x.a;}

	ModInt operator-()const{return ModInt()-*this;}
	ModInt pow(int64_t n)const{
		ModInt res(1),x(*this);
		while(n){
			if(n&1)res*=x;
			x*=x;
			n>>=1;
		}
		return res;
	}

    ModInt inv()const{return pow(mod-2);}
};

template<uint32_t mod>
istream& operator>>(istream& in,const ModInt<mod>& a){
	return (in>>a.a);
}
template<uint32_t mod>
ostream& operator<<(ostream& out,const ModInt<mod>& a){
	return (out<<a.a);
}
using mint=ModInt<1000000007>;

int N,M,K;

unordered_map<int,mint>dp[2][510][510];

vint G[555];
vector<string>dic;
int nextState[666][666];
int numMatch[666][666];

mint dfs(int ex,int v,int l,int s){
	if(l==M){
		if(!ex)return 0;
		return 1;
	}
	if(dp[ex][v][l].count(s))return dp[ex][v][l][s];
	mint ret=0;
	for(auto &u:G[v]){
		int ns=nextState[s][u];
		int nl=l+dic[u].size();
		int nv=u;
		int nx=ex+numMatch[s][u];
		if(nl>M||nx>1)continue;
		ret+=dfs(nx,nv,nl,ns);
	}
	return dp[ex][v][l][s]=ret;
}
void solve(){
	dic=vector<string>();
	rep(i,555)G[i]=vint();
	rep(i,2)rep(j,510)rep(k,510)dp[i][j][k]=unordered_map<int,mint>();

	vector<string>from(N),to(N);
	rep(i,N){
		cin>>from[i]>>to[i];
		dic.pb(from[i]);
		dic.pb(to[i]);
	}

	sort(all(dic));dic.erase(unique(all(dic)),dic.end());
	rep(i,N){
		int a=lower_bound(all(dic),from[i])-dic.begin();
		int b=lower_bound(all(dic),to[i])-dic.begin();
		G[a].pb(b);
	}

	AhoCorasick ac;
	rep(i,K){
		string s;
		cin>>s;
		ac.add(s,i);
	}

	ac.build();

	for(int i=0;i<ac.nds.size();i++){
		for(int j=0;j<dic.size();j++){
			int s=i;
			int cnt=0;
			rep(k,dic[j].size()){
				s=ac.process(s,dic[j][k]);
				cnt+=ac.nds[s].suflist.size();
			}
			nextState[i][j]=s;
			numMatch[i][j]=cnt;
		}
	}

	mint ans=0;
	for(int i=0;i<dic.size();i++)if(dic[i].size()<=M&&numMatch[0][i]<=1){
		ans+=dfs(numMatch[0][i],i,dic[i].size(),nextState[0][i]);
	}
	cout<<ans<<endl;
}

signed main(){
	while(cin>>N>>M>>K,N)solve();
	return 0;
}


Measured memory_bytes: 168888