Problem:
G: トレジャーハンター (Treasure Hunter)
問題
財宝の山が
N
個あり、それぞれの山は
1
から
N
までで番号づけられている。
i
番目の山には価値
p_i
のお宝が眠っており、このお宝はその山に訪れた時点で得ることができる。一度お宝を得るとその山からはお宝がなくなってしまうので、お宝はそれぞれ一度しか得ることはできない。
異なる山に移動するには必ず道を利用しなければならない。山と山の間には合計
N-1
本の道があり、
i
番目の道は山
u_i
と
v_i
を双方向に結んでいる。もしもどの道も問題なく通行可能であると仮定すると、任意の
2
つの山について相互に行き来可能であることが分かっている。
どの道も長らく誰も通行しておらず修復しないと渡れないため、
i
番目の道について最初に渡る際には
c_i
円を支払って工事し、通行可能にする必要がある。一度工事した道であればそれ以上お金を支払うことなく通行が可能である。
トレジャーハンターであるあなたは、道の工事費用の予算を
W
円持っている。あなたの目的は、はじめに降り立つ山を任意に
1
つ決め、合計
W
円以下で道を工事して異なる山に移動することで、得られるお宝の価値の合計を最大化することである。あなたは最大でどれだけの価値を得られるだろうか？
なお、お宝を途中で換金することはできないため、お宝を工事費用として使用することはできないことに注意せよ。
入力形式
入力は以下の形式で与えられる。
N
W
p_1
p_2
...
p_N
u_1
v_1
c_1
:
u_{N-1}
v_{N-1}
c_{N-1}
1
行目では、山の数
N
と工事費用の予算
W
が与えられる。
2
行目では、
i
番目の山に眠っているお宝の価値
p_i
が与えられる。
3
行目から
N+1
行目では、道の情報が与えられる。
2+i
行目は
i
番目の道の情報を表しており、山
u_i
と
v_i
の間に工事費用
c_i
の道があることを表す。
制約
1 \leq N \leq 10^2
1 \leq W \leq 10^5
1 \leq p_i \leq 10^9
1 \leq u_i \lt v_i \leq N
i \neq j
ならば
u_i \neq u_j
または
v_i \neq v_j
1 \leq c_i \leq 10^5
与えられる入力は全て整数である
出力形式
得られるお宝の価値の合計の最大値を
1
行に出力せよ。末尾の改行を忘れないこと。
入力例 1
3 10
6 8 2
1 2 3
2 3 8
出力例 1
14
山
1
または山
2
に降り立ち、山
1
と山
2
を結ぶ道を工事し、山
1
と山
2
にあるお宝を得るのが最適である。工事費用の予算は
10
であるので、ふたつの道を両方とも工事することはできない。
入力例 2
3 15
10 10 12
1 2 6
1 3 4
出力例 2
32
お宝を全て得ることができる。
入力例 3
5 1
4 8 8 2 10
1 2 3
2 4 5
2 5 2
1 3 7
出力例 3
10
予算が不足しており、どの道も工事できない場合もある。

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
#define inf (long long)-1e16
using namespace std;

struct edge {
  long long to, c;
  bool flg;
};

struct data {
  vector<long long> use, nuse;
};

long long n, w;
vector<long long> p;
vector<long long> cnt;
vector<vector<edge>> edges;

long long solve();
long long calc(long long now);
data dfs(long long now, vector<long long> &v);

int main() {
  cin >> n >> w;
  p.resize(n);
  edges.resize(n);
  for(int i = 0; i < n; ++i) cin >> p[i];
  for(int i = 0; i < n - 1; ++i) {
    int u, v, c;
    cin >> u >> v >> c;
    --u, --v;
    edges[u].push_back({v, c, 0});
    edges[v].push_back({u, c, 0});
  }
  cout << solve() << endl;
  return 0;
}

long long solve() {
  // calc children
  cnt.assign(n, -1);
  cnt[0] = 0;
  calc(0);
  vector<long long> v(w + 1, 0);
  auto f = [&](edge l, edge r) {
    return cnt[l.to] > cnt[r.to];
  };
  for(int i = 0; i < n; ++i)
    sort(edges[i].begin(), edges[i].end(), f);
  data resd = dfs(0, v);
  long long res = 0;
  for(int i = 0; i <= w; ++i)
    res = max({res, resd.use[i], resd.nuse[i]});
  return res;
}

long long calc(long long now) {
  for(int i = 0; i < edges[now].size(); ++i)
    if(cnt[edges[now][i].to] >= 0)
      edges[now][i].flg = 1;
    else {
      cnt[edges[now][i].to] = 0;
      cnt[now] += calc(edges[now][i].to);
    }
  return (cnt[now] += 1);
}

data dfs(long long now, vector<long long> &v) {
  data res;
  vector<long long> dummy(w + 1, 0);
  res.nuse = res.use = v;
  bool isfirst = 0;
  for(auto e : edges[now])
    if(!e.flg) {
      if(!isfirst) {
        isfirst = 1;
        data tmp = dfs(e.to, res.use);
        for(int i = 0; i <= w; ++i)
          res.nuse[i] =
              max({res.nuse[i], tmp.use[i], tmp.nuse[i]});
        for(int i = w; i >= e.c; --i)
          res.use[i] = max(tmp.use[i - e.c], res.use[i]);
        continue;
      }
      data tmp = dfs(e.to, res.use);
      for(int i = w; i >= e.c; --i)
        res.use[i] = max(tmp.use[i - e.c], res.use[i]);
      data ntmp = dfs(e.to, dummy);
      for(int i = 0; i <= w; ++i)
        res.nuse[i] =
            max({res.nuse[i], ntmp.use[i], ntmp.nuse[i]});
    }
  for(int i = 0; i <= w; ++i) res.use[i] += p[now];

  return res;
}
accuracy: 1
time_ms: 450
memory_kb: 179960
final_rank: 19

code_snippet: #include <bits/stdc++.h>
#define ll long long
#define INF (1LL << 60)
#define MOD 1000000007
#define EPS 1e-10
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define rrep(i,n) for(int i=(int)(n)-1;i>=0;--i)
#define srep(i,s,t) for(int i=(int)(s);i<(int)(t);++i)
#define each(a,b) for(auto& (a): (b))
#define all(v) (v).begin(),(v).end()
#define len(v) (int)(v).size()
#define zip(v) sort(all(v)),v.erase(unique(all(v)),v.end())
#define cmx(x,y) x=max(x,y)
#define cmn(x,y) x=min(x,y)
#define fi first
#define se second
#define pb push_back
#define show(x) cout<<#x<<" = "<<(x)<<endl
#define sar(a,n) {cout<<#a<<":";rep(pachico,n)cout<<" "<<a[pachico];cout<<endl;}

using namespace std;

template<typename S,typename T>auto&operator<<(ostream&o,pair<S,T>p){return o<<"{"<<p.fi<<","<<p.se<<"}";}
template<typename T>auto&operator<<(ostream&o,set<T>s){for(auto&e:s)o<<e<<" ";return o;}
template<typename S,typename T,typename U>
auto&operator<<(ostream&o,priority_queue<S,T,U>q){while(!q.empty())o<<q.top()<<" ",q.pop();return o;}
template<typename K,typename T>auto&operator<<(ostream&o,map<K,T>&m){for(auto&e:m)o<<e<<" ";return o;}
template<typename T>auto&operator<<(ostream&o,vector<T>v){for(auto&e:v)o<<e<<" ";return o;}
void ashow(){cout<<endl;}template<typename T,typename...A>void ashow(T t,A...a){cout<<t<<" ";ashow(a...);}
template<typename S,typename T,typename U>
struct TRI{S fi;T se;U th;TRI(){}TRI(S f,T s,U t):fi(f),se(s),th(t){}
bool operator<(const TRI&_)const{return(fi==_.fi)?((se==_.se)?(th<_.th):(se<_.se)):(fi<_.fi);}};
template<typename S,typename T,typename U>
auto&operator<<(ostream&o,TRI<S,T,U>&t){return o<<"{"<<t.fi<<","<<t.se<<","<<t.th<<"}";}

typedef pair<int, int> P;
typedef pair<ll, ll> pll;
typedef TRI<int, int, int> tri;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef vector<P> vp;
typedef vector<double> vd;
typedef vector<string> vs;

const int MAX_N = 105;

struct edge {
    int to, cost;
};

vector<edge> G[MAX_N];
int val[MAX_N], hc[MAX_N], cs[MAX_N];
ll ans;
int n, W;

int pre_dfs(int u, int p){
    int ret = 1, mx = 0;
    for(const edge& e : G[u]){
        if(e.to != p){
            int res = pre_dfs(e.to, u);
            cs[e.to] = e.cost;
            if(res > mx) mx = res, hc[u] = e.to;
            ret += res;
        }
    }
    return ret;
}

void dfs2(int u, int p, vector<ll>& dp){
    vector<ll> dp2(W+1, -INF);
    for(int i = cs[u]; i <= W; ++i){
        dp2[i] = dp[i-cs[u]] + val[u];
    }
    for(const edge& e : G[u]){
        if(e.to == p) continue;
        dfs2(e.to, u, dp2);
    }
    rep(i,W+1) dp[i] = max(dp[i], dp2[i]);
}

void dfs(int u, int p, const vector<ll>& dp, bool heavy){
    vector<ll> dp2(W+1, -INF);
    for(int i = cs[u]; i <= W; ++i){
        dp2[i] = dp[i-cs[u]] + val[u];
    }
    dp2[0] = val[u];
    for(const edge& e : G[u]){
        if(e.to == p || e.to == hc[u]) continue;
        dfs(e.to, u, dp2, false);
        dfs2(e.to, u, dp2);
    }
    rep(i,W+1) ans = max(ans, dp2[i]);
    if(hc[u] >= 0) dfs(hc[u], u, dp2, true);
}

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> n >> W;
    rep(i,n){
        cin >> val[i];
        hc[i] = -1;
    }
    rep(i,n-1){
        int u, v, c;
        cin >> u >> v >> c;
        --u, --v;
        G[u].pb((edge){v, c}), G[v].pb((edge){u, c});
    }
    pre_dfs(0, -1);
    cs[0] = W+1;
    vector<ll> dp(W+1, -INF);
    dfs(0, -1, dp, false);
    cout << ans << "\n";
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 62376
final_rank: 1

