#include using namespace std; using ll=long long; const ll ILL=2167167167167167167; const int INF=2100000000; #define rep(i,a,b) for (int i=(int)(a);i<(int)(b);i++) #define all(p) p.begin(),p.end() template using pq_ = priority_queue, greater>; template int LB(vector &v,T a){return lower_bound(v.begin(),v.end(),a)-v.begin();} template int UB(vector &v,T a){return upper_bound(v.begin(),v.end(),a)-v.begin();} template bool chmin(T &a,T b){if(b bool chmax(T &a,T b){if(a void So(vector &v) {sort(v.begin(),v.end());} template void Sore(vector &v) {sort(v.begin(),v.end(),[](T x,T y){return x>y;});} bool yneos(bool a,bool upp=false){if(a){cout<<(upp?"YES\n":"Yes\n");}else{cout<<(upp?"NO\n":"No\n");}return a;} template void vec_out(vector &p,int ty=0){ if(ty==2){cout<<'{';for(int i=0;i<(int)p.size();i++){if(i){cout<<",";}cout<<'"'< T vec_min(vector &a){assert(!a.empty());T ans=a[0];for(auto &x:a) chmin(ans,x);return ans;} template T vec_max(vector &a){assert(!a.empty());T ans=a[0];for(auto &x:a) chmax(ans,x);return ans;} template T vec_sum(vector &a){T ans=T(0);for(auto &x:a) ans+=x;return ans;} int pop_count(long long a){int res=0;while(a){res+=(int)(a&1),a>>=1;}return res;} template T square(T a){return a * a;} void solve(); // DEAR MYSTERIES / TOMOO int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int t = 1; // cin >> t; rep(i, 0, t) solve(); } void solve(){ int N, K; cin >> N >> K; vector A(N); rep(i, 0, N) cin >> A[i]; if (vec_sum(A) & 1) { cout << "-1\n"; return; } auto f = [&](ll a) -> ll { if (a == 0) return 0; if (a < K) return ILL; return (a - 1) / (2 * K) + 1; }; vector to(N); vector> G(N); rep(i, 0, N) { int a, b; cin >> a >> b; a--, b--; G[a].push_back(b); G[b].push_back(a); to[a]++, to[b]++; } ll ans = 0; vector order; rep(i, 0, N) { if (to[i] == 1) order.push_back(i); } rep(rp, 0, order.size()) { int a = order[rp]; to[a] = 0; for (auto x : G[a]) { to[x]--; if (to[x] >= 1) { ans += f(A[a]); A[x] -= A[a]; if (A[x] < 0 || ans >= ILL) { cout << "-1\n"; return; } if (to[x] == 1) order.push_back(x); } } } vector B; rep(i, 0, N) if (to[i] >= 2) { order = {i}; while (true) { B.push_back(A[order.back()]); to[order.back()] = 0; int nx = -1; for (auto x : G[order.back()]) { if (to[x] >= 2) { nx = x; break; } } if (nx == -1) break; order.push_back(nx); } break; } int M = B.size(); vector X(M), C(M); { ll tmp = 0; rep(i, 0, M) { X[i] = (i & 1) * 2 - 1; tmp = B[i] - tmp; C[i] = tmp; } } ll tree_ans = ans; ans = ILL; // vec_out(B); // vec_out(C); // vec_out(X); auto g = [&](ll x) -> ll { ll tmp = tree_ans; rep(i, 0, M) { tmp = min(ILL, tmp + f(C[i] + x * X[i])); } // cout << x << " " << tmp << endl; return tmp; }; if (M & 1) { ans = g(C[M - 1] / 2); if (ans == ILL) ans = -1; cout << ans << "\n"; return; } if (C.back()) { cout << "-1\n"; return; } // cout << tree_ans << endl; // x の値を 0 があり得るものにする // x の値を K があり得るものにする? rep(i, 0, 2) rep(j, 0, 2){ ll l = ILL; ll r = -ILL; rep(k, 0, M) { if (k % 2 == i) { // X[k] * val + C[k] = j * K // val = (j * K - C[k]) / X[k] chmin(l, (K * j - C[k]) / X[k]); chmax(r, (K * j - C[k]) / X[k]); } } chmin(ans, g(l)); chmin(ans, g(r)); } // cout << ans << endl; // 全てが K より大きいとして良い // その上で、適当なあれをする { ll l = -ILL; ll r = ILL; rep(i, 0, M) { if (X[i] == 1) { chmax(l, K + 1 - C[i]); } else { chmin(r, C[i] - K - 1); } } if (r >= l) { ll base = tree_ans; vector> p; rep(i, 0, M) { ll tmp = l * X[i] + C[i]; base += f(tmp); if (X[i] == 1) { // 2 * K であれのときを探す ll nx = 2 * K - (tmp - 1) % (2 * K); if (nx <= r - l) { p.push_back({nx, -1}); } } else { ll nx = (tmp - 1) % (2 * K) + 1; if (nx <= r - l) { p.push_back({nx, 1}); } } } chmin(ans, base); So(p); for (auto a : p) { base -= a.second; chmin(ans, base); } } } cout << ans << '\n'; } /* * [K, 2K] : 1 * (2K, 4K] : 2 * 基本的に、 * (2a, 2(a + 1)K] * 減らすのに a + 1 かかると思っていい * ただし、a = 1 の時だけへんで、 * [K, 2K] だし、0 にもできる * 0 がある時は分離していい * [1, K) があるならそれは -1 * 数 a は c 回で 0 にできるとき、 * a / 2K <= c <= a/ K である(当たり前) * というかなもりだから、最後の輪っか以外は自明じゃん */