#include #include #include #include #include #include #include constexpr int MAX_N = 5000; using Dp_t = std::array; int main() { int32_t n; std::cin >> n; // original values std::vector a(n); for (auto& x : a) { std::cin >> x; } std::vector> tree(n); // tree data. Assuming edge list, 1-indexed. for (int32_t i = 1; i < n; ++i) { int32_t u, v; std::cin >> u >> v; --u; --v; tree[u].push_back(v); tree[v].push_back(u); } // dfs(u)[x] = min cost when setting value of node u to x auto dfs = [&](auto&& self, int32_t u, int32_t p) -> Dp_t { // can always change all values to 2 for a total cost of 2n. Dp_t ans{}; std::iota(ans.begin(), ans.end(), 0); ans[a[u]] = 0; for (int32_t v : tree[u]) { if (v == p) continue; Dp_t sub = self(self, v, u); for (int32_t d = 2; d < ans.size(); ++d) { for (int32_t j = d + d; j < sub.size(); j += d) { sub[d] = std::min(sub[d], sub[j]); } } for (int32_t d = 2; d < ans.size(); ++d) { for (int32_t j = d + d; j < sub.size(); j += d) { sub[j] = std::min(sub[j], sub[d]); } } for (int32_t d = 2; d < ans.size(); ++d) { ans[d] += sub[d]; } } return ans; }; Dp_t ans = dfs(dfs, 0, -1); int32_t res = ans[2]; for (int32_t d = 3; d < ans.size(); ++d) { res = std::min(res, ans[d]); } std::cout << res << std::endl; return 0; }