Problem:
さんぽ
Problem Statement
ねこのそらは散歩が大好きだ．道を歩くと新しい発見がある．
そらの住む町は
N
個の広場と
N-1
本の道からなる．
道はちょうど二つの広場をつないでおり，枝分かれしたり道どうしが交わったりしない．
道には，歩くのにかかる時間
t
，得られる発見の個数の上限
m
，および，発見一つあたりの価値
v
が指定されている．
道を一方の端からもう一方の端まで歩いたとき，
m
回目までの通行では価値
v
の発見が一つ得られるが，
m+1
回目以降は発見が得られない．
今日もそらは，町内の散歩に出かけるようだ．
そらの散歩は広場 1 から始まり，いくつかの道 ( 0 本かもしれない ) を通って，最後に広場 1 に戻ってくる，というルートをとる．
また，日が暮れると寂しい気持ちになるので，そらは散歩時間を
T
以下にしたいと思っている．
そらの友人であるあなたの仕事は，散歩時間が
T
以下である散歩ルートにおいて，得られる発見の価値の総和の最大値を求めることである．
Input
入力は以下の形式に従う．与えられる数は全て整数である．
N
T
a_1
b_1
t_1
m_1
v_1
. . .
a_{N-1}
b_{N-1}
t_{N-1}
m_{N-1}
v_{N-1}
入力の
i+1
行目は，広場
a_i
と
b_i
をつなぐ，通行時間
t_i
，得られる発見の個数の上限
m_i
，発見一つあたりの価値
v_i
の道を表している．
Constraints
1 ≦ N ≦ 300
1 ≦ T ≦ 10^4
1 ≦ a_i, b_i ≦ N
1 ≦ t_i ≦ 10^4
0 ≦ m_i ≦ 10^4
1 ≦ v_i ≦ 10^5
どの二つの広場も道を通って行き来できる．
Output
得られる発見の価値の総和の最大値を 1 行に出力せよ．
Sample Input 1
4 5
1 2 1 4 7
2 3 1 2 77
2 4 1 2 777
Output for the Sample Input 1
1568
1→2→4→2→1 と移動することで，合計で価値 7+777+777+7=1568 の発見が得られる．
Sample Input 2
2 10000
1 2 1 10 1
Output for the Sample Input 2
10
Sample Input 3
5 15
1 2 3 2 1
2 3 3 2 1
1 4 8 2 777
1 5 1 3 10
Output for the Sample Input 3
32

Submitted solutions:

code_snippet: #include<stdio.h>
#include<iostream>
#include<vector>
#include<map>
#include<queue>
#include<string.h>
#include<algorithm>
struct Way{
	int to;
	long long int t,m,v;
};
struct S{
	long long int v,t;
	bool operator<(const S& s)const{
		return t>s.t;
	}
};

const int size=301;
const int tMax=10001;

std::vector<Way> G[size];
long long int values[size][tMax];

void saiki(int parent,int now,Way w1,int T){
	int t1;
	long long int v1;
	if(parent!=0){
		std::vector<S> tempV;
		S s1;
		for(int i=0;i<=T;i+=2){
			s1.t=i;
			s1.v=values[parent][i];
			if(s1.v!=-1)tempV.push_back(s1);
		}
		std::sort(tempV.begin(),tempV.end());
		for(int i=0;i<tempV.size();i++){
			long long int baseV=tempV[i].v;
			for(long long int j=2;j<=w1.m+1+(w1.m==0);j+=2){
				t1=j*w1.t+tempV[i].t;
				if(t1>T)break;
				v1=(j>=w1.m?w1.m:j)*w1.v+baseV;
				if(values[now][t1]<v1)values[now][t1]=v1;
				else break;
			}
		}
	}
	for(int i=0;i<G[now].size();i++){
		w1=G[now][i];
		if(parent!=w1.to){
			saiki(now,w1.to,w1,T);
			for(int j=0;j<=T;j++){
				if(values[now][j]<values[w1.to][j])values[now][j]=values[w1.to][j];
			}
		}
	}
}

int main(){
	int N,T,a,b;
	Way w1;
	long long int t1,m1;
	memset(values,-1,sizeof(values));
	
	scanf("%d %d",&N,&T);
	T=T-T%2;
	for(int i=0;i<N-1;i++){
		scanf("%d %d",&a,&b);
		std::cin>>w1.t>>w1.m>>w1.v;
		w1.to=b;
		G[a].push_back(w1);
		w1.to=a;
		G[b].push_back(w1);
	}
	values[1][0]=0;
	saiki(0,1,w1,T);
	long long int ans=0;
	for(int i=0;i<=T;i+=2){
		if(values[1][i]>ans)ans=values[1][i];
	}
	std::cout<<ans<<"\n";
}
accuracy: 1
time_ms: 130
memory_kb: 27216
final_rank: 4

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 310
#define MAX_T 10000

int n, T;
vector<pair<int,int> > way[SIZE];
int a[SIZE], b[SIZE], t[SIZE], m[SIZE], v[SIZE];

void dfs(vector<ll> &dp, int now, int back=-1, int eid = -1){  
  if(eid >= 0){
    int w = max(0, m[eid] - 2) / 2;
    ll tmp_v = v[eid]*2, tmp_t = t[eid]*2; 
    for(int j=1;j<=w;j*=2){
      for(int i=T-tmp_t;i>=0;i--){
        dp[i+tmp_t] = max(dp[i+tmp_t], dp[i] + tmp_v);
      }
      w -= j;
      tmp_t *= 2;
      tmp_v *= 2;
    }
    tmp_v=v[eid]*2*w; tmp_t=t[eid]*2*w;
    for(int i=T-tmp_t;i>=0;i--){
      dp[i+tmp_t] = max(dp[i+tmp_t], dp[i] + tmp_v);
    }

    if(max(0, m[eid] - 2)%2){
      for(int i=T-t[eid]*2;i>=0;i--){
        dp[i+t[eid]*2] = max(dp[i+t[eid]*2], dp[i] + v[eid]);
      }
    }
  }
  
  for(int i=0;i<way[now].size();i++){
    if(way[now][i].first == back) continue;
    int id = way[now][i].second;

    vector<ll> dp_dfs(T+1, -LLINF);
    for(int j=0;j+t[id]*2<=T;j++) dp_dfs[j+t[id]*2] = dp[j];
    
    dfs(dp_dfs, way[now][i].first, now, id);

    for(int j=0;j<=T;j++) dp[j] = max(dp[j], dp_dfs[j] + v[id]*min(2, m[id]));
  }
  
}

