#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <assert.h>
#include <vector>
#include <string>
#include <map>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

struct State {
  int left;
  int right;
  int lr;
  int cnt;
  State() {;}
  State(int left, int right, int lr, int cnt) : left(left), right(right), lr(lr), cnt(cnt) {;}
  bool operator<(const State &rhs) const {
    if (left != rhs.left) { return left < rhs.left; }
    if (right != rhs.right) { return right < rhs.right; }
    if (lr != rhs.lr) { return lr < rhs.lr; }
    return cnt < rhs.cnt;
  }
};

const ll MOD = 1000000007;
int n[2];
int m[2];
vector<string> strs[2];
vector<vector<int> > from[2];
vector<int> to[2];
map<State, ll> memo;

ll calc(int left, int right, int lr, int cnt);
ll NextState(int left, int right, int lr, int cnt) {
  ll ret = 0;
  if (lr == 0) {
    FORIT(it, from[1][right]) {
      ret = (ret + calc(left, *it, lr, cnt)) % MOD;
    }
  } else {
    FORIT(it, from[0][left]) {
      ret = (ret + calc(*it, right, lr, cnt)) % MOD;
    }
  }
  return ret;
}

ll calc(int left, int right, int lr, int cnt) {
  if (left == m[0] && right == m[1]) { return 1; }
  State state(left, right, lr, cnt);
  if (memo.count(state)) { return memo[state]; }
  ll ret = 0;
  const string &lstr = strs[0][left];
  const string &rstr = strs[1][right];
  if (lr == 0 && (int)lstr.size() == cnt) {
    ret = NextState(to[0][left], right, 1, 0);
  } else if (lr == 1 && (int)rstr.size() == cnt) {
    ret = NextState(left, to[1][right], 0, 0);
  } else {
    int lindex = 0;
    int rindex = 0;
    if (lr == 0) { lindex = cnt; }
    else { rindex = cnt; }
    while (lindex < (int)lstr.size() && rindex < (int)rstr.size()) {
      if (lstr[lindex] != rstr[rindex]) { goto end; }
      lindex++;
      rindex++;
    }
    if (lindex == (int)lstr.size()) {
      ret = NextState(to[0][left], right, 1, rindex);
    } else {
      ret = NextState(left, to[1][right], 0, lindex);
    }
  }
end:
  return memo[state] = ret;
}

char str[100];
int main() {
  int test;
  scanf("%d", &test);
  while (test--) {
    memo.clear();
    REP(iter, 2) {
      scanf("%d %d", &n[iter], &m[iter]);
      from[iter].clear();
      strs[iter].resize(m[iter] + 1);
      from[iter].resize(n[iter]);
      to[iter].resize(m[iter]);
      REP(i, m[iter]) {
        int f, t;
        scanf("%d %d %s", &f, &t, str);
        from[iter][f].push_back(i);
        to[iter][i] = t;
        strs[iter][i] = str;
      }
      from[iter][n[iter] - 1].push_back(m[iter]);
      strs[iter][m[iter]] = "!";
    }
    ll ans = 0;
    FORIT(lit, from[0][0]) {
      ans = (ans + NextState(*lit, 0, 0, 0)) % MOD;
    }
    printf("%lld\n", ans);
  }
}