code_snippet: #include <bits/stdc++.h>
#define ll long long
#define INF (1LL << 60)
#define MOD 1000000007
#define EPS 1e-10
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define rrep(i,n) for(int i=(int)(n)-1;i>=0;--i)
#define srep(i,s,t) for(int i=(int)(s);i<(int)(t);++i)
#define each(a,b) for(auto& (a): (b))
#define all(v) (v).begin(),(v).end()
#define len(v) (int)(v).size()
#define zip(v) sort(all(v)),v.erase(unique(all(v)),v.end())
#define cmx(x,y) x=max(x,y)
#define cmn(x,y) x=min(x,y)
#define fi first
#define se second
#define pb push_back
#define show(x) cout<<#x<<" = "<<(x)<<endl
#define sar(a,n) {cout<<#a<<":";rep(pachico,n)cout<<" "<<a[pachico];cout<<endl;}

using namespace std;

template<typename S,typename T>auto&operator<<(ostream&o,pair<S,T>p){return o<<"{"<<p.fi<<","<<p.se<<"}";}
template<typename T>auto&operator<<(ostream&o,set<T>s){for(auto&e:s)o<<e<<" ";return o;}
template<typename S,typename T,typename U>
auto&operator<<(ostream&o,priority_queue<S,T,U>q){while(!q.empty())o<<q.top()<<" ",q.pop();return o;}
template<typename K,typename T>auto&operator<<(ostream&o,map<K,T>&m){for(auto&e:m)o<<e<<" ";return o;}
template<typename T>auto&operator<<(ostream&o,vector<T>v){for(auto&e:v)o<<e<<" ";return o;}
void ashow(){cout<<endl;}template<typename T,typename...A>void ashow(T t,A...a){cout<<t<<" ";ashow(a...);}
template<typename S,typename T,typename U>
struct TRI{S fi;T se;U th;TRI(){}TRI(S f,T s,U t):fi(f),se(s),th(t){}
bool operator<(const TRI&_)const{return(fi==_.fi)?((se==_.se)?(th<_.th):(se<_.se)):(fi<_.fi);}};
template<typename S,typename T,typename U>
auto&operator<<(ostream&o,TRI<S,T,U>&t){return o<<"{"<<t.fi<<","<<t.se<<","<<t.th<<"}";}

typedef pair<int, int> P;
typedef pair<ll, ll> pll;
typedef TRI<int, int, int> tri;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef vector<P> vp;
typedef vector<double> vd;
typedef vector<string> vs;

const int MAX_N = 105;

struct edge {
    int to, cost;
};

vector<edge> G[MAX_N];
vector<ll> kp;
int val[MAX_N], hc[MAX_N], cs[MAX_N];
ll ans;
int n, W;

int pre_dfs(int u, int p){
    int ret = 1, mx = 0;
    for(const edge& e : G[u]){
        if(e.to != p){
            int res = pre_dfs(e.to, u);
            if(res > mx) mx = res, hc[u] = e.to, cs[u] = e.cost;
            ret += res;
        }
    }
    return ret;
}

vector<ll> dfs(int u, int p, const vector<ll>& dp, bool flag){
    auto dp2 = dp;
    if(hc[u] >= 0){
        // ナップサックテーブルを更新
        const vector<ll> dp3 = dfs(hc[u], u, dp2, flag);
        for(int i = cs[u]; i <= W; ++i){
            cmx(dp2[i], dp3[i-cs[u]]);
        }
    }
    for(const edge& e : G[u]){
        if(e.to != p && e.to != hc[u]){
            if(flag) dfs(e.to, u, kp, true);
            const vector<ll> dp3 = dfs(e.to, u, dp2, false);
            for(int i = e.cost; i <= W; ++i){
                cmx(dp2[i], dp3[i-e.cost]);
            }
        }
    }
    for(int i = 0; i <= W; ++i){
        dp2[i] += val[u];
        if(flag) cmx(ans, dp2[i]);
    }
    return dp2;
}

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> n >> W;
    rep(i,n){
        cin >> val[i];
        hc[i] = -1;
    }
    rep(i,n-1){
        int u, v, c;
        cin >> u >> v >> c;
        --u, --v;
        G[u].pb((edge){v, c}), G[v].pb((edge){u, c});
    }
    pre_dfs(0, -1);
    kp.resize(W+1, -INF), kp[0] = 0;
    dfs(0, -1, kp, true);
    cout << ans << "\n";
    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 62388
final_rank: 10

code_snippet: #include <bits/stdc++.h>
#define ll long long
#define INF (1LL << 60)
#define MOD 1000000007
#define EPS 1e-10
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define rrep(i,n) for(int i=(int)(n)-1;i>=0;--i)
#define srep(i,s,t) for(int i=(int)(s);i<(int)(t);++i)
#define each(a,b) for(auto& (a): (b))
#define all(v) (v).begin(),(v).end()
#define len(v) (int)(v).size()
#define zip(v) sort(all(v)),v.erase(unique(all(v)),v.end())
#define cmx(x,y) x=max(x,y)
#define cmn(x,y) x=min(x,y)
#define fi first
#define se second
#define pb push_back
#define show(x) cout<<#x<<" = "<<(x)<<endl
#define sar(a,n) {cout<<#a<<":";rep(pachico,n)cout<<" "<<a[pachico];cout<<endl;}

using namespace std;

template<typename S,typename T>auto&operator<<(ostream&o,pair<S,T>p){return o<<"{"<<p.fi<<","<<p.se<<"}";}
template<typename T>auto&operator<<(ostream&o,set<T>s){for(auto&e:s)o<<e<<" ";return o;}
template<typename S,typename T,typename U>
auto&operator<<(ostream&o,priority_queue<S,T,U>q){while(!q.empty())o<<q.top()<<" ",q.pop();return o;}
template<typename K,typename T>auto&operator<<(ostream&o,map<K,T>&m){for(auto&e:m)o<<e<<" ";return o;}
template<typename T>auto&operator<<(ostream&o,vector<T>v){for(auto&e:v)o<<e<<" ";return o;}
void ashow(){cout<<endl;}template<typename T,typename...A>void ashow(T t,A...a){cout<<t<<" ";ashow(a...);}
template<typename S,typename T,typename U>
struct TRI{S fi;T se;U th;TRI(){}TRI(S f,T s,U t):fi(f),se(s),th(t){}
bool operator<(const TRI&_)const{return(fi==_.fi)?((se==_.se)?(th<_.th):(se<_.se)):(fi<_.fi);}};
template<typename S,typename T,typename U>
auto&operator<<(ostream&o,TRI<S,T,U>&t){return o<<"{"<<t.fi<<","<<t.se<<","<<t.th<<"}";}

typedef pair<int, int> P;
typedef pair<ll, ll> pll;
typedef TRI<int, int, int> tri;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef vector<P> vp;
typedef vector<double> vd;
typedef vector<string> vs;

const int MAX_N = 105;

struct edge {
    int to, cost;
};

vector<edge> G[MAX_N];
vector<ll> kp;
int val[MAX_N], hc[MAX_N], cs[MAX_N];
ll ans;
int n, W;

int pre_dfs(int u, int p){
    int ret = 1, mx = 0;
    for(const edge& e : G[u]){
        if(e.to != p){
            int res = pre_dfs(e.to, u);
            cs[e.to] = e.cost;
            if(res > mx) mx = res, hc[u] = e.to;
            ret += res;
        }
    }
    return ret;
}

void dfs(int u, int p, const vector<ll>& dp, vector<ll>& dp2, bool flag){
    dp2 = dp;
    if(hc[u] >= 0){
        vector<ll> dp3;
        dfs(hc[u], u, dp2, dp3, flag);
        for(int i = cs[hc[u]]; i <= W; ++i){
            cmx(dp2[i], dp3[i-cs[hc[u]]]);
        }
    }
    for(const edge& e : G[u]){
        if(e.to != p && e.to != hc[u]){
            vector<ll> dp3;
            if(flag) dfs(e.to, u, kp, dp3, true);
            dfs(e.to, u, dp2, dp3, false);
            for(int i = cs[e.to]; i <= W; ++i){
                cmx(dp2[i], dp3[i-cs[e.to]]);
            }
        }
    }
    for(int i = 0; i <= W; ++i){
        dp2[i] += val[u];
        if(flag) cmx(ans, dp2[i]);
    }
}

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> n >> W;
    rep(i,n){
        cin >> val[i];
        hc[i] = -1;
    }
    rep(i,n-1){
        int u, v, c;
        cin >> u >> v >> c;
        --u, --v;
        G[u].pb((edge){v, c}), G[v].pb((edge){u, c});
    }
    pre_dfs(0, -1);
    kp.resize(W+1, -INF), kp[0] = 0;
    vector<ll> dp;
    dfs(0, -1, kp, dp, true);
    cout << ans << "\n";
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 62536
final_rank: 8

code_snippet: #include <bits/stdc++.h>
#define ll long long
#define INF (1LL << 60)
#define MOD 1000000007
#define EPS 1e-10
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define rrep(i,n) for(int i=(int)(n)-1;i>=0;--i)
#define srep(i,s,t) for(int i=(int)(s);i<(int)(t);++i)
#define each(a,b) for(auto& (a): (b))
#define all(v) (v).begin(),(v).end()
#define len(v) (int)(v).size()
#define zip(v) sort(all(v)),v.erase(unique(all(v)),v.end())
#define cmx(x,y) x=max(x,y)
#define cmn(x,y) x=min(x,y)
#define fi first
#define se second
#define pb push_back
#define show(x) cout<<#x<<" = "<<(x)<<endl
#define sar(a,n) {cout<<#a<<":";rep(pachico,n)cout<<" "<<a[pachico];cout<<endl;}

using namespace std;