int main(){

  scanf("%d%d", &n, &T);

  for(int i=0;i<n-1;i++){
    scanf("%d%d%d%d%d", a+i, b+i, t+i, m+i ,v+i);
    a[i]--; b[i]--;
    way[a[i]].push_back({b[i],i});
    way[b[i]].push_back({a[i],i});
  }

  vector<ll> dp(T + 1, -LLINF);

  dp[0] = 0;
  dfs(dp, 0);

  ll ans = 0;
  
  for(int i=0;i<=T;i++)
    ans = max(ans, dp[i]);

  printf("%lld\n", ans);
  
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 26468
final_rank: 2

code_snippet: #include <bits/stdc++.h>

using namespace std;
using ll = long long int;

void chmax(ll &A, ll B) { A = max(A, B); }

struct Edge {
    Edge() {}
    Edge(int to_, int tm_, int lim_, int cost_) : to(to_), tm(tm_), lim(lim_), cost(cost_) {}
    int to, tm, lim, cost;
};
using Graph = vector< vector<Edge> >;

ll N, T, dp[650][10010];
int euler[650], dir[650];
Edge euler_edge[650];
int idx = 0;

void dfs(Graph &G, int cur, int par=-1) {
    euler[idx++] = cur;
    for(auto e : G[cur]) {
        int to = e.to;
        if(to == par) continue;
        euler_edge[idx] = e;
        dir[idx] = 0;
        dfs(G, to, cur);
        euler_edge[idx] = e;
        dir[idx] = 1;
        euler[idx++] = cur;
    }
}

int main() {
    cin >> N >> T;

    Graph G(N);
    for(int i=0; i<N-1; i++) {
        int a, b, t, m, v; cin >> a >> b >> t >> m >> v;
        a--; b--;
        G[a].push_back(Edge{b, t, m, v});
        G[b].push_back(Edge{a, t, m, v});
    }
    dfs(G, 0);

    /*
    for(int i=0; i<idx; i++) {
        printf("%d (%d), ", euler[i], euler_edge[i].cost);
    }
    cout << endl;
    */

    vector<int> pre(N, -1);
    fill(dp[0], dp[650], -(1LL << 60));
    // for(int i=0; i<idx; i++) dp[i][0] = 0;
    dp[0][0] = pre[0] = 0;
    for(int i=1; i<idx; i++) {
        int prev_idx = pre[ euler[i] ];

        int tm = euler_edge[i].tm;
        int lim = euler_edge[i].lim;
        int cost = euler_edge[i].cost;

        for(int t=0; t<=T; t++) {
            if(prev_idx >= 0) chmax(dp[i][t], dp[prev_idx][t]);
        }

        if(dir[i] == 1) {
            // 帰り
            for(int t=0; t<=T; t++) {
                chmax(dp[i][t], dp[i-1][t]);
            }
        }
        else {
            // 行き
            if(lim % 2 == 1) {
                ll take_tm = (lim + 1) * tm, take_cost = lim * cost;
                for(int t=take_tm; t<=T; t++) {
                    chmax(dp[i][t], dp[i-1][t - take_tm] + take_cost);
                }
                lim--;
            }

            if(lim == 0) {
                ll take_tm = 2 * tm;
                for(int t=take_tm; t<=T; t++) {
                    chmax(dp[i][t], dp[i-1][t - take_tm]);
                }
            }
            else {
                lim -= 2;
                for(int m=2; lim>0; m*=2) {
                    ll x = min(lim, m); lim -= x;
                    ll take_tm = x * tm, take_cost = x * cost;
                    for(int t=T; t>=take_tm; t--) {
                        chmax(dp[i-1][t], dp[i-1][t - take_tm] + take_cost);
                    }
                }

                ll take_tm = 2 * tm, take_cost = 2 * cost;
                for(int t=take_tm; t<=T; t++) {
                    chmax(dp[i][t], dp[i-1][t - take_tm] + take_cost);
                }
            }
        }

        /*
        for(int t=0; t<=T; t++) {
            if(dp[i][t] < 0) cout << "-INF" << " ";
            else cout << dp[i][t] << " ";
        }
        cout << endl;
        */
        
        pre[ euler[i] ] = i;
    }
    cout << *max_element(dp[idx-1], dp[idx-1] + T + 1) << endl;
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 53996
final_rank: 11

code_snippet: #include <bits/stdc++.h>

using namespace std;
using ll = long long int;

void chmax(ll &A, ll B) { A = max(A, B); }

struct Edge {
    Edge() {}
    Edge(int to_, int tm_, int lim_, int cost_) : to(to_), tm(tm_), lim(lim_), cost(cost_) {}
    int to, tm, lim, cost;
};
using Graph = vector< vector<Edge> >;

ll N, T, dp[650][10010];
int euler[650];
Edge euler_edge[650];
int idx = 0;

void dfs(Graph &G, int cur, int par=-1) {
    euler[idx++] = cur;
    for(auto e : G[cur]) {
        int to = e.to;
        if(to == par) continue;
        euler_edge[idx] = e;
        dfs(G, to, cur);
        euler_edge[idx] = e;
        euler[idx++] = cur;
    }
}

int main() {
    cin >> N >> T;

    Graph G(N);
    for(int i=0; i<N-1; i++) {
        int a, b, t, m, v; cin >> a >> b >> t >> m >> v;
        a--; b--;
        G[a].push_back(Edge{b, t, m, v});
        G[b].push_back(Edge{a, t, m, v});
    }
    dfs(G, 0);

    /*
    for(int i=0; i<idx; i++) {
        printf("%d (%d), ", euler[i], euler_edge[i].cost);
    }
    cout << endl;
    */

    vector<int> pre(N, -1);
    fill(dp[0], dp[310], -(1LL << 28));
    // for(int i=0; i<idx; i++) dp[i][0] = 0;
    dp[0][0] = pre[0] = 0;
    for(int i=1; i<idx; i++) {
        int prev_idx = pre[ euler[i] ];

        int to = euler_edge[i].to;
        int tm = euler_edge[i].tm;
        int lim = euler_edge[i].lim;
        int cost = euler_edge[i].cost;

        for(int t=0; t<=T; t++) {
            if(prev_idx >= 0) chmax(dp[i][t], dp[prev_idx][t]);
        }

        if(to != euler[i]) {
            // 帰り
            for(int t=0; t<=T; t++) {
                chmax(dp[i][t], dp[i-1][t]);
            }
        }
        else {
            // 行き
            if(lim % 2 == 1) {
                int take_tm = (lim + 1) * tm, take_cost = lim * cost;
                for(int t=take_tm; t<=T; t++) {
                    chmax(dp[i][t], dp[i-1][t - take_tm] + take_cost);
                }
                lim--;
            }

            if(lim == 0) {
                int take_tm = 2 * tm;
                for(int t=take_tm; t<=T; t++) {
                    chmax(dp[i][t], dp[i-1][t - take_tm]);
                }
            }
            else {
                lim -= 2;
                for(int m=2; lim>0; m*=2) {
                    int x = min(lim, m); lim -= x;
                    int take_tm = x * tm, take_cost = x * cost;
                    for(int t=T; t>=take_tm; t--) {
                        chmax(dp[i-1][t], dp[i-1][t - take_tm] + take_cost);
                    }
                }

                int take_tm = 2 * tm, take_cost = 2 * cost;
                for(int t=take_tm; t<=T; t++) {
                    chmax(dp[i][t], dp[i-1][t - take_tm] + take_cost);
                }
            }
        }

        /*
        for(int t=0; t<=T; t++) {
            if(dp[i][t] < 0) cout << "-INF" << " ";
            else cout << dp[i][t] << " ";
        }
        cout << endl;
        */
        
        pre[ euler[i] ] = i;
    }
    cout << *max_element(dp[idx-1], dp[idx-1] + T + 1) << endl;
    return 0;
}
accuracy: 0.11428571428571428
time_ms: 50
memory_kb: 49960
final_rank: 13

code_snippet: #include <bits/stdc++.h>

using namespace std;
using ll = long long int;

void chmax(ll &A, ll B) { A = max(A, B); }

struct Edge {
    Edge() {}
    Edge(int to_, int tm_, int lim_, int cost_) : to(to_), tm(tm_), lim(lim_), cost(cost_) {}
    int to, tm, lim, cost;
};
using Graph = vector< vector<Edge> >;

ll N, T, dp[650][10010];
int euler[650];
Edge euler_edge[650];
int idx = 0;

void dfs(Graph &G, int cur, int par=-1) {
    euler[idx++] = cur;
    for(auto e : G[cur]) {
        int to = e.to;
        if(to == par) continue;
        euler_edge[idx] = e;
        dfs(G, to, cur);
        euler_edge[idx] = e;
        euler[idx++] = cur;
    }
}

int main() {
    cin >> N >> T;

    Graph G(N);
    for(int i=0; i<N-1; i++) {
        int a, b, t, m, v; cin >> a >> b >> t >> m >> v;
        a--; b--;
        G[a].push_back(Edge{b, t, m, v});
        G[b].push_back(Edge{a, t, m, v});
    }
    dfs(G, 0);

    /*
    for(int i=0; i<idx; i++) {
        printf("%d (%d), ", euler[i], euler_edge[i].cost);
    }
    cout << endl;
    */

    vector<int> pre(N, -1);
    fill(dp[0], dp[310], -(1LL << 60));
    dp[0][0] = 0;
    for(int i=1; i<idx; i++) {
        int prev_idx = pre[ euler[i] ];

        int to = euler_edge[i].to;
        int tm = euler_edge[i].tm;
        int lim = euler_edge[i].lim;
        int cost = euler_edge[i].cost;

        for(int t=0; t<=T; t++) {
            if(prev_idx >= 0) chmax(dp[i][t], dp[prev_idx][t]);
        }

        if(to != euler[i]) {
            // 帰り
            for(int t=0; t<=T; t++) {
                chmax(dp[i][t], dp[i-1][t]);
            }
        }
        else {
            // 行き
            if(lim % 2 == 1) {
                int take_tm = (lim + 1) * tm, take_cost = lim * cost;
                for(int t=take_tm; t<=T; t++) {
                    chmax(dp[i][t], dp[i-1][t - take_tm] + take_cost);
                }
                lim--;
            }

            if(lim == 0) {
                int take_tm = 2 * tm;
                for(int t=take_tm; t<=T; t++) {
                    chmax(dp[i][t], dp[i-1][t - take_tm]);
                }
            }
            else {
                lim -= 2;
                for(int m=2; lim>0; m*=2) {
                    int x = min(lim, m); lim -= x;
                    int take_tm = x * tm, take_cost = x * cost;
                    for(int t=T; t>=take_tm; t--) {
                        chmax(dp[i-1][t], dp[i-1][t - take_tm] + take_cost);
                    }
                }

                int take_tm = 2 * tm, take_cost = 2 * cost;
                for(int t=take_tm; t<=T; t++) {
                    chmax(dp[i][t], dp[i-1][t - take_tm] + take_cost);
                }
            }
        }

        /*
        for(int t=0; t<=T; t++) {
            if(dp[i][t] < 0) cout << "-INF" << " ";
            else cout << dp[i][t] << " ";
        }
        cout << endl;
        */
        pre[ euler[i] ] = i;
    }
    cout << *max_element(dp[idx-1], dp[idx-1] + T + 1) << endl;
    return 0;
}
accuracy: 0.04285714285714286
time_ms: 20
memory_kb: 42352
final_rank: 17

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

using namespace std;

typedef long long LL;

struct Edge {
    int to, t, m;
    LL v;
};

void dfs(int v, int parent, const vector<vector<Edge>> &graph, vector<pair<int,Edge>> &ord) {
    for(const auto &e : graph[v]) {
        if(e.to == parent) continue;
        ord.push_back(make_pair(e.to, e));
        dfs(e.to, v, graph, ord);
        ord.push_back(make_pair(v, e));
    }
}

bool solve() {
    int N, T;
    if(!(cin >> N >> T)) return false;
    if(!N && !T) return false;

    vector<vector<Edge>> graph(N);
    for(int i = 0; i < N-1; ++i) {
        int a, b, t, m;
        LL v;
        cin >> a >> b >> t >> m >> v;
        --a; --b;
        graph[a].push_back((Edge){b, t, m, v});
        graph[b].push_back((Edge){a, t, m, v});
    }
    
    vector<pair<int,Edge>> ord;
    ord.push_back(make_pair(0, Edge()));
    dfs(0, -1, graph, ord);
    const int M = ord.size();
    vector<vector<LL>> dp(M, vector<LL>(T+1, -1));
    dp[0][0] = 0;
    for(int i = 1; i < M; ++i) {
        const int v = ord[i].first;
        const Edge &e = ord[i].second;
        if(v != e.to) { //back
            int rem = e.m;
            // should pay 2
            for(int t = T; t >= 0; --t) {
                if(t-e.t*2 >= 0 && dp[i-1][t-e.t*2] >= 0) dp[i][t] = dp[i-1][t-e.t*2] + min(2, e.m)*e.v;
            }
            rem -= min(2, e.m);
            // optionally pay 1 if e.m is odd
            if(rem % 2 == 1) {
                for(int t = T; t >= 0; --t) {
                    if(t-e.t*2 >= 0 && dp[i][t-e.t*2] >= 0) dp[i][t] = max(dp[i][t], dp[i][t-e.t*2] + e.v);
                }
                --rem;
            }
            // binary dp
            for(int k = 2; rem > 0; k *= 2) {
                const int s = min(k, rem);
                const int dt = e.t * s;
                const int dv = e.v * s;
                for(int t = T; t >= 0; --t) {
                    if(t-dt >= 0 && dp[i][t-dt] >= 0) dp[i][t] = max(dp[i][t], dp[i][t-dt] + dv);
                }
                rem -= s;
            }
        } else {
            dp[i] = dp[i-1];
        }
        // Ignore current subtree
        for(int j = i-1; j >= 0; --j) {
            if(ord[j].first == v) {
                for(int t = 0; t <= T; ++t) {
                    dp[i][t] = max(dp[i][t], dp[j][t]);
                }
                break;
            }
        }
        /*
        cout << i << ' ' << v << ": ";
        for(auto val : dp[i]) {
            cout << val << ' ';
        }
        cout << endl;
        */
    }
    cout << *max_element(dp[M-1].begin(), dp[M-1].end()) << endl;
    return true;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(0);

    while(solve()) ;
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 47988
final_rank: 8

code_snippet: #include <iostream>
#include <iomanip>
#include <sstream>
#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cassert>
#include <climits>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
#define chmax(a,b) (a<(b)?(a=b,1):0)
#define chmin(a,b) (a>(b)?(a=b,1):0)
#define valid(y,x,h,w) (0<=y&&y<h&&0<=x&&x<w)
typedef long long ll;
typedef pair<int,int> pii;
const int INF = 1<<29;
const double PI = acos(-1);
const double EPS = 1e-8;

struct Edge {
  int dst,t,m,v;
  Edge(int dst, int t, int m, int v) :
    dst(dst),t(t),m(m),v(v) {}
};

int n, T;
vector<Edge> g[300];

vector<int> tour;
vector<Edge> tourEdge;

void dfs(int now, int pre) {
  tour.push_back(now);
  FOR(it, g[now]) {
    if (it->dst == pre) continue;
    
    tourEdge.push_back(*it);
    dfs(it->dst, now);
    tourEdge.push_back(*it);
    tour.push_back(now);
  }
}

ll dp[600][10001];
int prev[300];

int deq[10001];
ll deqv[10001];

const ll NEGINF = -1e15;

int main() {
  while(cin >> n >> T) {
    REP(i,n) g[i].clear();
    REP(i,n-1) {
      int a, b, t,m,v;
      cin>>a>>b>>t>>m>>v;
      a--;b--;
      g[a].push_back(Edge(b,t,m,v));
      g[b].push_back(Edge(a,t,m,v));
    }

    tour.clear();
    tourEdge.clear();
    dfs(0,-1);

    assert(tour.size() == n*2-1);
    
    memset(dp,-1,sizeof(dp));
    memset(prev,-1,sizeof(prev));
    
    dp[0][0] = 0;
    
    REP(i,tour.size()-1) {
//      cout << i << ": " << tour[i+1]+1 << " " << tourEdge[i].dst+1 << " "<< tourEdge[i].m << endl;
//      cout << prev[tour[i+1]] << endl;
      if (prev[tour[i+1]] != -1) {
        REP(j,T+1) {
          chmax(dp[i+1][j], dp[prev[tour[i+1]]][j]);
        }
      }
      prev[tour[i]] = i;
      if (tour[i+1] == tourEdge[i].dst) {
        // 行き
        if (tourEdge[i].m >= 2) {
          int w = tourEdge[i].t * 2;
          REP(a,w) {
            int s = 0, t = 0;
            for (int j=0; j*w+a <= T; ++j) {
              if (j && deqv[s] != NEGINF) {
                assert(deq[s] != j);
                chmax(dp[i+1][j*w+a], deqv[s] + j*tourEdge[i].v*2);
              }
              
              if (deq[s] == j-tourEdge[i].m/2) s++;
              ll val = dp[i][j*w+a] - j*tourEdge[i].v*2;
              if (dp[i][j*w+a] == -1) val = NEGINF;
              while(s<t && deqv[t-1] <= val) t--;
              deq[t] = j;
              deqv[t++] = val;

            }
          }
        }
        if (tourEdge[i].m&1) {
          REP(j,T+1) {
            int t = j+(tourEdge[i].m+1)*tourEdge[i].t;
            if (t > T) break;
            if (dp[i][j] != -1) {
              // cout << ":"<<tourEdge[i].m << endl;
              chmax(dp[i+1][t], dp[i][j] + tourEdge[i].m*tourEdge[i].v);
            }
          }
        } else if (tourEdge[i].m == 0) {
          REP(j,T+1) {
            int t = j+2*tourEdge[i].t;
            if (t > T) break;
            chmax(dp[i+1][t], dp[i][j]);
          }
        }
      } else {
        REP(j,T+1) {
          chmax(dp[i+1][j], dp[i][j]);
        }
      }
      // REP(j,20) cout << (dp[i+1][j]<0?-1:dp[i+1][j]) << " "; cout << endl;
      
    }
    ll ans = 0;
    REP(t,T+1) {
      if (chmax(ans, dp[tour.size()-1][t])) {
        // cout << t << endl;
      }
    }
    cout << ans << endl;

  }
}
accuracy: 1
time_ms: 30
memory_kb: 48224
final_rank: 5

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cerr<<*i<<" "; cerr<<endl; }
inline bool valid(int x, int y, int W, int H){ return (x >= 0 && y >= 0 && x < W && y < H); }

typedef long long ll;
const ll INF = 1000000000000000000LL;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
struct Edge{
  int src, dst, t, m, v;
  Edge(int s, int d, int t, int m, int v) : 
    src(s), dst(d), t(t), m(m), v(v) {}
};
typedef vector<Edge> Node;
typedef vector<Node> Graph;

Graph G;
ll t[1000], m[1000], vl[1000];
int prev[1000];
int last[1000];
void dfs(int v, int p, int& k){
  prev[k] = (last[v] >= 0) ? last[v] : k;
  last[v] = k;
  k++;
  FORIT(e, G[v]){
    if(e->dst != p){
      t[k] = e->t;
      m[k] = e->m;
      vl[k] = e->v;

      dfs(e->dst, e->src, k);

      prev[k] = (last[v] >= 0) ? last[v] : k;
      last[v] = k;
      k++;
    }
  }
}
void update(ll& x, ll y){
  if(x < y) x = y;
}

int main(){
  ll N, T;
  while(cin >> N >> T){
    G = Graph(N);
    REP(i, N - 1){
      int a, b, t, m, v;
      cin >> a >> b >> t >> m >> v;
      a--; b--;
      G[a].push_back(Edge(a, b, t, m, v));
      G[b].push_back(Edge(b, a, t, m, v));
    }
    int K = 0;
    memset(last, -1, sizeof(last));
    memset(t, 0, sizeof(t));
    memset(m, 0, sizeof(m));
    memset(vl, 0, sizeof(vl));
    dfs(0, -1, K);
    static ll dp[610][10010] = {};
    REP(i, K) REP(j, T + 1) dp[i][j] = -INF;
    dp[0][0] = 0;
    for(int i = 1; i < K; i++){
      if(m[i] >= 2){
        for(ll u = 2 * t[i]; u <= T; u++) update(dp[i][u], dp[i - 1][u - 2 * t[i]] + 2 * vl[i]);
        ll rest = m[i] - 2;
        if(rest % 2 == 1) rest--;
        for(ll c = 2; rest >= 2; c <<= 1){
          ll mul = min(rest, c);
          for(ll u = T; u >= mul * t[i]; u--) update(dp[i][u], dp[i][u - mul * t[i]] + mul * vl[i]);
          rest -= mul;
        }
      }
      if(m[i] % 2 == 1){
        for(ll u = (m[i] + 1) * t[i]; u <= T; u++) update(dp[i][u], dp[i - 1][u - (m[i] + 1) * t[i]] + m[i] * vl[i]);
      }
      if(m[i] == 0){
        for(ll u = 2 * t[i]; u <= T; u++) update(dp[i][u], dp[i - 1][u - 2 * t[i]]);
      }
      for(ll u = 0; u <= T; u++) update(dp[i][u], dp[prev[i]][u]); 
    }
    ll ans = 0;
    for(ll i = 0; i <= T; i++) update(ans, dp[K - 1][i]);
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 48324
final_rank: 6

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cerr<<*i<<" "; cerr<<endl; }
inline bool valid(int x, int y, int W, int H){ return (x >= 0 && y >= 0 && x < W && y < H); }

typedef long long ll;
const ll INF = 1000000000000000000LL;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
struct Edge{
  int src, dst, t, m, v;
  Edge(int s, int d, int t, int m, int v) : 
    src(s), dst(d), t(t), m(m), v(v) {}
};
typedef vector<Edge> Node;
typedef vector<Node> Graph;

Graph G;
ll t[1000], m[1000], vl[1000];
int prev[1000];
int last[1000];
void dfs(int v, int p, int& k){
  prev[k] = (last[v] >= 0) ? last[v] : k;
  last[v] = k;
  k++;
  FORIT(e, G[v]){
    if(e->dst != p){
      t[k] = e->t;
      m[k] = e->m;
      vl[k] = e->v;

      dfs(e->dst, e->src, k);

      prev[k] = (last[v] >= 0) ? last[v] : k;
      last[v] = k;
      k++;
    }
  }
}
void update(ll& x, ll y){
  if(x < y) x = y;
}

int main(){
  ll N, T;
  while(cin >> N >> T){
    G = Graph(N);
    REP(i, N - 1){
      int a, b, t, m, v;
      cin >> a >> b >> t >> m >> v;
      a--; b--;
      G[a].push_back(Edge(a, b, t, m, v));
      G[b].push_back(Edge(b, a, t, m, v));
    }
    int K = 0;
    memset(last, -1, sizeof(last));
    memset(t, 0, sizeof(t));
    memset(m, 0, sizeof(m));
    memset(vl, 0, sizeof(vl));
    dfs(0, -1, K);
    static ll dp[610][10000] = {};
    REP(i, K) REP(j, T + 1) dp[i][j] = -INF;
    dp[0][0] = 0;
    /*
    for(int i = 1; i < K; i++){
      for(int u = 0; u <= T; u++){
        update(dp[i][u], dp[prev[i]][u]);
        if(u - 2 * t[i] >= 0) update(dp[i][u], dp[i - 1][u - 2 * t[i]]);
        for(int c = 2; c <= m[i]; c += 2){
          if(u - c * t[i] < 0) break;
          update(dp[i][u], dp[i - 1][u - c * t[i]] + c * vl[i]);
        }
        int mk = (m[i] + 1) / 2;
        if(m[i] % 2 == 1 && u - 2 * mk * t[i] >= 0) update(dp[i][u], dp[i - 1][u - 2 * mk * t[i]] + m[i] * vl[i]);
      }
    }
    */
    for(int i = 1; i < K; i++){
      if(m[i] >= 2){
        for(ll u = 2 * t[i]; u <= T; u++) update(dp[i][u], dp[i - 1][u - 2 * t[i]] + 2 * vl[i]);
        ll rest = m[i] - 2;
        if(rest % 2 == 1) rest--;
        for(ll c = 2; rest >= 2; c <<= 1){
          ll mul = min(rest, c);
          for(ll u = T; u >= mul * t[i]; u--) update(dp[i][u], dp[i][u - mul * t[i]] + mul * vl[i]);
          rest -= mul;
        }
      }
      if(m[i] % 2 == 1){
        for(ll u = (m[i] + 1) * t[i]; u <= T; u++) update(dp[i][u], dp[i - 1][u - (m[i] + 1) * t[i]] + m[i] * vl[i]);
      }
      if(m[i] == 0){
        for(ll u = 2 * t[i]; u <= T; u++) update(dp[i][u], dp[i - 1][u - 2 * t[i]]);
      }
      for(ll u = 0; u <= T; u++) update(dp[i][u], dp[prev[i]][u]); 
    }
    ll ans = 0;
    for(ll i = 0; i <= T; i++) update(ans, dp[K - 1][i]);
    cout << ans << endl;
  }
  return 0;
}
accuracy: 0.05714285714285714
time_ms: 40
memory_kb: 48320
final_rank: 16

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cerr<<*i<<" "; cerr<<endl; }
inline bool valid(int x, int y, int W, int H){ return (x >= 0 && y >= 0 && x < W && y < H); }

typedef long long ll;
const ll INF = 1000000000000000000LL;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
struct Edge{
  int src, dst, t, m, v;
  Edge(int s, int d, int t, int m, int v) : 
    src(s), dst(d), t(t), m(m), v(v) {}
};
typedef vector<Edge> Node;
typedef vector<Node> Graph;

Graph G;
int a[1000];
int t[1000], m[1000], vl[1000];
int prev[1000];
int last[1000];
void dfs(int v, int p, int& k){
  prev[k] = (last[v] >= 0) ? last[v] : k;
  last[v] = k;
  a[k++] = v;
  FORIT(e, G[v]){
    if(e->dst != p){
      t[k] = e->t;
      m[k] = e->m;
      vl[k] = e->v;

      dfs(e->dst, e->src, k);

      prev[k] = (last[v] >= 0) ? last[v] : k;
      last[v] = k;
      a[k++] = v;
    }
  }
}
void update(ll& x, ll y){
  if(x < y) x = y;
}

int main(){
  int N, T;
  while(cin >> N >> T){
    G = Graph(N);
    REP(i, N - 1){
      int a, b, t, m, v;
      cin >> a >> b >> t >> m >> v;
      a--; b--;
      G[a].push_back(Edge(a, b, t, m, v));
      G[b].push_back(Edge(b, a, t, m, v));
    }
    int K = 0;
    memset(last, -1, sizeof(last));
    memset(t, 0, sizeof(t));
    memset(m, 0, sizeof(m));
    memset(vl, 0, sizeof(vl));
    dfs(0, -1, K);
    static ll dp[610][10000] = {};
    REP(i, K) REP(j, T + 1) dp[i][j] = -INF;
    dp[0][0] = 0;
    /*
    for(int i = 1; i < K; i++){
      for(int u = 0; u <= T; u++){
        update(dp[i][u], dp[prev[i]][u]);
        if(u - 2 * t[i] >= 0) update(dp[i][u], dp[i - 1][u - 2 * t[i]]);
        for(int c = 2; c <= m[i]; c += 2){
          if(u - c * t[i] < 0) break;
          update(dp[i][u], dp[i - 1][u - c * t[i]] + c * vl[i]);
        }
        int mk = (m[i] + 1) / 2;
        if(m[i] % 2 == 1 && u - 2 * mk * t[i] >= 0) update(dp[i][u], dp[i - 1][u - 2 * mk * t[i]] + m[i] * vl[i]);
      }
    }
    */
    for(int i = 1; i < K; i++){
      if(m[i] >= 2){
        for(int u = 2 * t[i]; u <= T; u++) update(dp[i][u], dp[i - 1][u - 2 * t[i]] + 2 * vl[i]);
        ll rest = m[i] - 2;
        if(rest % 2 == 1) rest--;
        for(ll c = 2; rest >= 2; c <<= 1){
          ll mul = min(rest, c);
          for(int u = T; u >= mul * t[i]; u--) update(dp[i][u], dp[i][u - mul * t[i]] + mul * vl[i]);
          rest -= mul;
        }
      }
      if(m[i] % 2 == 1){
        int mk = (m[i] + 1) / 2;
        for(int u = 2 * mk * t[i]; u <= T; u++) update(dp[i][u], dp[i - 1][u - 2 * mk * t[i]] + m[i] * vl[i]);
      }
      if(m[i] == 0){
        for(int u = 2 * t[i]; u <= T; u++) update(dp[i][u], dp[i - 1][u - 2 * t[i]]);
      }
      for(int u = 0; u <= T; u++) update(dp[i][u], dp[prev[i]][u]); 
    }
    ll ans = 0;
    for(int i = 0; i <= T; i++) update(ans, dp[K - 1][i]);
    cout << ans << endl;
  }
  return 0;
}
accuracy: 0.05714285714285714
time_ms: 40
memory_kb: 48312
final_rank: 14

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cerr<<*i<<" "; cerr<<endl; }
inline bool valid(int x, int y, int W, int H){ return (x >= 0 && y >= 0 && x < W && y < H); }

typedef long long ll;
const ll INF = 1000000000000000000LL;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
struct Edge{
  int src, dst, t, m, v;
  Edge(int s, int d, int t, int m, int v) : 
    src(s), dst(d), t(t), m(m), v(v) {}
};
typedef vector<Edge> Node;
typedef vector<Node> Graph;

Graph G;
int a[1000];
int t[1000], m[1000], vl[1000];
int prev[1000];
int last[1000];
void dfs(int v, int p, int& k){
  prev[k] = (last[v] >= 0) ? last[v] : k;
  last[v] = k;
  a[k++] = v;
  FORIT(e, G[v]){
    if(e->dst != p){
      t[k] = e->t;
      m[k] = e->m;
      vl[k] = e->v;

      dfs(e->dst, e->src, k);

      prev[k] = (last[v] >= 0) ? last[v] : k;
      last[v] = k;
      a[k++] = v;
    }
  }
}
void update(ll& x, ll y){
  if(x < y) x = y;
}

int main(){
  int N, T;
  while(cin >> N >> T){
    G = Graph(N);
    REP(i, N - 1){
      int a, b, t, m, v;
      cin >> a >> b >> t >> m >> v;
      a--; b--;
      G[a].push_back(Edge(a, b, t, m, v));
      G[b].push_back(Edge(b, a, t, m, v));
    }
    int K = 0;
    memset(last, -1, sizeof(last));
    memset(t, 0, sizeof(t));
    memset(m, 0, sizeof(m));
    memset(vl, 0, sizeof(vl));
    dfs(0, -1, K);
    static ll dp[610][10000] = {};
    REP(i, K) REP(j, T + 1) dp[i][j] = -INF;
    dp[0][0] = 0;
    /*
    for(int i = 1; i < K; i++){
      for(int u = 0; u <= T; u++){
        update(dp[i][u], dp[prev[i]][u]);
        if(u - 2 * t[i] >= 0) update(dp[i][u], dp[i - 1][u - 2 * t[i]]);
        for(int c = 2; c <= m[i]; c += 2){
          if(u - c * t[i] < 0) break;
          update(dp[i][u], dp[i - 1][u - c * t[i]] + c * vl[i]);
        }
        int mk = (m[i] + 1) / 2;
        if(m[i] % 2 == 1 && u - 2 * mk * t[i] >= 0) update(dp[i][u], dp[i - 1][u - 2 * mk * t[i]] + m[i] * vl[i]);
      }
    }
    */
    for(int i = 1; i < K; i++){
      if(m[i] >= 2){
        for(int u = 2 * t[i]; u <= T; u++) update(dp[i][u], dp[i - 1][u - 2 * t[i]] + 2 * vl[i]);
        ll rest = m[i] - 2;
        if(rest % 2 == 1) rest--;
        for(ll c = 2; rest >= 2; c <<= 1){
          ll mul = min(rest, c);
          for(int u = T; u >= mul * t[i]; u--) update(dp[i][u], dp[i][u - mul * t[i]] + mul * vl[i]);
          rest -= mul;
        }
      }
      if(m[i] % 2 == 1){
        int mk = (m[i] + 1) / 2;
        for(int u = 2 * mk * t[i]; u <= T; u++) update(dp[i][u], dp[i - 1][u - 2 * mk * t[i]] + m[i] * vl[i]);
      }
      for(int u = 2 * t[i]; u <= T; u++) update(dp[i][u], dp[i - 1][u - 2 * t[i]]);
      for(int u = 0; u <= T; u++) update(dp[i][u], dp[prev[i]][u]); 
    }
    ll ans = 0;
    for(int i = 0; i <= T; i++) update(ans, dp[K - 1][i]);
    cout << ans << endl;
  }
  return 0;
}
accuracy: 0.05714285714285714
time_ms: 40
memory_kb: 48312
final_rank: 14

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cerr<<*i<<" "; cerr<<endl; }
inline bool valid(int x, int y, int W, int H){ return (x >= 0 && y >= 0 && x < W && y < H); }

