#include <iostream>
#include <vector>
#include <string>
#include <cstdio>
#include <cstring>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

#define REP(i,a,n) for(i=a; i<n; i++)
#define rep(i,n) REP(i,0,n)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define foreach(it,x) for(typeof(x.begin()) it=x.begin(); it!=x.end(); it++)

#define AHOSIZE 26

const int mod = 1000000007;
int N,M,K;
vector<int> dict[500];
string from[250], to[250];
int ahosize;
char memo[1000]; // ahoid

struct Aho{
    bool accept;
    int id;
    Aho *next[AHOSIZE], *fail;

    Aho(){
        int i;
        fail = NULL;
        accept = false;
        id = ahosize; //
        ahosize++; //
        rep(i,AHOSIZE) next[i] = NULL;
    }
    ~Aho(){
        int i;
        rep(i,AHOSIZE) if( next[i] ) delete next[i];
    }

    void insert(const string& in){
        int i,n = in.length();
        Aho *now = this;

        rep(i,n){
            if( now->next[in[i]-'a'] == NULL ){
                now->next[in[i]-'a'] = new Aho();
            }
            now = now->next[in[i]-'a'];
        }
        now->accept = true;
    }

    // failツづーツ催ャツづゥ
    void build(){
        int i;
        queue<Aho*> q;
        q.push(this);
        
        while( !q.empty() ){
            Aho *now = q.front();
            q.pop();
            
            rep(i,AHOSIZE) if( now->next[i] ) {
                q.push(now->next[i]);

                Aho *r = now->fail;
                while( r != NULL && r->next[i] == NULL ) r = r->fail;
                if( r != NULL ){
                    now->next[i]->fail = r->next[i];
                }
                else{
                    now->next[i]->fail = this;
                }
            }
        }
    }

    Aho* match(Aho* root, const string& in, int* hit){
        int i, n = in.length();
        Aho *now = root;
        
        rep(i,n){
            if( now->next[in[i]-'a'] ){
                now = now->next[in[i]-'a'];
            }
            else{
                while( now != this ){
                    now = now->fail;
                    if( now->next[in[i]-'a'] ){
                        now = now->next[in[i]-'a'];
                        break;
                    }
                }
            }
            
            // ツつアツつアツづ個渉按猟敖づ債δδつ可サツつキツづゥツつアツづづ債つ堕ャツ可サツづつォツづゥ
            Aho* tmp = now;
            
            // ツ全ツ探ツ催オ
            /*
            while( tmp != this ){
                if( tmp->accept ) ++*hit;
                if( *hit >= 2 ) return NULL;
                tmp = tmp->fail;
            }
            */

            // ツδδつ可サ
            int cc = 0;
            if( memo[now->id] != -1 ){
                cc = memo[now->id];
            }
            else{
                while( tmp != this ){
                    if( memo[tmp->id] != -1 ){
                        cc += memo[tmp->id];
                        break;
                    }
                    else{
                        if( tmp->accept ) cc++;
                    }
                    tmp = tmp->fail;
                }
                memo[now->id] = cc;
            }
            *hit += cc;
            if( *hit >= 2 ) return NULL;
        }

        return now;
    }

};


struct state{
    int from,cnt;
    Aho* node;
    state(int f, int c, Aho *n){
        from = f, cnt = c, node = n;
    }
    bool operator<(const state& a)const{
        if( cnt != a.cnt ) return cnt < a.cnt;
        if( node != a.node ) return node < a.node;
        return from < a.from;
    }
};

#define Z 21
map<state,int> dp[Z];

int main(){
    int i,j;

    while( cin >> N >> M >> K, N|M|K ){
        // init
        rep(i,Z) dp[i].clear();
        rep(i,500) dict[i].clear();
        memset(memo, -1, sizeof(memo));
        ahosize = 0;


        Aho Ahoinit;
        set<string> ss;


        // dict[from is new index][ツ古つ青脳 = to is new index 

        // input
        rep(i,N){
            cin >> from[i] >> to[i];
            ss.insert(from[i]);
            ss.insert(to[i]);
        }

        //
        vector<string> words(ss.begin(), ss.end());
        rep(i,words.size()){
            rep(j,N) if( words[i] == from[j] ) {
                dict[i].push_back(lower_bound(all(words), to[j]) - words.begin());
            }
        }

        rep(i,K){
            string kigo; cin >> kigo;
            Ahoinit.insert(kigo);
        }
        Ahoinit.build();

        // start
        rep(i,words.size()){
            int cnt = 0;
            Aho* next = Ahoinit.match(&Ahoinit, words[i], &cnt);
            if( cnt < 2 ){
                dp[words[i].length()][state(i,cnt,next)] = 1;
            }
        }
        
        rep(j,M){
            foreach(it,dp[j%Z]){
                int f_id = it->first.from;
                int cnt = it->first.cnt;
                Aho *now = it->first.node;
                int res = it->second;

                rep(i,dict[f_id].size()){
                    int t_id = dict[f_id][i];
                    int n = words[t_id].length();
                    if( j + n > M ) continue;

                    int tcnt = cnt;
                    Aho *next = Ahoinit.match(now, words[t_id], &tcnt);
                    if( tcnt < 2 && next != NULL ){
                        dp[(j + n)%Z][state(t_id, tcnt, next)] += res;
                        dp[(j + n)%Z][state(t_id, tcnt, next)] %= mod;
                    }
                }
            }
            // clear
            dp[j%Z].clear();
        }

        int ans = 0;
        foreach(it,dp[M%Z]) if( it->first.cnt == 1 ) {
            ans += it->second;
            ans %= mod;
        }
        cout << ans << endl;
        
    }

    return 0;
}

Measured memory_bytes: 2800