template<typename S,typename T>auto&operator<<(ostream&o,pair<S,T>p){return o<<"{"<<p.fi<<","<<p.se<<"}";}
template<typename T>auto&operator<<(ostream&o,set<T>s){for(auto&e:s)o<<e<<" ";return o;}
template<typename S,typename T,typename U>
auto&operator<<(ostream&o,priority_queue<S,T,U>q){while(!q.empty())o<<q.top()<<" ",q.pop();return o;}
template<typename K,typename T>auto&operator<<(ostream&o,map<K,T>&m){for(auto&e:m)o<<e<<" ";return o;}
template<typename T>auto&operator<<(ostream&o,vector<T>v){for(auto&e:v)o<<e<<" ";return o;}
void ashow(){cout<<endl;}template<typename T,typename...A>void ashow(T t,A...a){cout<<t<<" ";ashow(a...);}
template<typename S,typename T,typename U>
struct TRI{S fi;T se;U th;TRI(){}TRI(S f,T s,U t):fi(f),se(s),th(t){}
bool operator<(const TRI&_)const{return(fi==_.fi)?((se==_.se)?(th<_.th):(se<_.se)):(fi<_.fi);}};
template<typename S,typename T,typename U>
auto&operator<<(ostream&o,TRI<S,T,U>&t){return o<<"{"<<t.fi<<","<<t.se<<","<<t.th<<"}";}

typedef pair<int, int> P;
typedef pair<ll, ll> pll;
typedef TRI<int, int, int> tri;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef vector<P> vp;
typedef vector<double> vd;
typedef vector<string> vs;

const int MAX_N = 105;

struct edge {
    int to, cost;
};

vector<edge> G[MAX_N];
vector<ll> kp;
int val[MAX_N], hc[MAX_N], cs[MAX_N];
ll ans;
int n, W;

int pre_dfs(int u, int p){
    int ret = 1, mx = 0;
    for(const edge& e : G[u]){
        if(e.to != p){
            int res = pre_dfs(e.to, u);
            cs[e.to] = e.cost;
            if(res > mx) mx = res, hc[u] = e.to;
            ret += res;
        }
    }
    return ret;
}

vector<ll> dfs(int u, int p, const vector<ll>& dp, bool flag){
    auto dp2 = dp;
    if(hc[u] >= 0){
        const vector<ll> dp3 = dfs(hc[u], u, dp2, flag);
        for(int i = cs[hc[u]]; i <= W; ++i){
            cmx(dp2[i], dp3[i-cs[hc[u]]]);
        }
    }
    for(const edge& e : G[u]){
        if(e.to != p && e.to != hc[u]){
            if(flag) dfs(e.to, u, kp, true);
            const vector<ll> dp3 = dfs(e.to, u, dp2, false);
            for(int i = cs[e.to]; i <= W; ++i){
                cmx(dp2[i], dp3[i-cs[e.to]]);
            }
        }
    }
    for(int i = 0; i <= W; ++i){
        dp2[i] += val[u];
        if(flag) cmx(ans, dp2[i]);
    }
    return dp2;
}

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> n >> W;
    rep(i,n){
        cin >> val[i];
        hc[i] = -1;
    }
    rep(i,n-1){
        int u, v, c;
        cin >> u >> v >> c;
        --u, --v;
        G[u].pb((edge){v, c}), G[v].pb((edge){u, c});
    }
    pre_dfs(0, -1);
    kp.resize(W+1, -INF), kp[0] = 0;
    dfs(0, -1, kp, true);
    cout << ans << "\n";
    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 62376
final_rank: 9

code_snippet: #include <bits/stdc++.h>
#define ll long long
#define INF (1LL << 60)
#define MOD 1000000007
#define EPS 1e-10
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define rrep(i,n) for(int i=(int)(n)-1;i>=0;--i)
#define srep(i,s,t) for(int i=(int)(s);i<(int)(t);++i)
#define each(a,b) for(auto& (a): (b))
#define all(v) (v).begin(),(v).end()
#define len(v) (int)(v).size()
#define zip(v) sort(all(v)),v.erase(unique(all(v)),v.end())
#define cmx(x,y) x=max(x,y)
#define cmn(x,y) x=min(x,y)
#define fi first
#define se second
#define pb push_back
#define show(x) cout<<#x<<" = "<<(x)<<endl
#define sar(a,n) {cout<<#a<<":";rep(pachico,n)cout<<" "<<a[pachico];cout<<endl;}

using namespace std;

template<typename S,typename T>auto&operator<<(ostream&o,pair<S,T>p){return o<<"{"<<p.fi<<","<<p.se<<"}";}
template<typename T>auto&operator<<(ostream&o,set<T>s){for(auto&e:s)o<<e<<" ";return o;}
template<typename S,typename T,typename U>
auto&operator<<(ostream&o,priority_queue<S,T,U>q){while(!q.empty())o<<q.top()<<" ",q.pop();return o;}
template<typename K,typename T>auto&operator<<(ostream&o,map<K,T>&m){for(auto&e:m)o<<e<<" ";return o;}
template<typename T>auto&operator<<(ostream&o,vector<T>v){for(auto&e:v)o<<e<<" ";return o;}
void ashow(){cout<<endl;}template<typename T,typename...A>void ashow(T t,A...a){cout<<t<<" ";ashow(a...);}
template<typename S,typename T,typename U>
struct TRI{S fi;T se;U th;TRI(){}TRI(S f,T s,U t):fi(f),se(s),th(t){}
bool operator<(const TRI&_)const{return(fi==_.fi)?((se==_.se)?(th<_.th):(se<_.se)):(fi<_.fi);}};
template<typename S,typename T,typename U>
auto&operator<<(ostream&o,TRI<S,T,U>&t){return o<<"{"<<t.fi<<","<<t.se<<","<<t.th<<"}";}

typedef pair<int, int> P;
typedef pair<ll, ll> pll;
typedef TRI<int, int, int> tri;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef vector<P> vp;
typedef vector<double> vd;
typedef vector<string> vs;

const int MAX_N = 105;

struct edge {
    int to, cost;
};

vector<edge> G[MAX_N];
int val[MAX_N], hc[MAX_N], cs[MAX_N];
ll ans;
int n, W;

int pre_dfs(int u, int p){
    int ret = 1, mx = 0;
    for(const edge& e : G[u]){
        if(e.to != p){
            int res = pre_dfs(e.to, u);
            if(res > mx){
                mx = res, hc[u] = e.to, cs[u] = e.cost;
            }
            ret += res;
        }
    }
    return ret;
}

void dfs2(int u, int p, int cost, vector<ll>& dp){
    vector<ll> dp2(W+1, -INF);
    for(int i = cost; i <= W; ++i){
        dp2[i] = dp[i-cost] + val[u];
    }
    for(const edge& e : G[u]){
        if(e.to == p) continue;
        dfs2(e.to, u, e.cost, dp2);
    }
    rep(i,W+1) dp[i] = max(dp[i], dp2[i]);
}

void dfs(int u, int p, int cost, const vector<ll>& dp, bool heavy){
    vector<ll> dp2(W+1, -INF);
    for(int i = cost; i <= W; ++i){
        dp2[i] = dp[i-cost] + val[u];
    }
    dp2[0] = val[u];
    for(const edge& e : G[u]){
        if(e.to == p || e.to == hc[u]) continue;
        dfs(e.to, u, e.cost, dp2, false);
        dfs2(e.to, u, e.cost, dp2);
    }
    rep(i,W+1) ans = max(ans, dp2[i]);
    if(hc[u] >= 0) dfs(hc[u], u, cs[u], dp2, true);
}

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> n >> W;
    rep(i,n){
        cin >> val[i];
        hc[i] = -1;
    }
    rep(i,n-1){
        int u, v, c;
        cin >> u >> v >> c;
        --u, --v;
        G[u].pb((edge){v, c}), G[v].pb((edge){u, c});
    }
    pre_dfs(0, -1);
    vector<ll> dp(W+1, -INF);
    dfs(0, -1, 0, dp, false);
    cout << ans << "\n";
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 62484
final_rank: 3

code_snippet: #include <bits/stdc++.h>
#define ll long long
#define INF (1LL << 60)
#define MOD 1000000007
#define EPS 1e-10
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define rrep(i,n) for(int i=(int)(n)-1;i>=0;--i)
#define srep(i,s,t) for(int i=(int)(s);i<(int)(t);++i)
#define each(a,b) for(auto& (a): (b))
#define all(v) (v).begin(),(v).end()
#define len(v) (int)(v).size()
#define zip(v) sort(all(v)),v.erase(unique(all(v)),v.end())
#define cmx(x,y) x=max(x,y)
#define cmn(x,y) x=min(x,y)
#define fi first
#define se second
#define pb push_back
#define show(x) cout<<#x<<" = "<<(x)<<endl
#define sar(a,n) {cout<<#a<<":";rep(pachico,n)cout<<" "<<a[pachico];cout<<endl;}

using namespace std;

template<typename S,typename T>auto&operator<<(ostream&o,pair<S,T>p){return o<<"{"<<p.fi<<","<<p.se<<"}";}
template<typename T>auto&operator<<(ostream&o,set<T>s){for(auto&e:s)o<<e<<" ";return o;}
template<typename S,typename T,typename U>
auto&operator<<(ostream&o,priority_queue<S,T,U>q){while(!q.empty())o<<q.top()<<" ",q.pop();return o;}
template<typename K,typename T>auto&operator<<(ostream&o,map<K,T>&m){for(auto&e:m)o<<e<<" ";return o;}
template<typename T>auto&operator<<(ostream&o,vector<T>v){for(auto&e:v)o<<e<<" ";return o;}
void ashow(){cout<<endl;}template<typename T,typename...A>void ashow(T t,A...a){cout<<t<<" ";ashow(a...);}
template<typename S,typename T,typename U>
struct TRI{S fi;T se;U th;TRI(){}TRI(S f,T s,U t):fi(f),se(s),th(t){}
bool operator<(const TRI&_)const{return(fi==_.fi)?((se==_.se)?(th<_.th):(se<_.se)):(fi<_.fi);}};
template<typename S,typename T,typename U>
auto&operator<<(ostream&o,TRI<S,T,U>&t){return o<<"{"<<t.fi<<","<<t.se<<","<<t.th<<"}";}

typedef pair<int, int> P;
typedef pair<ll, ll> pll;
typedef TRI<int, int, int> tri;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef vector<P> vp;
typedef vector<double> vd;
typedef vector<string> vs;