typedef long long ll;
const ll INF = 1000000000000000000LL;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
struct Edge{
  int src, dst, t, m, v;
  Edge(int s, int d, int t, int m, int v) : 
    src(s), dst(d), t(t), m(m), v(v) {}
};
typedef vector<Edge> Node;
typedef vector<Node> Graph;

Graph G;
int a[1000];
int t[1000], m[1000], vl[1000];
int prev[1000];
int last[1000];
void dfs(int v, int p, int& k){
  prev[k] = (last[v] >= 0) ? last[v] : k;
  last[v] = k;
  a[k++] = v;
  FORIT(e, G[v]){
    if(e->dst != p){
      t[k] = e->t;
      m[k] = e->m;
      vl[k] = e->v;

      dfs(e->dst, e->src, k);

      prev[k] = (last[v] >= 0) ? last[v] : k;
      last[v] = k;
      a[k++] = v;
    }
  }
}
void update(ll& x, ll y){
  if(x < y) x = y;
}

int main(){
  int N, T;
  while(cin >> N >> T){
    G = Graph(N);
    REP(i, N - 1){
      int a, b, t, m, v;
      cin >> a >> b >> t >> m >> v;
      a--; b--;
      G[a].push_back(Edge(a, b, t, m, v));
      G[b].push_back(Edge(b, a, t, m, v));
    }
    int K = 0;
    memset(last, -1, sizeof(last));
    memset(t, 0, sizeof(t));
    memset(m, 0, sizeof(m));
    memset(vl, 0, sizeof(vl));
    dfs(0, -1, K);
    static ll dp[610][10000] = {};
    REP(i, K) REP(j, T + 1) dp[i][j] = -INF;
    dp[0][0] = 0;
    /*
    for(int i = 1; i < K; i++){
      for(int u = 0; u <= T; u++){
        update(dp[i][u], dp[prev[i]][u]);
        if(u - 2 * t[i] >= 0) update(dp[i][u], dp[i - 1][u - 2 * t[i]]);
        for(int c = 2; c <= m[i]; c += 2){
          if(u - c * t[i] < 0) break;
          update(dp[i][u], dp[i - 1][u - c * t[i]] + c * vl[i]);
        }
        int mk = (m[i] + 1) / 2;
        if(m[i] % 2 == 1 && u - 2 * mk * t[i] >= 0) update(dp[i][u], dp[i - 1][u - 2 * mk * t[i]] + m[i] * vl[i]);
      }
    }
    */
    for(int i = 1; i < K; i++){
      if(m[i] >= 2){
        for(int u = 2 * t[i]; u <= T; u++) update(dp[i][u], dp[i - 1][u - 2 * t[i]] + 2 * vl[i]);
        ll rest = m[i] - 2;
        for(ll c = 2; rest >= 2; c <<= 1){
          ll mul = min(rest, c);
          if(mul % 2 == 1) mul--;
          for(int u = T; u >= mul * t[i]; u--) update(dp[i][u], dp[i][u - mul * t[i]] + mul * vl[i]);
          rest -= mul;
        }
      }
      int mk = (m[i] + 1) / 2;
      for(int u = 2 * mk * t[i]; u <= T; u++) update(dp[i][u], dp[i - 1][u - 2 * mk * t[i]] + m[i] * vl[i]);
      for(int u = 0; u <= T; u++) update(dp[i][u], dp[prev[i]][u]);
    }
    ll ans = 0;
    for(int i = 0; i <= T; i++) update(ans, dp[K - 1][i]);
    cout << ans << endl;
  }
  return 0;
}
accuracy: 0.014285714285714285
time_ms: 10
memory_kb: 45740
final_rank: 19

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cerr<<*i<<" "; cerr<<endl; }
inline bool valid(int x, int y, int W, int H){ return (x >= 0 && y >= 0 && x < W && y < H); }

