#include <iostream> 
#include <sstream> 
#include <iomanip> 
#include <algorithm> 
#include <cmath> 
#include <string> 
#include <vector> 
#include <list> 
#include <queue> 
#include <stack> 
#include <set> 
#include <map> 
#include <bitset> 
#include <numeric> 
#include <climits> 
#include <cfloat> 
using namespace std;

const int MOD = 1000000007;

void input(int &n, int &m, vector<vector<int> >& to, vector<vector<string> >& str)
{
    cin >> n >> m;
    to.assign(n, vector<int>());
    str.assign(n, vector<string>());

    for(int i=0; i<m; ++i){
        int a, b;
        string s;
        cin >> a >> b >> s;
        to[a].push_back(b);
        str[a].push_back(s);
    }
}

bool compare(string& s, string& t)
{
    int n = min(s.size(), t.size());
    if(s.substr(0, n) != t.substr(0, n))
        return false;

    s = s.substr(n);
    t = t.substr(n);
    return true;
}

int main()
{
    int t;
    cin >> t;

    while(--t >= 0){
        int n1, m1, n2, m2;
        vector<vector<int> > to1, to2;
        vector<vector<string> > str1, str2;
        input(n1, m1, to1, str1);
        input(n2, m2, to2, str2);

        vector<vector<vector<map<string, int> > > > dp(n1, vector<vector<map<string, int> > >(n2, vector<map<string, int> >(2)));
        dp[0][0][0][""] = 1;

        for(int i=0; i<n1; ++i){
            for(int j=0; j<n2; ++j){
                if(i == n1-1 && j == n2-1)
                    break;

                while(!dp[i][j][0].empty()){
                    map<string, int>::iterator it = dp[i][j][0].begin();
                    string s0 = it->first;
                    int num = it->second;
                    dp[i][j][0].erase(it);

                    for(unsigned k=0; k<to1[i].size(); ++k){
                        int to = to1[i][k];
                        string s = s0;
                        string t = str1[i][k];
                        if(compare(s, t)){
                            if(t.size() == 0){
                                dp[to][j][0][s] += num;
                                dp[to][j][0][s] %= MOD;
                            }else{
                                dp[to][j][1][t] += num;
                                dp[to][j][1][t] %= MOD;
                            }
                        }
                    }
                }

                while(!dp[i][j][1].empty()){
                    map<string, int>::iterator it = dp[i][j][1].begin();
                    string s0 = it->first;
                    int num = it->second;
                    dp[i][j][1].erase(it);

                    for(unsigned k=0; k<to2[j].size(); ++k){
                        int to = to2[j][k];
                        string s = s0;
                        string t = str2[j][k];
                        if(compare(s, t)){
                            if(s.size() == 0){
                                dp[i][to][0][t] += num;
                                dp[i][to][0][t] %= MOD;
                            }else{
                                dp[i][to][1][s] += num;
                                dp[i][to][1][s] %= MOD;
                            }
                        }
                    }
                }
            }
        }

        cout << dp[n1-1][n2-1][0][""] << endl;
    }

    return 0;
}

Measured memory_bytes: 17000