const int MAX_N = 105;

struct edge {
    int to, cost;
};

vector<edge> G[MAX_N];
int val[MAX_N], hc[MAX_N], cs[MAX_N];
ll ans;
int n, W;

int pre_dfs(int u, int p){
    int ret = 1, mx = 0;
    for(const edge& e : G[u]){
        if(e.to != p){
            int res = pre_dfs(e.to, u);
            if(res > mx){
                mx = res, hc[u] = e.to, cs[u] = e.cost;
            }
            ret += res;
        }
    }
    return ret;
}

void dfs2(int u, int p, int cost, vector<ll>& dp){
    vector<ll> dp2(W+1, -INF);
    for(int i = cost; i <= W; ++i){
        dp2[i] = dp[i-cost] + val[u];
    }
    for(const edge& e : G[u]){
        if(e.to == p) continue;
        dfs2(e.to, u, e.cost, dp2);
    }
    rep(i,W+1) dp[i] = max(dp[i], dp2[i]);
}

// dp には常にその頂点と連結していけるところでのナップサック結果が入る
void dfs(int u, int p, int cost, const vector<ll>& dp, bool heavy){
    vector<ll> dp2(W+1, -INF);
    for(int i = cost; i <= W; ++i){
        dp2[i] = dp[i-cost] + val[u];
    }
    dp2[0] = val[u];
    for(const edge& e : G[u]){
        if(e.to == p || e.to == hc[u]) continue;
        dfs(e.to, u, e.cost, dp2, false);
        dfs2(e.to, u, e.cost, dp2);
    }
    rep(i,W+1) ans = max(ans, dp2[i]);
    if(hc[u] >= 0){
        dfs(hc[u], u, cs[u], dp2, true);
    }
}

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> n >> W;
    rep(i,n){
        cin >> val[i];
        hc[i] = -1;
    }
    rep(i,n-1){
        int u, v, c;
        cin >> u >> v >> c;
        --u, --v;
        G[u].pb((edge){v, c}), G[v].pb((edge){u, c});
    }
    pre_dfs(0, -1);
    vector<ll> dp(W+1, -INF);
    dfs(0, -1, 0, dp, false);
    cout << ans << "\n";
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 62448
final_rank: 2

code_snippet: #include <bits/stdc++.h>
#define ll long long
#define INF (1LL << 60)
#define MOD 1000000007
#define EPS 1e-10
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define rrep(i,n) for(int i=(int)(n)-1;i>=0;--i)
#define srep(i,s,t) for(int i=(int)(s);i<(int)(t);++i)
#define each(a,b) for(auto& (a): (b))
#define all(v) (v).begin(),(v).end()
#define len(v) (int)(v).size()
#define zip(v) sort(all(v)),v.erase(unique(all(v)),v.end())
#define cmx(x,y) x=max(x,y)
#define cmn(x,y) x=min(x,y)
#define fi first
#define se second
#define pb push_back
#define show(x) cout<<#x<<" = "<<(x)<<endl
#define sar(a,n) {cout<<#a<<":";rep(pachico,n)cout<<" "<<a[pachico];cout<<endl;}

using namespace std;

template<typename S,typename T>auto&operator<<(ostream&o,pair<S,T>p){return o<<"{"<<p.fi<<","<<p.se<<"}";}
template<typename T>auto&operator<<(ostream&o,set<T>s){for(auto&e:s)o<<e<<" ";return o;}
template<typename S,typename T,typename U>
auto&operator<<(ostream&o,priority_queue<S,T,U>q){while(!q.empty())o<<q.top()<<" ",q.pop();return o;}
template<typename K,typename T>auto&operator<<(ostream&o,map<K,T>&m){for(auto&e:m)o<<e<<" ";return o;}
template<typename T>auto&operator<<(ostream&o,vector<T>v){for(auto&e:v)o<<e<<" ";return o;}
void ashow(){cout<<endl;}template<typename T,typename...A>void ashow(T t,A...a){cout<<t<<" ";ashow(a...);}
template<typename S,typename T,typename U>
struct TRI{S fi;T se;U th;TRI(){}TRI(S f,T s,U t):fi(f),se(s),th(t){}
bool operator<(const TRI&_)const{return(fi==_.fi)?((se==_.se)?(th<_.th):(se<_.se)):(fi<_.fi);}};
template<typename S,typename T,typename U>
auto&operator<<(ostream&o,TRI<S,T,U>&t){return o<<"{"<<t.fi<<","<<t.se<<","<<t.th<<"}";}

typedef pair<int, int> P;
typedef pair<ll, ll> pll;
typedef TRI<int, int, int> tri;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef vector<P> vp;
typedef vector<double> vd;
typedef vector<string> vs;

const int MAX_N = 105;

struct edge {
    int to, cost;
};

vector<edge> G[MAX_N];
int val[MAX_N], hc[MAX_N], cs[MAX_N];
ll ans;
int n, W;

int pre_dfs(int u, int p){
    int ret = 1, mx = 0;
    for(const edge& e : G[u]){
        if(e.to != p){
            int res = pre_dfs(e.to, u);
            if(res > mx){
                mx = res, hc[u] = e.to, cs[u] = e.cost;
            }
            ret += res;
        }
    }
    return ret;
}

void dfs2(int u, int p, int cost, vector<ll>& dp){
    vector<ll> dp2(W+1, -INF);
    for(int i = cost; i <= W; ++i){
        dp2[i] = dp[i-cost] + val[u];
    }
    for(const edge& e : G[u]){
        if(e.to == p) continue;
        dfs2(e.to, u, e.cost, dp2);
    }
    rep(i,W+1) dp[i] = max(dp[i], dp2[i]);
}

// dp には常にその頂点と連結していけるところでのナップサック結果が入る
void dfs(int u, int p, int cost, vector<ll>& dp, bool heavy){
    vector<ll> dp2(W+1, -INF);
    for(int i = cost; i <= W; ++i){
        dp2[i] = dp[i-cost] + val[u];
    }
    dp2[0] = val[u];
    for(const edge& e : G[u]){
        if(e.to == p || e.to == hc[u]) continue;
        vector<ll> dp3 = dp2;
        dfs(e.to, u, e.cost, dp3, false);
        dfs2(e.to, u, e.cost, dp2);
    }
    rep(i,W+1) ans = max(ans, dp2[i]);
    if(hc[u] >= 0){
        dfs(hc[u], u, cs[u], dp2, true);
    }
}

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> n >> W;
    rep(i,n){
        cin >> val[i];
        hc[i] = -1;
    }
    rep(i,n-1){
        int u, v, c;
        cin >> u >> v >> c;
        --u, --v;
        G[u].pb((edge){v, c}), G[v].pb((edge){u, c});
    }
    pre_dfs(0, -1);
    vector<ll> dp(W+1, -INF);
    dfs(0, -1, 0, dp, false);
    cout << ans << "\n";
    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 62460
final_rank: 13

code_snippet: #include <bits/stdc++.h>
#define ll long long
#define INF (1LL << 60)
#define MOD 1000000007
#define EPS 1e-10
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define rrep(i,n) for(int i=(int)(n)-1;i>=0;--i)
#define srep(i,s,t) for(int i=(int)(s);i<(int)(t);++i)
#define each(a,b) for(auto& (a): (b))
#define all(v) (v).begin(),(v).end()
#define len(v) (int)(v).size()
#define zip(v) sort(all(v)),v.erase(unique(all(v)),v.end())
#define cmx(x,y) x=max(x,y)
#define cmn(x,y) x=min(x,y)
#define fi first
#define se second
#define pb push_back
#define show(x) cout<<#x<<" = "<<(x)<<endl
#define sar(a,n) {cout<<#a<<":";rep(pachico,n)cout<<" "<<a[pachico];cout<<endl;}

using namespace std;

template<typename S,typename T>auto&operator<<(ostream&o,pair<S,T>p){return o<<"{"<<p.fi<<","<<p.se<<"}";}
template<typename T>auto&operator<<(ostream&o,set<T>s){for(auto&e:s)o<<e<<" ";return o;}
template<typename S,typename T,typename U>
auto&operator<<(ostream&o,priority_queue<S,T,U>q){while(!q.empty())o<<q.top()<<" ",q.pop();return o;}
template<typename K,typename T>auto&operator<<(ostream&o,map<K,T>&m){for(auto&e:m)o<<e<<" ";return o;}
template<typename T>auto&operator<<(ostream&o,vector<T>v){for(auto&e:v)o<<e<<" ";return o;}
void ashow(){cout<<endl;}template<typename T,typename...A>void ashow(T t,A...a){cout<<t<<" ";ashow(a...);}
template<typename S,typename T,typename U>
struct TRI{S fi;T se;U th;TRI(){}TRI(S f,T s,U t):fi(f),se(s),th(t){}
bool operator<(const TRI&_)const{return(fi==_.fi)?((se==_.se)?(th<_.th):(se<_.se)):(fi<_.fi);}};
template<typename S,typename T,typename U>
auto&operator<<(ostream&o,TRI<S,T,U>&t){return o<<"{"<<t.fi<<","<<t.se<<","<<t.th<<"}";}

typedef pair<int, int> P;
typedef pair<ll, ll> pll;
typedef TRI<int, int, int> tri;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef vector<P> vp;
typedef vector<double> vd;
typedef vector<string> vs;

const int MAX_N = 105;

struct edge {
    int to, cost;
};

vector<edge> G[MAX_N];
int val[MAX_N], hc[MAX_N], cs[MAX_N];
ll ans;
int n, W;

int pre_dfs(int u, int p){
    int ret = 1, mx = 0;
    for(const edge& e : G[u]){
        if(e.to != p){
            int res = pre_dfs(e.to, u);
            if(res > mx){
                mx = res, hc[u] = e.to, cs[u] = e.cost;
            }
            ret += res;
        }
    }
    return ret;
}

void dfs2(int u, int p, int cost, vector<ll>& dp){
    vector<ll> dp2(W+1, -INF);
    for(int i = cost; i <= W; ++i){
        dp2[i] = dp[i-cost] + val[u];
    }
    for(const edge& e : G[u]){
        if(e.to == p) continue;
        dfs2(e.to, u, e.cost, dp2);
    }
    rep(i,W+1) dp[i] = max(dp[i], dp2[i]);
}