typedef long long ll;
const ll INF = 1000000000000000000LL;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
struct Edge{
  int src, dst, t, m, v;
  Edge(int s, int d, int t, int m, int v) : 
    src(s), dst(d), t(t), m(m), v(v) {}
};
typedef vector<Edge> Node;
typedef vector<Node> Graph;

Graph G;
int a[1000];
int t[1000], m[1000], vl[1000];
int prev[1000];
int last[1000];
void dfs(int v, int p, int& k){
  prev[k] = (last[v] >= 0) ? last[v] : k;
  last[v] = k;
  a[k++] = v;
  FORIT(e, G[v]){
    if(e->dst != p){
      t[k] = e->t;
      m[k] = e->m;
      vl[k] = e->v;

      dfs(e->dst, e->src, k);

      prev[k] = (last[v] >= 0) ? last[v] : k;
      last[v] = k;
      a[k++] = v;
    }
  }
}
void update(ll& x, ll y){
  if(x < y) x = y;
}

int main(){
  int N, T;
  while(cin >> N >> T){
    G = Graph(N);
    REP(i, N - 1){
      int a, b, t, m, v;
      cin >> a >> b >> t >> m >> v;
      a--; b--;
      G[a].push_back(Edge(a, b, t, m, v));
      G[b].push_back(Edge(b, a, t, m, v));
    }
    int K = 0;
    memset(last, -1, sizeof(last));
    memset(t, 0, sizeof(t));
    memset(m, 0, sizeof(m));
    memset(vl, 0, sizeof(vl));
    dfs(0, -1, K);
    static ll dp[610][10000] = {};
    REP(i, K) REP(j, T + 1) dp[i][j] = -INF;
    dp[0][0] = 0;
    /*
    for(int i = 1; i < K; i++){
      for(int u = 0; u <= T; u++){
        update(dp[i][u], dp[prev[i]][u]);
        if(u - 2 * t[i] >= 0) update(dp[i][u], dp[i - 1][u - 2 * t[i]]);
        for(int c = 2; c <= m[i]; c += 2){
          if(u - c * t[i] < 0) break;
          update(dp[i][u], dp[i - 1][u - c * t[i]] + c * vl[i]);
        }
        int mk = (m[i] + 1) / 2;
        if(m[i] % 2 == 1 && u - 2 * mk * t[i] >= 0) update(dp[i][u], dp[i - 1][u - 2 * mk * t[i]] + m[i] * vl[i]);
      }
    }
    */
    for(int i = 1; i < K; i++){
      for(int u = 2 * t[i]; u <= T; u++) update(dp[i][u], dp[i - 1][u - 2 * t[i]] + 2 * vl[i]);
      ll rest = m[i] - 2;
      for(ll c = 2; rest >= 2; c <<= 1){
        ll mul = min(rest, c);
        if(mul % 2 == 1) mul--;
        for(int u = T; u >= mul * t[i]; u--) update(dp[i][u], dp[i][u - mul * t[i]] + mul * vl[i]);
        rest -= mul;
      }
      int mk = (m[i] + 1) / 2;
      for(int u = 2 * mk * t[i]; u <= T; u++) update(dp[i][u], dp[i - 1][u - 2 * mk * t[i]] + m[i] * vl[i]);
      for(int u = 0; u <= T; u++) update(dp[i][u], dp[prev[i]][u]);
    }
    ll ans = 0;
    for(int i = 0; i <= T; i++) update(ans, dp[K - 1][i]);
    cout << ans << endl;
  }
  return 0;
}
accuracy: 0.014285714285714285
time_ms: 20
memory_kb: 45736
final_rank: 20

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cerr<<*i<<" "; cerr<<endl; }
inline bool valid(int x, int y, int W, int H){ return (x >= 0 && y >= 0 && x < W && y < H); }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
struct Edge{
  int src, dst, t, m, v;
  Edge(int s, int d, int t, int m, int v) : 
    src(s), dst(d), t(t), m(m), v(v) {}
};
typedef vector<Edge> Node;
typedef vector<Node> Graph;

