// {{{ boilerplate
#include "io.h"
#include "mod.h"
#include "snippets/ranges.h"
#include <bits/stdc++.h>
// }}}
using Mod = ModT<998'244'353>;
constexpr int N = 3000;
int n, m, belong[N], head[N], to[N << 1], next[N << 1], depth[N], parent[N],
dsu_parent[N], leader_[N], dist_[N][N];
bool visit[N];
Mod dp[N][N];
namespace ct /* component tree */ {
int head[N], next[N];
}
namespace gr /* grouping */ {
int head[N], next[N];
}
int dsu_find(int u) {
if (dsu_parent[u] != u) {
dsu_parent[u] = dsu_find(dsu_parent[u]);
}
return dsu_parent[u];
}
int &leader(int u) { return leader_[belong[u]]; }
bool prepare(int u) {
if (!~leader(u)) {
leader(u) = u;
}
auto U = leader(u);
if (U != dsu_find(u)) {
return false;
}
gr::next[u] = gr::head[U];
gr::head[U] = u;
for (auto it = head[u]; ~it; it = next[it]) {
auto v = to[it];
if (v != parent[u]) {
depth[v] = u;
parent[v] = u;
if (belong[u] == belong[v]) {
dsu_parent[v] = dsu_parent[u];
}
if (!prepare(v)) {
return false;
}
auto V = leader(v);
if (U != V) {
ct::next[V] = ct::head[U];
ct::head[U] = V;
}
}
}
return true;
}
int dist(int u, int v) {
if (depth[u] > depth[v]) {
return dist(v, u);
}
auto &cache = dist_[u][v];
if (!~cache) {
cache = dist(u, parent[v]) + 1;
}
return cache;
}
std::vector<int> children;
void dfs(int u) {
for (auto v = ct::head[u]; ~v; v = ct::next[v]) {
dfs(v);
}
std::fill(dp[u], dp[u] + n, Mod{0});
children.clear();
for (auto v = ct::head[u]; ~v; v = ct::next[v]) {
children.push_back(v);
}
for (auto c = gr::head[u]; ~c; c = gr::next[c]) {
Mod ways{1};
for (auto &&v : children) {
auto d_u = dist(c, v);
Mod vways{0};
// = d_u - 2
vways += dp[v][d_u - 1];
if (belong[u] < belong[v]) {
if (d_u >= 2) {
vways += dp[v][d_u - 2];
}
} else {
vways += dp[v][d_u];
}
ways *= vways;
}
dp[u][dist(u, c)] += ways;
}
}
int main() {
IO io;
auto T = io.read();
while (T--) {
std::tie(n, m) = io.read_t<int, int>();
std::fill(head, head + n, -1);
for (int i = 0; i < (n - 1) << 1; i++) {
to[i] = io.read() - 1;
}
for (int i = 0; i < (n - 1) << 1; i++) {
next[i] = head[to[i ^ 1]];
head[to[i ^ 1]] = i;
}
std::fill(visit, visit + m, false);
for (int i = 0; i < n; i++) {
visit[belong[i] = io.read() - 1] = true;
}
auto solve = [&]() -> Mod {
depth[0] = 0;
parent[0] = -1;
std::iota(dsu_parent, dsu_parent + n, 0);
std::fill(leader_, leader_ + m, -1);
std::fill(ct::head, ct::head + n, -1);
std::fill(gr::head, gr::head + n, -1);
if (!prepare(0)) {
return Mod{0};
}
for (int u = 0; u < n; u++) {
std::fill(dist_[u], dist_[u] + n, -1);
dist_[u][u] = 0;
}
dfs(0);
return std::accumulate(dp[0], dp[0] + n, Mod{0});
};
io << solve() << '\n';
}
}