void dfs(int u, int p, int cost, vector<ll>& dp){
    vector<ll> dp2(W+1, -INF);
    dp2[0] = val[u];
    for(const edge& e : G[u]){
        if(e.to == p) continue;
        vector<ll> dp3(W+1, -INF); // 1 個下からスタート
        dfs(e.to, u, e.cost, dp3);
        dfs2(e.to, u, e.cost, dp2);
    }
    rep(i,W+1) ans = max(ans, dp2[i]);
}

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> n >> W;
    rep(i,n){
        cin >> val[i];
        hc[i] = -1;
    }
    rep(i,n-1){
        int u, v, c;
        cin >> u >> v >> c;
        --u, --v;
        G[u].pb((edge){v, c}), G[v].pb((edge){u, c});
    }
    // pre_dfs(0, -1);
    vector<ll> dp(W+1, -INF);
    dfs(0, -1, 0, dp);
    cout << ans << "\n";
    return 0;
}
accuracy: 1
time_ms: 970
memory_kb: 120220
final_rank: 17

code_snippet: #include <bits/stdc++.h>
#define ll long long
#define INF (1LL << 60)
#define MOD 1000000007
#define EPS 1e-10
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define rrep(i,n) for(int i=(int)(n)-1;i>=0;--i)
#define srep(i,s,t) for(int i=(int)(s);i<(int)(t);++i)
#define each(a,b) for(auto& (a): (b))
#define all(v) (v).begin(),(v).end()
#define len(v) (int)(v).size()
#define zip(v) sort(all(v)),v.erase(unique(all(v)),v.end())
#define cmx(x,y) x=max(x,y)
#define cmn(x,y) x=min(x,y)
#define fi first
#define se second
#define pb push_back
#define show(x) cout<<#x<<" = "<<(x)<<endl
#define sar(a,n) {cout<<#a<<":";rep(pachico,n)cout<<" "<<a[pachico];cout<<endl;}

using namespace std;

template<typename S,typename T>auto&operator<<(ostream&o,pair<S,T>p){return o<<"{"<<p.fi<<","<<p.se<<"}";}
template<typename T>auto&operator<<(ostream&o,set<T>s){for(auto&e:s)o<<e<<" ";return o;}
template<typename S,typename T,typename U>
auto&operator<<(ostream&o,priority_queue<S,T,U>q){while(!q.empty())o<<q.top()<<" ",q.pop();return o;}
template<typename K,typename T>auto&operator<<(ostream&o,map<K,T>&m){for(auto&e:m)o<<e<<" ";return o;}
template<typename T>auto&operator<<(ostream&o,vector<T>v){for(auto&e:v)o<<e<<" ";return o;}
void ashow(){cout<<endl;}template<typename T,typename...A>void ashow(T t,A...a){cout<<t<<" ";ashow(a...);}
template<typename S,typename T,typename U>
struct TRI{S fi;T se;U th;TRI(){}TRI(S f,T s,U t):fi(f),se(s),th(t){}
bool operator<(const TRI&_)const{return(fi==_.fi)?((se==_.se)?(th<_.th):(se<_.se)):(fi<_.fi);}};
template<typename S,typename T,typename U>
auto&operator<<(ostream&o,TRI<S,T,U>&t){return o<<"{"<<t.fi<<","<<t.se<<","<<t.th<<"}";}

typedef pair<int, int> P;
typedef pair<ll, ll> pll;
typedef TRI<int, int, int> tri;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef vector<P> vp;
typedef vector<double> vd;
typedef vector<string> vs;

const int MAX_N = 105;

struct edge {
    int to, cost;
};

vector<edge> G[MAX_N];
int val[MAX_N], hc[MAX_N], cs[MAX_N];
ll ans;
int n, W;

int pre_dfs(int u, int p){
    int ret = 1, mx = 0;
    for(const edge& e : G[u]){
        if(e.to != p){
            int res = pre_dfs(e.to, u);
            if(res > mx){
                mx = res, hc[u] = e.to, cs[u] = e.cost;
            }
            ret += res;
        }
    }
    return ret;
}

void dfs2(int u, int p, int cost, vector<ll>& dp){
    vector<ll> dp2(W+1, -INF);
    for(int i = cost; i <= W; ++i){
        dp2[i] = dp[i-cost] + val[u];
    }
    for(const edge& e : G[u]){
        if(e.to == p) continue;
        dfs2(e.to, u, e.cost, dp2);
    }
    rep(i,W+1) dp[i] = max(dp[i], dp2[i]);
}

void dfs(int u, int p, int cost, vector<ll>& dp, bool heavy){
    vector<ll> dp2(W+1, -INF);
    dp2[0] = val[u];
    if(heavy){
        for(int i = cost; i <= W; ++i){
            dp2[i] = dp[i-cost] + val[u];
        }
    }
    for(const edge& e : G[u]){
        if(e.to == p || e.to == hc[u]) continue;
        vector<ll> dp3(W+1, -INF);
        dfs(e.to, u, e.cost, dp3, false);
        dfs2(e.to, u, e.cost, dp2);
    }
    rep(i,W+1) ans = max(ans, dp2[i]);
    if(hc[u] >= 0){
        dfs(hc[u], u, cs[u], dp2, true);
    }
}

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> n >> W;
    rep(i,n){
        cin >> val[i];
        hc[i] = -1;
    }
    rep(i,n-1){
        int u, v, c;
        cin >> u >> v >> c;
        --u, --v;
        G[u].pb((edge){v, c}), G[v].pb((edge){u, c});
    }
    pre_dfs(0, -1);
    vector<ll> dp(W+1, -INF);
    dfs(0, -1, 0, dp, false);
    cout << ans << "\n";
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 62448
final_rank: 6

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
#include <utility>
#include <queue>
#include <set>
#include <map>
#include <deque>
#include <iomanip>
#include <cstdio>
#include <stack>
#include <numeric>

using namespace std;
typedef  long long ll;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<VI> VVI;
#define  MP make_pair
#define  PB push_back
#define inf 1L<<60
#define mod 1000000007
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define int long long
int n,w;
vector<vector<pair<int,int> > >  g;
vector<int> nex;
vector<ll> p;
ll cost[200][200];
ll ans;

int dfsssss(int id,int pre){
    int ret = 1, mx = 0;
    for(auto x:g[id]){
        if(x.first !=pre){
            int res = dfsssss(x.first,id);
            if(mx < res){
                nex[id] = x.first;
                mx = res;
            }
            ret += res;
        }
    }
    return ret;
}

void dfs2(int id,int pre,vector<ll>&dp){
    vector<ll> dp3(w+1,-inf);
    for(int i=cost[id][pre];i<=w;i++){
        dp3[i] = dp[i-cost[id][pre]] + p[id];
    }
    for(auto x:g[id]){
        if(x.first == pre)continue;
        dfs2(x.first,id,dp3);
    }
    // dp3 にはテーブル dp を初期値として id を取る + id 内の部分木で更新を行なった後の姿が入る
    rep(i,w+1){
        dp[i] = max(dp[i], dp3[i]);
    }
}

void dfs(int id,int pre,vector<ll>&dp){
    vector<ll> dp3(w+1,-inf);
    dp3[0] = p[id];
    if(pre!=-1&&nex[pre]==id){
        for(int i=cost[id][pre];i<=w;i++){
            dp3[i] = dp[i-cost[id][pre]] + p[id];
        }
    }
    for(auto x:g[id]){
        if(x.first == pre)continue;
        if(x.first == nex[id])continue;
        vector<ll> dp4(w+1,-inf);
        dfs(x.first,id,dp4);
        dfs2(x.first,id,dp3);
    }
    rep(i,w+1) ans = max(ans,dp3[i]);
    if(nex[id]!=-1){
        dfs(nex[id],id,dp3);
    }
}

