//use std::collections::VecDeque; use proconio::{input, marker::Usize1}; const INF: usize = 1 << 60; fn main() { input! { t: usize, } for _ in 0..t { solve(); } } fn solve() { input! { n: usize, // 頂点数 m: usize, // 辺の数 k: usize, // mod uv: [(Usize1, Usize1); m], b: [usize; n], } // グラフ(木)の構築 let tree = make_graph(n, m, &uv); // 木の葉から貪欲に。最後の頂点が一致すればOK let mut isok = false; dfs(n, m, &tree, 0, INF, &b, &mut isok, k); println!("{}", if isok {"Yes"} else {"No"}); } fn make_graph(n: usize, _m: usize, uv: &Vec<(usize, usize)>) -> Vec>{ let mut ret = vec![Vec::new(); n]; for &(u, v) in uv { ret[u].push(v); ret[v].push(u); } ret } fn dfs(n: usize, _m:usize, tree: &Vec>, cpos: usize, ppos: usize, b: &Vec, isok: &mut bool, k: usize, ) -> usize{ // 操作済みの操作回数 let mut cnt = 0; // 自身の子を調べる for &npos in &tree[cpos] { // あと戻り禁止 if npos == ppos { continue; } // 操作回数を取得 cnt += dfs(n, _m, tree, npos, cpos, b, isok, k); } // 必要回数を取得 let ret = (b[cpos] + k - cnt) % k; // 根なら判定する if cpos == 0 { if ret == 0 { *isok = true;} } ret }