Graph G;
int a[1000];
int t[1000], m[1000], vl[1000];
int prev[1000];
int last[1000];
void dfs(int v, int p, int& k){
  prev[k] = (last[v] >= 0) ? last[v] : k;
  last[v] = k;
  a[k++] = v;
  FORIT(e, G[v]){
    if(e->dst != p){
      t[k] = e->t;
      m[k] = e->m;
      vl[k] = e->v;

      dfs(e->dst, e->src, k);

      prev[k] = (last[v] >= 0) ? last[v] : k;
      last[v] = k;
      a[k++] = v;
    }
  }
}
void update(int& x, int y){
  if(x < y) x = y;
}

int main(){
  int N, T;
  while(cin >> N >> T){
    G = Graph(N);
    REP(i, N - 1){
      int a, b, t, m, v;
      cin >> a >> b >> t >> m >> v;
      a--; b--;
      G[a].push_back(Edge(a, b, t, m, v));
      G[b].push_back(Edge(b, a, t, m, v));
    }
    int K = 0;
    memset(last, -1, sizeof(last));
    memset(t, 0, sizeof(t));
    memset(m, 0, sizeof(m));
    memset(vl, 0, sizeof(vl));
    dfs(0, -1, K);
    static int dp[610][10000] = {};
    REP(i, K) REP(j, T + 1) dp[i][j] = -INF;
    dp[0][0] = 0;
    for(int i = 1; i < K; i++){
      for(int u = 0; u <= T; u++){
        update(dp[i][u], dp[prev[i]][u]);
        if(u - 2 * t[i] >= 0) update(dp[i][u], dp[i - 1][u - 2 * t[i]]);
        for(int k = 1; 2 * k <= m[i]; k++){
          if(u - 2 * k * t[i] < 0) break;
          update(dp[i][u], dp[i - 1][u - 2 * k * t[i]] + 2 * k * vl[i]);
        }
        int mk = (m[i] + 1) / 2;
        if(u - 2 * mk * t[i] >= 0) update(dp[i][u], dp[i - 1][u - 2 * mk * t[i]] + m[i] * vl[i]);
      }
    }
    int ans = 0;
    for(int i = 0; i <= T; i++) update(ans, dp[K - 1][i]);
    cout << ans << endl;
  }
  return 0;
}
accuracy: 0.014285714285714285
time_ms: 50
memory_kb: 23312
final_rank: 18