signed main(){

    cin >> n >> w;
    p.resize(n);
    rep(i,n)cin >> p[i];
    g.resize(n);
    nex.resize(n,-1);
    rep(i,n-1){
        int u,v;
        int c;
        cin >> u >> v >> c;
        u--;v--;
        g[u].push_back(MP(v,c));
        g[v].push_back(MP(u,c));
        cost[u][v] = c;
        cost[v][u] = c;
    }
    dfsssss(0,-1);
    vector<ll> dp(w+1,-inf);
    dfs(0,-1,dp);
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 62464
final_rank: 7

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
#include <utility>
#include <queue>
#include <set>
#include <map>
#include <deque>
#include <iomanip>
#include <cstdio>
#include <stack>
#include <numeric>

using namespace std;
typedef  long long ll;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<VI> VVI;
#define  MP make_pair
#define  PB push_back
#define inf 1L<<60
#define mod 1000000007
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define int long long
int n,w;
vector<vector<pair<int,int> > >  g;
vector<int> nex;
vector<ll> p;
ll cost[200][200];
ll ans;

int dfsssss(int id,int pre){
    int ret = 1, mx = 0;
    for(auto x:g[id]){
        if(x.first !=pre){
            int res = dfsssss(x.first,id);
            if(mx < res){
                nex[id] = x.first;
                mx = res;
            }
            ret += res;
        }
    }
    return ret;
}

void dfs2(int id,int pre,vector<ll>&dp){
    vector<ll> dp3(w+1,-inf);
    for(int i=w;i>=cost[id][pre];i--){
        dp3[i] = dp[i-cost[id][pre]] + p[id];
    }
    for(auto x:g[id]){
        if(x.first == pre)continue;
        dfs2(x.first,id,dp3);
    }
    // dp3 にはテーブル dp を初期値として id を取る + id 内の部分木で更新を行なった後の姿が入る
    rep(i,w+1){
        dp[i] = max(dp[i], dp3[i]);
    }
}

void dfs(int id,int pre,vector<ll>&dp){
    vector<ll> dp3(w+1,-inf);
    dp3[0] = p[id];
    if(pre!=-1&&nex[pre]==id){
        for(int i=cost[id][pre];i<=w;i++){
            dp3[i] = dp[i-cost[id][pre]] + p[id];
        }
    }
    for(auto x:g[id]){
        if(x.first == pre)continue;
        if(x.first == nex[id])continue;
        vector<ll> dp4(w+1,-inf);
        dfs(x.first,id,dp4);
        dfs2(x.first,id,dp3);
    }
    rep(i,w+1) ans = max(ans,dp3[i]);
    if(nex[id]!=-1){
        dfs(nex[id],id,dp3);
    }
}

signed main(){

    cin >> n >> w;
    p.resize(n);
    rep(i,n)cin >> p[i];
    g.resize(n);
    nex.resize(n,-1);
    rep(i,n-1){
        int u,v;
        int c;
        cin >> u >> v >> c;
        u--;v--;
        g[u].push_back(MP(v,c));
        g[v].push_back(MP(u,c));
        cost[u][v] = c;
        cost[v][u] = c;
    }
    dfsssss(0,-1);
    vector<ll> dp(w+1,-inf);
    dfs(0,-1,dp);
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 62340
final_rank: 4

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
#include <utility>
#include <queue>
#include <set>
#include <map>
#include <deque>
#include <iomanip>
#include <cstdio>
#include <stack>
#include <numeric>

using namespace std;
typedef  long long ll;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<VI> VVI;
#define  MP make_pair
#define  PB push_back
#define inf 1L<<60
#define mod 1000000007
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define int long long
int n,w;
vector<vector<pair<int,int> > >  g;
vector<int> nex;
vector<ll> p;
ll cost[200][200];
ll ans;

int dfsssss(int id,int pre){
    int ret = 1, mx = 0;
    for(auto x:g[id]){
        if(x.first !=pre){
            int res = dfsssss(x.first,id);
            if(mx < res){
                nex[id] = x.first;
                mx = res;
            }
            ret += res;
        }
    }
    return ret;
}

void dfs(int id,int pre,vector<ll>&dp,bool flag){
    if(!flag){
        vector<ll> dp3(w+1,-inf);
        dp3[0] = p[id];
        if(pre!=-1&&nex[pre]==id){
            for(int i=cost[id][pre];i<=w;i++){
                dp3[i] = dp[i-cost[id][pre]] + p[id];
            }
        }
        for(auto x:g[id]){
            if(x.first == pre)continue;
            if(x.first == nex[id])continue;
            vector<ll> dp4(w+1,-inf);
            dfs(x.first,id,dp4,0);
            dfs(x.first,id,dp3,1);
        }
        rep(i,w+1) ans = max(ans,dp3[i]);
        if(nex[id]!=-1){
            dfs(nex[id],id,dp3,0);
        }
    }else{
        vector<ll> dp3(w+1,-inf);
        for(int i=w;i>=cost[id][pre];i--){
            dp3[i] = dp[i-cost[id][pre]] + p[id];
        }
        for(auto x:g[id]){
            if(x.first == pre)continue;
            dfs(x.first,id,dp3,1);
        }
        // dp3 にはテーブル dp を初期値として id を取る + id 内の部分木で更新を行なった後の姿が入る
        rep(i,w+1){
            dp[i] = max(dp[i], dp3[i]);
        }
    }
}

signed main(){

    cin >> n >> w;
    p.resize(n);
    rep(i,n)cin >> p[i];
    g.resize(n);
    nex.resize(n,-1);
    rep(i,n-1){
        int u,v;
        int c;
        cin >> u >> v >> c;
        u--;v--;
        g[u].push_back(MP(v,c));
        g[v].push_back(MP(u,c));
        cost[u][v] = c;
        cost[v][u] = c;
    }
    dfsssss(0,-1);
    vector<ll> dp(w+1,-inf);
    dfs(0,-1,dp,0);
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 62416
final_rank: 5

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
#include <utility>
#include <queue>
#include <set>
#include <map>
#include <deque>
#include <iomanip>
#include <cstdio>
#include <stack>
#include <numeric>

using namespace std;
typedef  long long ll;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<VI> VVI;
#define  MP make_pair
#define  PB push_back
#define inf 1L<<60
#define mod 1000000007
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define int long long
int n,w;
vector<vector<pair<int,int> > >  g;
vector<int> nex;
vector<int>  dep;
vector<ll> p;
ll cost[200][200];
int dfsssss(int id,int pre){
    int mx = 0;
    for(auto x:g[id]){
        if(x.first !=pre){
            int k = dfsssss(x.first,id);
            k++;
            if(mx < k){
                nex[id] = x.first;
                mx = max(k,mx);
            }
        }
    }
    return dep[id] = mx;
}

vector<ll> ans;

void dfs(int id,int pre,vector<ll>&dp,bool flag){
    if(!flag){
        vector<ll> dp3(w+1,-inf);
        dp3[0] = p[id];
        if(pre!=-1&&nex[pre]==id){
            for(int i=cost[id][pre];i<=w;i++){
                dp3[i] = dp[i-cost[id][pre]] + p[id];
            }
        }
        for(auto x:g[id]){
            if(x.first == pre)continue;
            if(x.first == nex[id])continue;
            vector<ll> dp4(w+1,-inf);
            dfs(x.first,id,dp4,0);
            dfs(x.first,id,dp3,1);
        }
        rep(i,w+1){
            ans[i] = max(ans[i],dp3[i]);
        }
        if(nex[id]!=-1){
            dfs(nex[id],id,dp3,0);
        }
    }else{
        vector<ll> dp3(w+1,-inf);
        for(int i=w;i>=cost[id][pre];i--){
            dp3[i] = dp[i-cost[id][pre]] + p[id];
        }
        for(auto x:g[id]){
            if(x.first == pre)continue;
            dfs(x.first,id,dp3,1);
        }
        // dp3 にはテーブル dp を初期値として id を取る + id 内の部分木で更新を行なった後の姿が入る
        rep(i,w+1){
            dp[i] = max(dp[i], dp3[i]);
        }
    }
}

signed main(){

    cin >> n >> w;
    p.resize(n);
    rep(i,n)cin >> p[i];
    g.resize(n);
    dep.resize(n);
    ans.resize(w+1);
    nex.resize(n,-1);
    rep(i,n-1){
        int u,v;
        int c;
        cin >> u >> v >> c;
        u--;v--;
        g[u].push_back(MP(v,c));
        g[v].push_back(MP(u,c));
        cost[u][v] = c;
        cost[v][u] = c;
    }
    dfsssss(0,-1);
    vector<ll> dp(w+1,-inf);
    dfs(0,-1,dp,0);
    ll ma = 0;
    rep(i,w+1){
        ma = max(ma,ans[i]);
    }
    cout << ma << endl;
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 63212
final_rank: 12

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
#include <utility>
#include <queue>
#include <set>
#include <map>
#include <deque>
#include <iomanip>
#include <cstdio>
#include <stack>
#include <numeric>

using namespace std;
typedef  long long ll;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<VI> VVI;
#define  MP make_pair
#define  PB push_back
#define inf 1L<<60
#define mod 1000000007
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define int long long
int n,w;
vector<vector<pair<int,int> > >  g;
vector<int> nex;
vector<int>  dep;
vector<ll> p;
ll cost[200][200];
int dfsssss(int id,int pre){
    int mx = 0;
    for(auto x:g[id]){
        if(x.first !=pre){
            int k = dfsssss(x.first,id);
            k++;
            if(mx < k){
                nex[id] = x.first;
                mx = max(k,mx);
            }
        }
    }
    return dep[id] = mx;
}

vector<ll> ans;

void dfs(int id,int pre,vector<ll>&dp,vector<ll> &dp2,bool flag){
    if(!flag){
        vector<ll> dp3(w+1,-inf);
        dp3[0] = p[id];
        if(pre!=-1&&nex[pre]==id){
            for(int i=cost[id][pre];i<=w;i++){
                dp3[i] = dp2[i-cost[id][pre]] + p[id];
            }
        }
        for(auto x:g[id]){
            if(x.first == pre)continue;
            if(x.first == nex[id])continue;
            vector<ll> dp4(w+1,-inf);
            dfs(x.first,id,dp4,dp4,0);
            dfs(x.first,id,dp3,dp3,1);
        }
        rep(i,w+1){
            ans[i] = max(ans[i],dp3[i]);
        }
        if(nex[id]!=-1){
            dfs(nex[id],id,dp3,dp3,0);
        }
    }else{
        vector<ll> dp3(w+1,-inf);
        for(int i=w;i>=cost[id][pre];i--){
            dp3[i] = dp[i-cost[id][pre]] + p[id];
        }
        for(auto x:g[id]){
            if(x.first == pre)continue;
            dfs(x.first,id,dp3,dp3,1);
        }
        // dp3 にはテーブル dp を初期値として id を取る + id 内の部分木で更新を行なった後の姿が入る
        rep(i,w+1){
            dp[i] = max(dp[i], dp3[i]);
        }
    }
}

signed main(){

    cin >> n >> w;
    p.resize(n);
    rep(i,n)cin >> p[i];
    g.resize(n);
    dep.resize(n);
    ans.resize(w+1);
    nex.resize(n,-1);
    rep(i,n-1){
        int u,v;
        int c;
        cin >> u >> v >> c;
        u--;v--;
        g[u].push_back(MP(v,c));
        g[v].push_back(MP(u,c));
        cost[u][v] = c;
        cost[v][u] = c;
    }
    dfsssss(0,-1);
    vector<ll> dp(w+1,-inf);
    //rep(i,n)cerr << nex[i] << endl;
    dp[0] = 0;
    dfs(0,-1,dp,dp,0);
    ll ma = 0;
    rep(i,w+1){
        ma = max(ma,ans[i]);
    }
    cout << ma << endl;
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 63208
final_rank: 11

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
#include <utility>
#include <queue>
#include <set>
#include <map>
#include <deque>
#include <iomanip>
#include <cstdio>
#include <stack>
#include <numeric>

using namespace std;
typedef  long long ll;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<VI> VVI;
#define  MP make_pair
#define  PB push_back
#define inf 1L<<60
#define mod 1000000007
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define int long long
int n,w;
vector<vector<pair<int,int> > >  g;
vector<int> nex;
vector<int>  dep;
vector<ll> p;
ll cost[200][200];
int dfsssss(int id,int pre){
    int mx = 0;
    for(auto x:g[id]){
        if(x.first !=pre){
            int k = dfsssss(x.first,id);
            k++;
            if(mx < k){
                nex[id] = x.first;
                mx = max(k,mx);
            }
        }
    }
    return dep[id] = mx;
}

vector<ll> ans;

void dfs(int id,int pre,vector<ll>&dp,vector<ll> &dp2,bool flag){
    if(!flag){
        vector<ll> dp3(w+1,-inf);
        dp3[0] = p[id];
        if(pre!=-1&&nex[pre]==id){
            for(int i=cost[id][pre];i<=w;i++){
                dp3[i] = dp2[i-cost[id][pre]] + p[id];
            }
        }
        for(auto x:g[id]){
            if(x.first == pre)continue;
            if(x.first == nex[id])continue;
            vector<ll> dp4(w+1,-inf);
            dfs(x.first,id,dp4,dp4,0);
            dfs(x.first,id,dp3,dp3,1);
        }
        rep(i,w+1){
            ans[i] = max(ans[i],dp3[i]);
        }
        if(nex[id]!=-1){
            dfs(nex[id],id,dp3,dp3,0);
        }
    }else{
        vector<ll> dp3(w+1,-inf);
        for(int i=w;i>=cost[id][pre];i--){
            dp3[i] = dp[i-cost[id][pre]] + p[id];
        }
        for(auto x:g[id]){
            if(x.first == pre)continue;
            vector<ll> dp4 = dp3;
            dfs(x.first,id,dp3,dp4,1);
        }
        // dp3 にはテーブル dp に加えて id を取ると決めたときの id を根とする部分木で適当につないだときの最適値
        rep(i,w+1){
            dp[i] = max(dp[i],dp3[i]);
        }
    }
}

signed main(){

    cin >> n >> w;
    p.resize(n);
    rep(i,n)cin >> p[i];
    g.resize(n);
    dep.resize(n);
    ans.resize(w+1);
    nex.resize(n,-1);
    rep(i,n-1){
        int u,v;
        int c;
        cin >> u >> v >> c;
        u--;v--;
        g[u].push_back(MP(v,c));
        g[v].push_back(MP(u,c));
        cost[u][v] = c;
        cost[v][u] = c;
    }
    dfsssss(0,-1);
    vector<ll> dp(w+1,-inf);
    //rep(i,n)cerr << nex[i] << endl;
    dp[0] = 0;
    dfs(0,-1,dp,dp,0);
    ll ma = 0;
    rep(i,w+1){
        ma = max(ma,ans[i]);
    }
    cout << ma << endl;
    return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 63188
final_rank: 15

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
#include <utility>
#include <queue>
#include <set>
#include <map>
#include <deque>
#include <iomanip>
#include <cstdio>
#include <stack>
#include <numeric>

using namespace std;
typedef  long long ll;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<VI> VVI;
#define  MP make_pair
#define  PB push_back
#define inf 1L<<60
#define mod 1000000007
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define int long long
int n,w;
vector<vector<pair<int,int> > >  g;
vector<int> nex;
vector<int>  dep;
vector<ll> p;
ll cost[200][200];
int dfsssss(int id,int pre){
    int mx = 0;
    for(auto x:g[id]){
        if(x.first !=pre){
            int k = dfsssss(x.first,id);
            k++;
            if(mx < k){
                nex[id] = x.first;
                mx = max(k,mx);
            }
        }
    }
    return dep[id] = mx;
}

vector<ll> ans;

void dfs(int id,int pre,vector<ll>&dp,vector<ll> &dp2,bool flag){
    // dpは更新する奴  dp2は今の状態
    if(!flag){//連結いらない
        vector<ll> dp3(w+1,-inf);
        dp3[0] = p[id];
        if(pre!=-1&&nex[pre]==id){
            for(int i=cost[id][pre];i<=w;i++){
                dp3[i] = dp2[i-cost[id][pre]] + p[id];
            }
        }
        for(auto x:g[id]){
            if(x.first == pre)continue;
            if(x.first == nex[id])continue;
            vector<ll> dp4(w+1,-inf);
            dfs(x.first,id,dp4,dp4,0);
            dfs(x.first,id,dp3,dp3,1);
        }
        // cerr << id << endl;
        // rep(i,w+1){
        //     cerr << dp[i] << endl;
        // }
        rep(i,w+1){
            ans[i] = max(ans[i],dp3[i]);
        }
        if(nex[id]!=-1){
            dfs(nex[id],id,dp3,dp3,0);
        }
    }else{//連結
        vector<ll> dp3(w+1,-inf);
        for(int i=w;i>=cost[id][pre];i--){
            dp3[i] = dp2[i-cost[id][pre]] + p[id];
        }
        // rep(i,w+1){
        //     dp[i] = max(dp[i],dp3[i]);
        // }

        for(auto x:g[id]){
            if(x.first == pre)continue;
            vector<ll> dp4 = dp3;
            dfs(x.first,id,dp3,dp4,1);
        }
        rep(i,w+1){
            dp[i] = max(dp[i],dp3[i]);
        }
    }
}

signed main(){

    cin >> n >> w;
    p.resize(n);
    rep(i,n)cin >> p[i];
    g.resize(n);
    dep.resize(n);
    ans.resize(w+1);
    nex.resize(n,-1);
    rep(i,n-1){
        int u,v;
        int c;
        cin >> u >> v >> c;
        u--;v--;
        g[u].push_back(MP(v,c));
        g[v].push_back(MP(u,c));
        cost[u][v] = c;
        cost[v][u] = c;
    }
    dfsssss(0,-1);
    vector<ll> dp(w+1,-inf);
    //rep(i,n)cerr << nex[i] << endl;
    dp[0] = 0;
    dfs(0,-1,dp,dp,0);
    ll ma = 0;
    rep(i,w+1){
        ma = max(ma,ans[i]);
    }
    cout << ma << endl;
    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 63216
final_rank: 16

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define SIZE 105

struct Edge{
	Edge(int arg_to,ll arg_cost){
		to = arg_to;
		cost = arg_cost;
	}
	int to;
	ll cost;
};

int N;
ll W;
vector<Edge> G[SIZE];
ll value[SIZE];

void init(vector<ll> &V){

	V[0] = 0;
	for(ll i = 1; i <= W; i++){

		V[i] = -HUGE_NUM;
	}
}

vector<ll> dfs_USE(vector<ll> dp,int node_id,int parent){

	vector<ll> ret = dp;

	for(int i = 0; i < G[node_id].size(); i++){

		int child = G[node_id][i].to;
		if(child == parent)continue;

		vector<ll> work_USE = dfs_USE(ret,child,node_id);

		for(int k = W; k-G[node_id][i].cost >= 0; k--){

			if(work_USE[k-G[node_id][i].cost] == -HUGE_NUM)continue;

			ret[k] = max(ret[k],work_USE[k-G[node_id][i].cost]);
		}
	}

	for(int i = 0; i <= W; i++){
		if(ret[i] == -HUGE_NUM)continue;
		ret[i] += value[node_id];
	}

	return ret;
}

vector<ll> dfs_NOT(int node_id,int parent){

	vector<ll> ret(W+1);
	init(ret);

	vector<ll> first_dp(W+1);
	init(first_dp);

	for(int i = 0; i < G[node_id].size(); i++){

		int child = G[node_id][i].to;
		if(child == parent)continue;

		vector<ll> work_NOT = dfs_NOT(child,node_id);
		for(int k = 0; k <= W; k++){

			ret[k] = max(ret[k],work_NOT[k]);
		}

		vector<ll> work_USE = dfs_USE(first_dp,child,node_id);

		for(int k = 0; k <= W; k++){

			ret[k] = max(ret[k],work_USE[k]);
		}
	}
	return ret;
}


int main(){

	scanf("%d %lld",&N,&W);

	for(int i = 0; i < N; i++){

		scanf("%lld",&value[i]);
	}

	int from,to;
	ll cost;

	for(int i = 0; i < N-1; i++){

		scanf("%d %d %lld",&from,&to,&cost);
		from--;
		to--;

		G[from].push_back(Edge(to,cost));
		G[to].push_back(Edge(from,cost));
	}

	vector<ll> ret_NOT = dfs_NOT(0,-1);

	vector<ll> first_dp(W+1);

	init(first_dp);

	vector<ll> ret_USE = dfs_USE(first_dp,0,-1);

	ll ans = 0;

	for(int i = 0; i <= W; i++){

		ans = max(ans,max(ret_NOT[i],ret_USE[i]));
	}

	printf("%lld\n",ans);

	return 0;
}
accuracy: 1
time_ms: 1570
memory_kb: 121592
final_rank: 20

code_snippet: #include <algorithm>
#include <iostream>
#include <vector>

using namespace std;
using ll = long long;
#define REP(i, n) for (int i = 0; i < n; ++i)
struct E {
	int to, cost;
};
using G = vector<vector<E>>;
vector<int> p;
G g;
constexpr ll inf = 1e18 + 1;
int n, w;

vector<ll> rec1(const vector<ll> &x, int v, int par) {
	auto a = x;
	for (auto e : g[v]) {
		if (e.to != par) {
			auto tmp = rec1(a, e.to, v);
			REP(i, w + 1 - e.cost) {
				a[i + e.cost] = max(a[i + e.cost], tmp[i]);
			}
		}
	}
	REP(i, w + 1) {
		a[i] += p[v];
	}
	return a;
}
vector<ll> rec0(int v, int par) {
	vector<ll> ret(w + 1, -inf);
	ret[0] = 0;
	vector<ll> z(w + 1, -inf);
	z[0] = 0;
	for (auto &&e : g[v]) {
		if (e.to != par) {
			auto tmp = rec0(e.to, v);
			REP(i, w + 1) {
				ret[i] = max(ret[i], tmp[i]);
			}
			auto tmp1 = rec1(z, e.to, v);
			REP(i, w + 1) {
				ret[i] = max(ret[i], tmp1[i]);
			}
		}
	}
	return ret;
}

int main() {

	cin >> n >> w;
	p.resize(n);
	REP(i, n) cin >> p[i];
	g.resize(n);
	REP(i, n - 1) {
		int a, b, c;
		cin >> a >> b >> c;
		a--;
		b--;
		g[a].push_back(E{b, c});
		g[b].push_back(E{a, c});
	}
	vector<ll> ans = rec0(0, -1);
	vector<ll> init(w + 1, -inf);
	init[0] = 0;
	vector<ll> ans1 = rec1(init, 0, -1);
	ll res = -inf;
	res = max(res, *max_element(begin(ans), end(ans)));
	res = max(res, *max_element(begin(ans1), end(ans1)));
	cout << res << endl;
	//cerr << "test" << endl;
}
accuracy: 1
time_ms: 1040
memory_kb: 120180
final_rank: 18

code_snippet: #include <bits/stdc++.h>
#pragma GCC diagnostic ignored "-Wsign-compare"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#define NDEBUG
#define SHOW(...) static_cast<void>(0)
//!===========================================================!//
//!  dP     dP                          dP                    !//
//!  88     88                          88                    !//
//!  88aaaaa88a .d8888b. .d8888b. .d888b88 .d8888b. 88d888b.  !//
//!  88     88  88ooood8 88'  '88 88'  '88 88ooood8 88'  '88  !//
//!  88     88  88.  ... 88.  .88 88.  .88 88.  ... 88        !//
//!  dP     dP  '88888P' '88888P8 '88888P8 '88888P' dP        !//
//!===========================================================!//
template <typename T>
T read()
{
    T v;
    return std::cin >> v, v;
}
template <typename T>
std::vector<T> readVec(const std::size_t l)
{
    std::vector<T> v(l);
    for (auto& e : v) { std::cin >> e; }
    return v;
}
using ld = long double;
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
constexpr unsigned int MOD = 1000000007;
template <typename T>
constexpr T INF = std::numeric_limits<T>::max() / 4;
template <typename F>
constexpr F PI = static_cast<F>(3.1415926535897932385);
std::mt19937 mt{std::random_device{}()};
template <typename T>
bool chmin(T& a, const T& b) { return (a > b ? a = b, true : false); }
template <typename T>
bool chmax(T& a, const T& b) { return (a < b ? a = b, true : false); }
template <typename T>
std::vector<T> Vec(const std::size_t n, T v) { return std::vector<T>(n, v); }
template <class... Args>
auto Vec(const std::size_t n, Args... args) { return std::vector<decltype(Vec(args...))>(n, Vec(args...)); }
template <typename T>
constexpr T popCount(const T u)
{
#ifdef __has_builtin
    return u == 0 ? T(0) : (T)__builtin_popcountll(u);
#else
    unsigned long long v = static_cast<unsigned long long>(u);
    return v = (v & 0x5555555555555555ULL) + (v >> 1 & 0x5555555555555555ULL), v = (v & 0x3333333333333333ULL) + (v >> 2 & 0x3333333333333333ULL), v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL, static_cast<T>(v * 0x0101010101010101ULL >> 56 & 0x7f);
#endif
}
template <typename T>
constexpr T log2p1(const T u)
{
#ifdef __has_builtin
    return u == 0 ? T(0) : T(64 - __builtin_clzll(u));
#else
    unsigned long long v = static_cast<unsigned long long>(u);
    return v = static_cast<unsigned long long>(v), v |= (v >> 1), v |= (v >> 2), v |= (v >> 4), v |= (v >> 8), v |= (v >> 16), v |= (v >> 32), popCount(v);
#endif
}
template <typename T>
constexpr T clog(const T v) { return v == 0 ? T(0) : log2p1(v - 1); }
template <typename T>
constexpr T msbp1(const T v) { return log2p1(v); }
template <typename T>
constexpr T lsbp1(const T v)
{
#ifdef __has_builtin
    return __builtin_ffsll(v);
#else
    return v == 0 ? T(0) : popCount((v & (-v)) - T(1)) + T(1);
#endif
}
template <typename T>
constexpr bool ispow2(const T v) { return popCount(v) == 1; }
template <typename T>
constexpr T ceil2(const T v) { return v == 0 ? T(1) : T(1) << log2p1(v - 1); }
template <typename T>
constexpr T floor2(const T v) { return v == 0 ? T(0) : T(1) << (log2p1(v) - 1); }
//!=================================================!//
//!   .88888.                             dP        !//
//!  d8'   '88                            88        !//
//!  88        88d888b. .d8888b. 88d888b. 88d888b.  !//
//!  88   YP88 88'  '88 88'  '88 88'  '88 88'  '88  !//
//!  Y8.   .88 88       88.  .88 88.  .88 88    88  !//
//!   '88888'  dP       '88888P8 88Y888P' dP    dP  !//
//!                              88                 !//
//!                              dP                 !//
//!=================================================!//
struct Graph
{
    Graph(const std::size_t v) : V{v}, edge(v), rev_edge(v) {}
    void addEdge(const std::size_t from, const std::size_t to, const bool bi = false)
    {
        assert(from < V), assert(to < V);
        edge[from].push_back(to), rev_edge[to].push_back(from);
        if (bi) { addEdge(to, from, false); }
    }
    const std::vector<std::size_t>& operator[](const std::size_t i) const { return assert(i < V), edge[i]; }
    friend std::ostream& operator<<(std::ostream& os, const Graph& g)
    {
        os << "[\n";
        for (std::size_t i = 0; i < g.V; i++) {
            for (const std::size_t to : g.edge[i]) { os << i << "->" << to << "\n"; }
        }
        return (os << "]\n");
    }
    std::size_t V;
    std::vector<std::vector<std::size_t>> edge, rev_edge;
};
using Tree = Graph;
//!==================================!//
//!  dP     dP  dP        888888ba   !//
//!  88     88  88        88    '8b  !//
//!  88aaaaa88a 88        88     88  !//
//!  88     88  88        88     88  !//
//!  88     88  88        88    .8P  !//
//!  dP     dP  88888888P 8888888P   !//
//!==================================!//
class HLD
{
public:
    HLD(Tree& tree, const std::size_t r = 0) : par(tree.V, tree.V), top(tree.V, tree.V), in(tree.V, tree.V), out(tree.V, tree.V)
    {
        const std::size_t N = tree.V;
        std::vector<std::size_t> sz(N, 1);
        auto dfs1 = [&](auto&& self, const std::size_t s, const std::size_t p) -> std::size_t {
            par[s] = p;
            for (std::size_t& to : tree.edge[s]) {
                if (p == to) { continue; }
                sz[s] += self(self, to, s);
                if (sz[to] > sz[tree.edge[s][0]]) { std::swap(to, tree.edge[s][0]); }
            }
            return sz[s];
        };
        dfs1(dfs1, r, N);
        top[r] = r;
        auto dfs2 = [&](auto&& self, const std::size_t s, const std::size_t p, std::size_t& ind) -> void {
            in[s] = ind++;
            for (const std::size_t to : tree.edge[s]) {
                if (to == p) { continue; }
                top[to] = (to == tree.edge[s][0] ? top[s] : to);
                self(self, to, s, ind);
            }
            out[s] = ind;
        };
        std::size_t ind = 0;
        dfs2(dfs2, r, N, ind);
    }
    std::size_t at(const std::size_t v) const { return in[v]; }
    std::pair<std::size_t, std::size_t> sub(const std::size_t v) const { return {in[v], out[v]}; }
    std::vector<std::pair<std::size_t, std::size_t>> path(std::size_t u, std::size_t v, const bool edgeWeight = false) const
    {
        using P = std::pair<std::size_t, std::size_t>;
        std::vector<P> head, tail;
        for (std::size_t pu = top[u], pv = top[v]; pu != pv;) {
            if (in[pu] < in[pv]) {
                tail.push_back({in[pv], in[v]});
                v = par[pv], pv = top[v];
            } else {
                tail.push_back({in[u], in[pu]});
                u = par[pu], pu = top[u];
            }
        }
        if (edgeWeight) {
            if (std::abs((int)in[u] - (int)in[v]) >= 1) { head.push_back(in[u] < in[v] ? P{in[u] + 1, in[v]} : P{in[u], in[v] + 1}); }
        } else {
            head.push_back({in[u], in[v]});
        }
        std::reverse(tail.begin(), tail.end());
        for (const auto& p : tail) { head.push_back(p); }
        return head;
    }

private:
    std::vector<std::size_t> par, top, in, out;
};
//!=====================================!//
//!  8888ba.88ba           oo           !//
//!  88  '8b  '8b                       !//
//!  88   88   88 .d8888b. dP 88d888b.  !//
//!  88   88   88 88'  '88 88 88'  '88  !//
//!  88   88   88 88.  .88 88 88    88  !//
//!  dP   dP   dP '88888P8 dP dP    dP  !//
//!=====================================!//
int main()
{
    const int N = read<int>(), W = read<int>();
    const auto P = readVec<ll>(N);
    auto C = Vec(N, N, 0);
    Graph T(N);
    for (int i = 0; i < N - 1; i++) {
        const int u = read<int>() - 1, v = read<int>() - 1, c = read<int>();
        T.addEdge(u, v, true), C[u][v] = C[v][u] = c;
    }
    HLD hld(T, 0);
    ll ans = 0;
    std::vector<ll> init(W + 1, -INF<ll>);
    init[0] = 0;
    auto RecDP = [&, N, W](auto&& self, const int s, const int prev, const bool empty, const std::vector<ll>& X) -> std::vector<ll> {
        auto Xs = X;
        for (int i = 0; i < T[s].size(); i++) {
            const int to = T[s][i];
            if (to == prev) { continue; }
            if (i > 0 and empty) { self(self, to, s, true, init); }
            const auto Y = self(self, to, s, i == 0 and empty, Xs);
            const int c = C[s][to];
            for (int w = 0; w <= W - c; w++) { chmax(Xs[w + c], Y[w]); }
        }
        for (int w = 0; w <= W; w++) {
            Xs[w] += P[s];
            if (empty) { chmax(ans, Xs[w]); }
        }
        return Xs;
    };
    RecDP(RecDP, 0, -1, true, init);
    std::cout << ans << std::endl;
    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 62544
final_rank: 14