#include <iostream>
#include <fstream>
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iomanip>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

#define EPS 1e-9
#define INF MOD
#define MOD 1000000007LL
#define fir first
#define iss istringstream
#define sst stringstream
#define ite iterator
#define ll long long
#define mp make_pair
#define rep(i,n) rep2(i,0,n)
#define rep2(i,m,n) for(int i=m;i<n;i++)
#define pi pair<int,int>
#define pb push_back
#define sec second
#define sh(i) (1LL<<i)
#define sz size()
#define vi vector<int>
#define vc vector
#define vl vector<ll>
#define vs vector<string>

int T,n,m,N,M,a,b;
map<pi,int> dp;
string s;
struct E{int from;char c;E(int a,char b):from(a),c(b){}};
vc<E> e[3010],f[3010];

int F(int a,int b){
	if(dp.find(pi(a,b))!=dp.end())return dp[pi(a,b)];
	int& res=dp[pi(a,b)];
	if(!a&&!b)return res=1;
	rep(i,e[a].sz)rep(j,f[b].sz)if(e[a][i].c==f[b][j].c){
		res=(res+F(e[a][i].from,f[b][j].from))%MOD;
	}
	return res;
}

int main(){
	cin>>T;
	rep(tc,T){
		rep(i,3010)e[i].clear(),f[i].clear();
		cin>>n>>m;
		int cur=n;
		rep(i,m){
			cin>>a>>b>>s;
			if(s.sz==1)e[b].pb(E(a,s[0]));
			else rep(j,s.sz){
				if(j==0)e[cur].pb(E(a,s[j])),cur++;
				else if(j==s.sz-1)e[b].pb(E(cur-1,s[j]));
				else e[cur].pb(E(cur-1,s[j])),cur++;
			}
		}
		cin>>N>>M;
		cur=N;
		rep(i,M){
			cin>>a>>b>>s;
			if(s.sz==1)f[b].pb(E(a,s[0]));
			else rep(j,s.sz){
				if(j==0)f[cur].pb(E(a,s[j])),cur++;
				else if(j==s.sz-1)f[b].pb(E(cur-1,s[j]));
				else f[cur].pb(E(cur-1,s[j])),cur++;
			}
		}
		dp.clear();
		cout<<F(n-1,N-1)<<endl;
	}
}