code_snippet: #include<stdio.h>
#include<iostream>
#include<vector>
#include<map>
#include<queue>
#include<string.h>
#include<algorithm>
struct Way{
	int to;
	long long int t,m,v;
};
struct S{
	long long int v,t;
	bool operator<(const S& s)const{
		return t>s.t;
	}
};

const int size=301;
const int tMax=10001;

std::vector<Way> G[size];
long long int values[size][tMax];

void saiki(int parent,int now,Way w1,int T){
	int t1;
	long long int v1;
	if(parent!=0){
		std::vector<S> tempV;
		S s1;
		for(int i=0;i<=T;i+=2){
			s1.t=i;
			s1.v=values[parent][i];
			if(s1.v!=-1)tempV.push_back(s1);
		}
		std::sort(tempV.begin(),tempV.end());
		for(int i=0;i<tempV.size();i++){
			long long int baseV=tempV[i].v;
			for(long long int j=2;j<=w1.m+1+(w1.m==0);j+=2){
				t1=j*w1.t+tempV[i].t;
				if(t1>T)break;
				v1=(j>=w1.m?w1.m:j)*w1.v+baseV;
				if(values[now][t1]<v1)values[now][t1]=v1;
				else break;
			}
		}
	}
	for(int i=0;i<G[now].size();i++){
		w1=G[now][i];
		if(parent!=w1.to){
			saiki(now,w1.to,w1,T);
			for(int j=0;j<=T;j++){
				if(values[now][j]<values[w1.to][j])values[now][j]=values[w1.to][j];
			}
		}
	}
}

int main(){
	int N,T,a,b;
	Way w1;
	long long int t1,m1;
	memset(values,-1,sizeof(values));
	
	scanf("%d %d",&N,&T);
	T=T-T%2;
	for(int i=0;i<N-1;i++){
		scanf("%d %d",&a,&b);
		std::cin>>w1.t>>w1.m>>w1.v;
		w1.to=b;
		G[a].push_back(w1);
		w1.to=a;
		G[b].push_back(w1);
	}
	values[1][0]=0;
	saiki(0,1,w1,T);
	long long int ans=0;
	for(int i=0;i<=T;i+=2){
		if(values[1][i]>ans)ans=values[1][i];
	}
	std::cout<<ans<<"\n";
}
accuracy: 1
time_ms: 270
memory_kb: 24996
final_rank: 9

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
#include <cfloat>
#include <ctime>
#include <cassert>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <numeric>
#include <list>
#include <iomanip>
#include <fstream>
#include <bitset>
   
using namespace std;
   
 
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define foreach(it, c) for (__typeof__((c).begin()) it=(c).begin(); it != (c).end(); ++it)
#define rforeach(it, c) for (__typeof__((c).rbegin()) it=(c).rbegin(); it != (c).rend(); ++it)
#define all(c) (c).begin(), (c).end()
#define rall(c) (c).rbegin(), (c).rend()
#define CL(arr, val) memset(arr, val, sizeof(arr))
#define COPY(dest, src) memcpy(dest, src, sizeof(dest))
#define ten(n) ((long long)(1e##n))
#define bin(n) (1ull << (n))
#define erep(i, n) for (int i = 0; i <= (int)(n); ++i)
#define revrep(i, n) for (int i = (n); i >= 0; --i)
#define pb push_back

template <class T> void chmax(T& a, const T& b) { a = max(a, b); }
template <class T> void chmin(T& a, const T& b) { a = min(a, b); }

template <class T> void uniq(T& c) { sort(c.begin(), c.end()); c.erase(unique(c.begin(), c.end()), c.end()); }
 
template <class T> string to_s(const T& a) { ostringstream os; os << a; return os.str(); }
template <class T> T to_T(const string& s) { istringstream is(s); T res; is >> res; return res; }
  
template <class T, class U> ostream& operator<<(ostream& os, pair<T, U>& p) { os << "( " << p.first << ", " << p.second << " )"; return os; }
  
template <class T> void print(T a, int n, const string& deli = " ", int br = 1) { for (int i = 0; i < n; ++i) { cout << a[i]; if (i + 1 != n) cout << deli; } while (br--) cout << endl; }
template <class T> void print(const T& c, const string& deli = " ", int br = 1) { foreach (it, c) { cout << *it; if (++it != c.end()) cout << deli;--it; } while (br--) cout << endl; }
template <class T> void print2d(T a, int w, int h, int width = -1, int br = 1) { for (int i = 0; i < h; ++i) { for (int j = 0; j < w; ++j) {    if (width != -1) cout.width(width); cout << a[i][j] << ' '; } cout << endl; } while (br--) cout << endl; }
   
template <class T> void input(T& a, int n) { for (int i = 0; i < n; ++i) cin >> a[i]; }
template <class T> void input(T* a, int n) { for (int i = 0; i < n; ++i) cin >> a[i]; }

