voidtarjan(int x) { dfn[x] = low[x] = ++ *dfn, ins[stk[++ top] = x] = true; for (int i = h[x], v; ~i; i = ne[i]) if (!dfn[v = e[i]]) tarjan(v), chkmin(low[x], low[v]); elseif (ins[v]) chkmin(low[x], dfn[v]); if (low[x] ^ dfn[x]) return; int cur; ++ *bel; do bel[cur = stk[top --]] = *bel, ins[cur] = false; while (cur != x); }
voiddfs(int x, int fa = 0) { dep[x] = dep[fa] + 1, f[x] = fa; for (int v : g[x]) if (v != fa) dfs(v, x); }
std::vector<int> getpath(int u, int v) { std::vector<int> pth1, pth2; while (u != v) { if (dep[u] > dep[v]) pth1.push_back(u), u = f[u]; else pth2.push_back(v), v = f[v]; } pth1.push_back(u); std::reverse(pth2.begin(), pth2.end()); for (int &x : pth2) pth1.push_back(x); return pth1; }
intmain() { int m; std::cin >> n >> m; for (int i = 1; i <= 2 * n + 2 * m; ++ i) h[i] = -1; for (int i = 1, u, v; i < n; ++ i) { scanf("%d %d", &u, &v); g[u].push_back(v), g[v].push_back(u); } auto getid = [&](int u, char c) { if (!gt[u][0]) gt[u][0] = c; if (gt[u][0] == c) return0; if (!gt[u][1]) gt[u][1] = c; if (gt[u][1] == c) return1; return-1; }; dfs(1); for (int id = 1, u, v; id <= m; ++ id) { scanf("%d%d%s", &u, &v, s); auto path = getpath(u, v); int sz = path.size(); for (int i = 0; i < sz; ++ i) for (int x = 0; x < 2; ++ x) { if (getid(path[i], s[i]) != x) { add(path[i] + x * n, 2 * n + id); add(2 * n + m + id, path[i] + !x * n); } if (getid(path[i], s[sz - i - 1]) != x) { add(path[i] + x * n, 2 * n + m + id); add(2 * n + id, path[i] + !x * n); } } } for (int i = 1; i <= n; ++ i) { if (!gt[i][0]) gt[i][0] = 'a'; if (!gt[i][1]) gt[i][1] = 'a'; } for (int i = 1; i <= 2 * n + 2 * m; ++ i) if (!dfn[i]) tarjan(i); for (int i = 1; i <= n; ++ i) if (bel[i] == bel[i + n]) returnputs("NO"), 0; for (int i = 2 * n + 1; i <= 2 * n + m; ++ i) if (bel[i] == bel[i + m]) returnputs("NO"), 0; puts("YES"); for (int i = 1; i <= n; ++ i) putchar(gt[i][bel[i + n] < bel[i]]); return0; }