#include #include template std::ostream &operator<<(std::ostream &os, const atcoder::static_modint &mint) { os << mint.val(); return os; } template std::ostream &operator<<(std::ostream &os, const std::pair &p) { os << "[" << p.first << " " << p.second << "]"; return os; } int main() { using namespace std; using modint = atcoder::static_modint<998244353>; unsigned N; cin >> N; vector> edges(N); for (unsigned i{1}, u, v; i < N; ++i) { cin >> u >> v; edges[--u].emplace_back(--v); edges[v].emplace_back(u); } vector A(N); for (auto &&a : A) cin >> a; modint ans{}; for (unsigned i{30}; i--;) { (ans *= 2) += [dfs_impl{[&edges, &A, &i](const auto &f, unsigned now, unsigned prev) -> pair { pair ans{!(1 & (A[now] >> i)), 1 & (A[now] >> i)}; auto &&[z, o]{ans}; for (const auto &next : edges[now]) if (next != prev) { const auto &[zero, one]{f(f, next, now)}; ans = make_pair(z * (zero + one) + o * one, o * (zero + one) + z * one); } return ans; }}] { return dfs_impl(dfs_impl, 0, 0).second; }(); } cout << ans.val() << endl; return 0; }