void fix_pre(int n) { cout.setf(ios::fixed, ios::floatfield); cout.precision(10); }
void fast_io() { cin.tie(0); ios::sync_with_stdio(false); }
#define trace(x) (cout << #x << ": " << (x) << endl)
 
bool in_rect(int x, int y, int w, int h) { return 0 <= x && x < w && 0 <= y && y < h; }


typedef long long ll;
typedef pair<int, int> pint;
 
// y(v): v>^<  y(^): ^>v<
const int dx[] = { 0, 1, 0, -1 };
const int dy[] = { 1, 0, -1, 0 };

const double PI = acos(-1.0);


struct Edge
{
    int to, t, m, v;
};
vector<Edge> g[305];
int prev[610];
ll t[610], m[610], v[610];
void dfs(int pos, int par, int& n)
{
    prev[n] = -1;

    rep(i, g[pos].size())
    {
        const Edge& e = g[pos][i];
        if (e.to != par)
        {
            t[n] = e.t, m[n] = e.m, v[n] = e.v;
            int prev_n = n++;

            dfs(e.to, pos, n);

            prev[n] = prev_n;
        }
    }

    ++n;
}
int main()
{
    int _n, T;
    cin >> _n >> T;
    T /= 2; // round
    rep(i, _n - 1)
    {
        int a, b, _t, _m, _v;
        cin >> a >> b >> _t >> _m >> _v;
        --a, --b;
        g[a].pb((Edge){ b, _t, _m, _v });
        g[b].pb((Edge){ a, _t, _m, _v });
    }

    int n = 0;
    dfs(0, -1, n);

    const ll inf = ten(16);
    static ll dp[610][ten(4) / 2 + 10];
    erep(i, n) erep(j, T)
        dp[i][j] = -inf;
    dp[0][0] = 0;

    rep(i, n)
    {
        if (prev[i] != -1)
        {
            // ignore subtree
            erep(j, T)
                chmax(dp[i][j], dp[prev[i]][j]);
        }

        if (m[i] == 0)
        {
            for (int j = 0; j + t[i] <= T; ++j)
                chmax(dp[i + 1][j + t[i]], dp[i][j]);
        }
        else
        {
            bool odd_m = m[i] & 1;
            v[i] *= 2, m[i] /= 2; // round

            for (int peri = 0; peri < t[i]; ++peri)
            {
                // (round, val)
                // q[i].first < q[i + 1].first && q[i].second > q[i + 1].second
                static deque<pair<int, ll> > q;
                q.clear();
                for (int round = 0; peri + round * t[i] <= T; ++round)
                {
                    int j = peri + round * t[i];

                    if (!q.empty() && round - q.front().first > m[i])
                        q.pop_front();

                    // need at least one round
                    if (!q.empty() && round - q.front().first > 0)
                        chmax(dp[i + 1][j], q.front().second + round * v[i]);

                    ll val = dp[i][j] - round * v[i];
                    while (!q.empty() && q.back().second <= val)
                        q.pop_back();
                    q.push_back(make_pair(round, val));

                    if (odd_m && round - q.front().first == m[i] && j + t[i] <= T)
                        chmax(dp[i + 1][j + t[i]], q.front().second + round * v[i] + v[i] / 2);
                }
            }
        }
    }

    ll res = 0;
    erep(j, T)
        chmax(res, dp[n][j]);
    cout << res << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 24840
final_rank: 1

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

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

const int INF=1<<29;

const int V_MAX=300;
const int E_MAX=V_MAX-1;
const int T_MAX=10000;

struct edge{ int v,cost,capa,val; };

int n;
vector<edge> G[V_MAX]; // tree

vector< pair<edge,int> > order; // <<to,cost,capa,val>,forward or backward>

void dfs(int u,int pre){
	int cost_parent=0,capa_parent=0,val_parent=0;

	rep(i,G[u].size()){
		int v=G[u][i].v,cost=G[u][i].cost,capa=G[u][i].capa,val=G[u][i].val;
		if(v!=pre){
			order.push_back(make_pair((edge){u,cost,capa,val},0)); // forward
			dfs(v,u);
		}
		else{
			cost_parent=cost;
			capa_parent=capa;
			val_parent=val;
		}
	}

	order.push_back(make_pair((edge){u,cost_parent,capa_parent,val_parent},1)); // backward
}

int main(){
	int T; scanf("%d%d",&n,&T);
	rep(u,n) G[u].clear();
	rep(i,n-1){
		int u,v,cost,capa,val;
		scanf("%d%d%d%d%d",&u,&v,&cost,&capa,&val); u--; v--;
		G[u].push_back((edge){v,cost,capa,val});
		G[v].push_back((edge){u,cost,capa,val});
	}

	order.clear();
	dfs(0,-1);

	int m=order.size();
	static int pre[V_MAX+E_MAX];
	rep(i,m){
		pre[i]=-1;
		int u=order[i].first.v;
		rep(j,i){
			int v=order[j].first.v;
			if(u==v) pre[i]=j;
		}
	}

	static int dp[V_MAX+E_MAX][T_MAX+1];
	rep(i,m) rep(j,T+1) dp[i][j]=-INF;
	dp[0][0]=0;
	for(int i=1;i<m;i++){
		int cost=order[i-1].first.cost;
		int capa=order[i-1].first.capa;
		int val=order[i-1].first.val;
		int dir=order[i-1].second;

		rep(j,T+1) if(pre[i]!=-1) dp[i][j]=max(dp[i][j],dp[pre[i]][j]);

		if(dir==0){ // forward
			if(capa%2==1){
				for(int j=(capa+1)*cost;j<=T;j++){
					dp[i][j]=max(dp[i][j],dp[i-1][j-(capa+1)*cost]+capa*val);
				}
				capa--;
			}

			if(capa==0){
				for(int j=2*cost;j<=T;j++) dp[i][j]=max(dp[i][j],dp[i-1][j-2*cost]);
			}
			else{ // capa>=2
				capa-=2;
				for(int c=2;capa>0;c*=2){ // O(log capa) 個の商品に分割
					c=min(c,capa);
					for(int j=T;j>=c*cost;j--){
						dp[i-1][j]=max(dp[i-1][j],dp[i-1][j-c*cost]+c*val);
					}
					capa-=c;
				}

				for(int j=2*cost;j<=T;j++) dp[i][j]=max(dp[i][j],dp[i-1][j-2*cost]+2*val);
			}
		}
		else{ // backward
			rep(j,T+1) dp[i][j]=max(dp[i][j],dp[i-1][j]);
		}
	}

	printf("%d\n",*max_element(dp[m-1],dp[m-1]+T+1));

	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 24544
final_rank: 3

code_snippet: #include <iostream>
#include <map>
#include <cstring>
#include <vector>
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;

int N,T;

struct Edge{
	int a,b,t,m,v;
	Edge(){}
	Edge(int a,int b,int t,int m,int v) : a(a), b(b), t(t), m(m), v(v) {}
};
vector<Edge> g[310];
vector<int> seg;
vector<int> rev;
int gen_seg(int x,int p){
	seg.push_back(x);
	rev.push_back(0);
	for(int i = 0 ; i < g[x].size() ; i++){
		if( g[x][i].b != p ) gen_seg(g[x][i].b,x);
	}
	if( p != -1 ) seg.push_back(p) , rev.push_back(1);
}
vector<int> pos[310];

vector<Edge> G[310];

long long dp[610][10010] = {};
long long dp2[10010] = {};

map< pair<int,int> , Edge > info;



int main(){
	for(int i = 0 ; i < 610 ; i++)
		for(int j = 0 ; j < 10010 ; j++)
			dp[i][j] = -1e12;
	
	cin >> N >> T;
	for(int i = 0; i < N-1 ; i++){
		int a,b,t,m,v;
		cin >> a >> b >> t >> m >> v;
		a--,b--;
		g[a].push_back(Edge(a,b,t,m,v));
		g[b].push_back(Edge(b,a,t,m,v));
		info[make_pair(a,b)] = info[make_pair(b,a)] = Edge(a,b,t,m,v);
	}
	gen_seg(0,-1);
	for(int i = 0 ; i < seg.size() ; i++)
		pos[seg[i]].push_back(i);
	dp[0][0] = 0;
	for(int i = 0 ; i+1 < seg.size() ; i++){
		Edge e = info[make_pair(seg[i],seg[i+1])];
		if( rev[i+1] ){
			for(int j = 0 ; j <= T ; j++){
				dp[i+1][j] = max(dp[i+1][j],dp[i][j]);
			}
		}else{
			// use
			int m = e.m / 2, v = e.v * 2, t = e.t * 2;
			for(int j = 0 ; j <= T ; j++) dp2[j] = -1e12;
			if( m > 0 ){
				//ikkai ugoku
				m--;
				for(int j = t ; j <= T ; j++) dp2[j] = dp[i][j-t]+v;
				if(e.m%2){
					for(int j = T ; j >= 2*e.t ; j--){
						dp2[j] = max(dp2[j],dp2[j-2*e.t]+e.v);
					}
				}
			}else{
				// ikkai ugoku
				if(e.m%2)
					for(int j = 2*e.t ; j <= T ; j++) dp2[j] = dp[i][j-2*e.t]+e.v;
			}
			// muda ni move
			for(int j = t ; j <= T ; j++)
				dp2[j] = max(dp2[j],dp[i][j-t]);
				
			for(int k = 1; m > 0 ; k *= 2 ){
				int wei = min(m,k);
				int VV = v * wei;
				int TT = t * wei;
				for(int j = T ; j >= TT ; j--){
					dp2[j] = max(dp2[j],dp2[j-TT]+VV);
				}
				m -= wei;
			}
			
			for(int j = 0 ; j <= T ; j++)
				dp[i+1][j] = max(dp[i+1][j],dp2[j]);
			
			// unuse
			int next = *upper_bound(pos[seg[i]].begin(),pos[seg[i]].end(),i);
			for(int j = 0 ; j <= T ; j++){
				dp[next][j] = max(dp[next][j],dp[i][j]);
			}
		}
	}
	cout << *max_element(dp[seg.size()-1],dp[seg.size()-1]+T+1) << endl;
	
	
	
	
}
accuracy: 1
time_ms: 60
memory_kb: 49112
final_rank: 7

code_snippet: #include <iostream>
#include <map>
#include <cstring>
#include <vector>
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;

int N,T;

struct Edge{
	int a,b;
	long long t,m,v;
	Edge(){}
	Edge(int a,int b,long long t,long long m,long long v) : a(a), b(b), t(t), m(m), v(v) {}
};
vector<Edge> g[310];
vector<int> seg;
vector<int> rev;
int gen_seg(int x,int p){
	seg.push_back(x);
	rev.push_back(0);
	for(int i = 0 ; i < g[x].size() ; i++){
		if( g[x][i].b != p ) gen_seg(g[x][i].b,x);
	}
	if( p != -1 ) seg.push_back(p) , rev.push_back(1);
}
vector<int> pos[310];

vector<Edge> G[310];

long long dp[610][10010] = {};
long long dp2[10010] = {};

map< pair<int,int> , Edge > info;



int main(){
	for(int i = 0 ; i < 610 ; i++)
		for(int j = 0 ; j < 10010 ; j++)
			dp[i][j] = -1e12;
	
	cin >> N >> T;
	for(int i = 0; i < N-1 ; i++){
		int a,b,t,m,v;
		cin >> a >> b >> t >> m >> v;
		a--,b--;
		g[a].push_back(Edge(a,b,t,m,v));
		g[b].push_back(Edge(b,a,t,m,v));
		info[make_pair(a,b)] = info[make_pair(b,a)] = Edge(a,b,t,m,v);
	}
	gen_seg(0,-1);
	/*for(int i = 0 ; i < seg.size() ; i++)
		cout << seg[i] << " ";
	cout << endl;
	for(int i = 0 ; i < rev.size() ; i++)
		cout << rev[i] << " ";
	cout << endl;
	*/
	for(int i = 0 ; i < seg.size() ; i++)
		pos[seg[i]].push_back(i);
	dp[0][0] = 0;
	for(int i = 0 ; i+1 < seg.size() ; i++){
		Edge e = info[make_pair(seg[i],seg[i+1])];
		/*for(int j = 0 ; j <= T ; j++){
			if( dp[i][j] >= 0 ) cout << "[" << i << "][" << j << "] = " << dp[i][j] << endl;
		}*/
		if( rev[i+1] ){
			for(int j = 0 ; j <= T ; j++){
				dp[i+1][j] = max(dp[i+1][j],dp[i][j]);
			}
		}else{
			// use
			long long m = e.m / 2, v = e.v * 2, t = e.t * 2;
			for(int j = 0 ; j <= T ; j++) dp2[j] = -1e12;
			if( m > 0 ){
				//ikkai ugoku
				m--;
				for(int j = t ; j <= T ; j++) dp2[j] = dp[i][j-t]+v;
				if(e.m%2){
					for(int j = T ; j >= 2*e.t ; j--){
						dp2[j] = max(dp2[j],dp2[j-2*e.t]+e.v);
					}
				}
			}else{
				// ikkai ugoku
				if(e.m%2)
					for(int j = 2*e.t ; j <= T ; j++) dp2[j] = dp[i][j-2*e.t]+e.v;
			}
			// muda ni move
			for(int j = t ; j <= T ; j++)
				dp2[j] = max(dp2[j],dp[i][j-t]);
				
			for(long long k = 1; m > 0 ; k *= 2 ){
				long long wei = min(m,k);
				long long VV = v * wei;
				long long TT = t * wei;
				for(int j = T ; j >= TT ; j--){
					dp2[j] = max(dp2[j],dp2[j-TT]+VV);
				}
				m -= wei;
			}
			
			for(int j = 0 ; j <= T ; j++)
				dp[i+1][j] = max(dp[i+1][j],dp2[j]);
			
			// unuse
			int next = *upper_bound(pos[seg[i]].begin(),pos[seg[i]].end(),i);
			for(int j = 0 ; j <= T ; j++){
				dp[next][j] = max(dp[next][j],dp[i][j]);
			}
		}
	}
	cout << *max_element(dp[seg.size()-1],dp[seg.size()-1]+T+1) << endl;
	
	
	
	
}
accuracy: 1
time_ms: 70
memory_kb: 49116
final_rank: 10

code_snippet: #include <iostream>
#include <map>
#include <cstring>
#include <vector>
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;

int N,T;

struct Edge{
	int a,b;
	long long t,m,v;
	Edge(){}
	Edge(int a,int b,long long t,long long m,long long v) : a(a), b(b), t(t), m(m), v(v) {}
};
vector<Edge> g[310];
vector<int> seg;
vector<int> rev;
int gen_seg(int x,int p){
	seg.push_back(x);
	rev.push_back(0);
	for(int i = 0 ; i < g[x].size() ; i++){
		if( g[x][i].b != p ) gen_seg(g[x][i].b,x);
	}
	if( p != -1 ) seg.push_back(p) , rev.push_back(1);
}
vector<int> pos[310];

vector<Edge> G[310];

long long dp[610][10010] = {};
long long dp2[10010] = {};

map< pair<int,int> , Edge > info;



int main(){
	for(int i = 0 ; i < 310 ; i++)
		for(int j = 0 ; j < 10010 ; j++)
			dp[i][j] = -1e12;
	
	cin >> N >> T;
	for(int i = 0; i < N-1 ; i++){
		int a,b,t,m,v;
		cin >> a >> b >> t >> m >> v;
		a--,b--;
		g[a].push_back(Edge(a,b,t,m,v));
		g[b].push_back(Edge(b,a,t,m,v));
		info[make_pair(a,b)] = info[make_pair(b,a)] = Edge(a,b,t,m,v);
	}
	gen_seg(0,-1);
	/*for(int i = 0 ; i < seg.size() ; i++)
		cout << seg[i] << " ";
	cout << endl;
	for(int i = 0 ; i < rev.size() ; i++)
		cout << rev[i] << " ";
	cout << endl;
	*/
	for(int i = 0 ; i < seg.size() ; i++)
		pos[seg[i]].push_back(i);
	dp[0][0] = 0;
	for(int i = 0 ; i+1 < seg.size() ; i++){
		Edge e = info[make_pair(seg[i],seg[i+1])];
		/*for(int j = 0 ; j <= T ; j++){
			if( dp[i][j] >= 0 ) cout << "[" << i << "][" << j << "] = " << dp[i][j] << endl;
		}*/
		if( rev[i+1] ){
			for(int j = 0 ; j <= T ; j++){
				dp[i+1][j] = max(dp[i+1][j],dp[i][j]);
			}
		}else{
			// use
			long long m = e.m / 2, v = e.v * 2, t = e.t * 2;
			for(int j = 0 ; j <= T ; j++) dp2[j] = -1e12;
			if( m > 0 ){
				//ikkai ugoku
				m--;
				for(int j = t ; j <= T ; j++) dp2[j] = dp[i][j-t]+v;
				if(e.m%2){
					for(int j = T ; j >= 2*e.t ; j--){
						dp2[j] = max(dp2[j],dp2[j-2*e.t]+e.v);
					}
				}
			}else{
				// ikkai ugoku
				if(e.m%2)
					for(int j = 2*e.t ; j <= T ; j++) dp2[j] = dp[i][j-2*e.t]+e.v;
			}
			// muda ni move
			for(int j = t ; j <= T ; j++)
				dp2[j] = max(dp2[j],dp[i][j-t]);
				
			for(long long k = 1; m > 0 ; k *= 2 ){
				long long wei = min(m,k);
				long long VV = v * wei;
				long long TT = t * wei;
				for(int j = T ; j >= TT ; j--){
					dp2[j] = max(dp2[j],dp2[j-TT]+VV);
				}
				m -= wei;
			}
			
			for(int j = 0 ; j <= T ; j++)
				dp[i+1][j] = max(dp[i+1][j],dp2[j]);
			
			// unuse
			int next = *upper_bound(pos[seg[i]].begin(),pos[seg[i]].end(),i);
			for(int j = 0 ; j <= T ; j++){
				dp[next][j] = max(dp[next][j],dp[i][j]);
			}
		}
	}
	cout << *max_element(dp[seg.size()-1],dp[seg.size()-1]+T+1) << endl;
	
	
	
	
}
accuracy: 0.11428571428571428
time_ms: 50
memory_kb: 48424
final_rank: 12