#include using namespace std; using ll = long long; static const ll MOD = 998244353; // 快速幂 ll pow_mod(ll a, ll e) { ll r = 1; while (e) { if (e & 1) r = r * a % MOD; a = a * a % MOD; e >>= 1; } return r; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; vector a(n + 1); int Amax = 0; for (int i = 1; i <= n; i++) { cin >> a[i]; Amax = max(Amax, a[i]); } // 1) 线性筛求 spf vector spf(Amax + 1); vector primes; for (int i = 2; i <= Amax; i++) { if (!spf[i]) { spf[i] = i; primes.push_back(i); } for (int p : primes) { if ((ll)p * i > Amax) break; spf[p * i] = p; if (p == spf[i]) break; } } // 2) 分解质因子 vector>> factors(n + 1); for (int i = 1; i <= n; i++) { int x = a[i]; while (x > 1) { int p = spf[x], c = 0; while (spf[x] == p) { x /= p; c++; } factors[i].emplace_back(p, c); } } // 3) 建图 + 挑根做一次栈式 DFS,获得 children 列表 vector> g(n + 1), children(n + 1); for (int i = 1, u, v; i < n; i++) { cin >> u >> v; g[u].push_back(v); g[v].push_back(u); } vector parent(n + 1, 0); { // 非递归把 parent/children 填好 vector stk; stk.reserve(n); stk.push_back(1); parent[1] = 0; for (int idx = 0; idx < (int)stk.size(); idx++) { int u = stk[idx]; for (int v : g[u]) if (v != parent[u]) { parent[v] = u; children[u].push_back(v); stk.push_back(v); } } } // 4) 后序遍历 + small-to-large map 合并 vector ans(n + 1), lcmv(n + 1); vector *> mp(n + 1, nullptr); // 显式栈: (u, state=0=pre,1=post) vector> stk; stk.reserve(2 * n); stk.emplace_back(1, 0); while (!stk.empty()) { auto [u, state] = stk.back(); stk.pop_back(); if (state == 0) { // pre(u) mp[u] = new unordered_map(); mp[u]->reserve(factors[u].size()); lcmv[u] = 1; for (auto &fc : factors[u]) { int p = fc.first, e = fc.second; (*mp[u])[p] = e; lcmv[u] = lcmv[u] * pow_mod(p, e) % MOD; } // 压栈:先自己的 post,再所有孩子的 pre stk.emplace_back(u, 1); for (int v : children[u]) { stk.emplace_back(v, 0); } } else { // post(u):所有 children 都已经建好 mp[v], lcmv[v] for (int v : children[u]) { // small-to-large if (mp[u]->size() < mp[v]->size()) { swap(mp[u], mp[v]); swap(lcmv[u], lcmv[v]); } // 把 v 并入 u for (auto &kv : *mp[v]) { int p = kv.first, e_v = kv.second; int e_u = (*mp[u])[p]; if (e_v > e_u) { (*mp[u])[p] = e_v; // 新增 p^(e_v-e_u) lcmv[u] = lcmv[u] * pow_mod(p, e_v - e_u) % MOD; } } // 释放 child map delete mp[v]; mp[v] = nullptr; } ans[u] = lcmv[u]; } } // 5) 输出 ostringstream oss; for (int i = 1; i <= n; i++) { oss << ans[i] << "\n"; } cout << oss.str(); return 0; }