#include #include #include #include #include using namespace std; // 定数 const int MAXN = 500005; const int MAXA = 1000001; const int MOD = 998244353; // グローバル変数 vector adj[MAXN]; int a[MAXN]; int sz[MAXN]; long long ans[MAXN]; int spf[MAXA]; // Smallest Prime Factor // エラトステネスの篩で最小の素因数を求める void sieve() { iota(spf, spf + MAXA, 0); // spf[i] = i で初期化 for (int i = 2; i * i < MAXA; ++i) { if (spf[i] == i) { // iが素数 for (int j = i * i; j < MAXA; j += i) { if (spf[j] == j) { // まだ最小素因数が更新されていない spf[j] = i; } } } } } // 高速な素因数分解 map get_factors(int n) { map factors; while (n != 1) { factors[spf[n]]++; n /= spf[n]; } return factors; } // mod上のべき乗 long long power(long long base, long long exp) { long long res = 1; base %= MOD; while (exp > 0) { if (exp % 2 == 1) res = (res * base) % MOD; base = (base * base) % MOD; exp /= 2; } return res; } // DFSで部分木のサイズを計算し、重い子を特定する void dfs_size(int u, int p) { sz[u] = 1; int heavy_child_idx = -1; int max_sz = 0; for (size_t i = 0; i < adj[u].size(); ++i) { int v = adj[u][i]; if (v == p) continue; dfs_size(v, u); sz[u] += sz[v]; if (sz[v] > max_sz) { max_sz = sz[v]; heavy_child_idx = i; } } // 重い子を隣接リストの先頭に持ってくる if (heavy_child_idx != -1) { swap(adj[u][0], adj[u][heavy_child_idx]); } } // DSU on Trees を用いたメインのDFS map dfs_solve(int u, int p) { map u_lcm_factors; // 重い子が存在すれば、その結果を再利用する int heavy_child = -1; if (!adj[u].empty() && adj[u][0] != p) { heavy_child = adj[u][0]; } if (heavy_child != -1) { u_lcm_factors = dfs_solve(heavy_child, u); } // 軽い子の結果をマージする for (int v : adj[u]) { if (v == p || v == heavy_child) continue; map lc_lcm_factors = dfs_solve(v, u); for (auto const& [prime, exponent] : lc_lcm_factors) { u_lcm_factors[prime] = max(u_lcm_factors[prime], exponent); } } // 現在のノードの重みをマージする map current_factors = get_factors(a[u]); for (auto const& [prime, exponent] : current_factors) { u_lcm_factors[prime] = max(u_lcm_factors[prime], exponent); } // uを根とする部分木の答えを計算する long long current_ans = 1; for (auto const& [prime, exponent] : u_lcm_factors) { current_ans = (current_ans * power(prime, exponent)) % MOD; } ans[u] = current_ans; return u_lcm_factors; } int main() { // 高速化 ios_base::sync_with_stdio(false); cin.tie(NULL); sieve(); int n; cin >> n; for (int i = 1; i <= n; ++i) { cin >> a[i]; } for (int i = 0; i < n - 1; ++i) { int u, v; cin >> u >> v; adj[u].push_back(v); adj[v].push_back(u); } // 1を根として処理を開始 dfs_size(1, 0); dfs_solve(1, 0); for (int i = 1; i <= n; ++i) { cout << ans[i] << "\n"; } return 0; }