#include <stdio.h>
#include <vector>
#include <algorithm>
#include <string.h>
using namespace std;
#define INPUT freopen("/Users/grh/Programming/CLionProjects/SimpleTest/input.txt", "r", stdin)
const int N = 200005;
vector<pair<int, int>> link[2 * N];
int node_stat[N]; // 节点是否存在
int tot_dis2min_dep[1000005]; // 距离到最少边数的映射
vector<pair<int, int>> buf(1000005);
vector<int> tot_dis_buf(1000005);
// 计算子树的大小
int get_tree_size(int node, int prev) {
if (node_stat[node] == 0) {
return 0;
}
int sum = 1;
for (auto nei : link[node]) {
if (nei.first != prev && node_stat[nei.first] == 1) {
sum += get_tree_size(nei.first, node);
}
}
return sum;
}
// 求取重心, 函数返回子树的大小
int get_center(int node, int prev, int tot, int& center_node, int& min_wei) {
int ans = 1;
int wei = 0;
for (auto nei : link[node]) {
if (nei.first != prev && node_stat[nei.first] == 1) {
int sub_size = get_center(nei.first, node, tot, center_node, min_wei);
wei = max(wei, sub_size);
ans += sub_size;
}
}
wei = max(wei, tot - ans);
if (wei < min_wei) {
min_wei = wei;
center_node = node;
}
return ans;
}
// 求取重心
int get_center(int node) {
int tot = get_tree_size(node, -1);
int center_node = -1, min_wei = 0x7fffffff;
get_center(node, -1, tot, center_node, min_wei);
// 此时计算完了min_wei就是重心的最大子树的大小(包括其父节点开始的特殊的逆向的子树)
return center_node;
}
void find_dis_min_dep(int node, int prev, int cur_dep, int cur_dis, int K, vector<pair<int, int>>& buf) {
if (cur_dis > K) {
return;
}
buf.push_back(pair<int, int>{cur_dis, cur_dep});
for (auto nei : link[node]) {
if (nei.first != prev and node_stat[nei.first] == 1) {
find_dis_min_dep(nei.first, node, cur_dep + 1, cur_dis + nei.second, K, buf);
}
}
}
int solve(int node, int K) {
int tot_ans = 0x7fffffff;
if (node_stat[node] == 0) {
return tot_ans;
}
int center_node = get_center(node);
node_stat[center_node] = 0;
// 处理第三类,两个端点都在子树里面,处理时候逐个子树处理,统计每一个子树里面节点到重心的距离,统计同一个距离能够达成的最少边数,
// 全局不断合并每一个子树的信息,当前子树就使用当期那子树信息和前面已经枚举过的所有子树的信息来统计一个端点在当期那子树,另一个
// 端点在前面已经枚举过的子树的情况
tot_dis_buf.clear();
for (auto nei : link[center_node]) {
if (node_stat[nei.first] == 1) {
buf.clear();
find_dis_min_dep(nei.first, center_node, 1, nei.second, K, buf);
for (auto& p : buf) {
int dis = p.first;
int dep = p.second;
// 处理第二类,一个点在重心,另外一个点在子树内部
if (dis == K) {
tot_ans = min(tot_ans, dep);
}
int target_dis = K - dis;
if (tot_dis2min_dep[target_dis] != 0x3f3f3f3f) {
tot_ans = min(tot_ans, tot_dis2min_dep[target_dis] + dep);
}
}
for (auto& p : buf) {
int dis = p.first;
int dep = p.second;
tot_dis2min_dep[dis] = min(tot_dis2min_dep[dis], dep);
tot_dis_buf.push_back(dis);
}
}
}
// 恢复tot_dis2min_dep的现场
for (auto dis : tot_dis_buf) {
tot_dis2min_dep[dis] = 0x3f3f3f3f;
}
// 处理第一类,两个端点都在子树内部
for (auto nei : link[center_node]) {
if (node_stat[nei.first] == 1) {
tot_ans = min(tot_ans, solve(nei.first, K));
}
}
node_stat[center_node] = 1;
return tot_ans;
}
int main() {
//INPUT;
int N, K;
int a, b, w;
scanf("%d %d", &N, &K);
for (int i = 0; i < N; i++) {
link[i].clear();
node_stat[i] = 1;
}
memset(tot_dis2min_dep, 0x3f, sizeof(tot_dis2min_dep));
// 添加邻接表,边上包含权值
for (int i = 0; i < N-1; i++) {
scanf("%d %d %d", &a, &b, &w);
link[a].push_back(pair<int, int>{b, w});
link[b].push_back(pair<int, int>{a, w});
}
// 随便以一个点作为一开始的树根,进行求解
int ans = solve(0, K);
if (ans == 0x7fffffff) {
ans = -1;
}
printf("%d\n", ans);
return 0;
}