#include <bits/stdc++.h>
#define lx (x * 2)
#define rx (x * 2 + 1)
#define mid ((l + r) >> 1)
#define ll long long
using namespace std;
int read()
{
int x = 0, f = 1;
char ch = 0;
while(!isdigit(ch))
{
if(ch == '-')
{
f = -1;
}
ch = getchar();
}
while(isdigit(ch))
{
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
const int N = 100000, LG = 20;
ll INF = (ll)0x3f3f3f3f3f3f3f3f;
int n, q;
struct Edge
{
int v;
ll w;
int nxt;
}edge[N * 2 + 5];
int head[N + 5], cnte;
void adde(int u, int v, ll w)
{
edge[++cnte] = {v, w, head[u]};
head[u] = cnte;
}
ll dep[N + 5];
int dep1[N + 5];
int fa[N + 5], siz[N + 5], hson[N + 5];
struct St
{
int id, dep;
bool operator < (const St &t) const
{
return dep < t.dep;
}
}st[N * 2 + 5][LG + 5];
int cnts;
int sta[N + 5], ed[N + 5];
void dfs1(int u, int fath)
{
dep1[u] = dep1[fath] + 1;
st[++cnts][0] = {u, dep1[u]};
sta[u] = cnts;
fa[u] = fath;
siz[u] = 1;
for(int i = head[u]; i; i = edge[i].nxt)
{
int v = edge[i].v;
if(v == fath)
{
continue;
}
dep[v] = dep[u] + edge[i].w;
dfs1(v, u);
st[++cnts][0] = {u, dep1[u]};
siz[u] += siz[v];
if(siz[v] > siz[hson[u]])
{
hson[u] = v;
}
}
ed[u] = cnts;
}
int dfn[N + 5], rk[N + 5], cntn;
int tp[N + 5];
void dfs2(int u, int topp)
{
dfn[u] = ++cntn;
rk[cntn] = u;
tp[u] = topp;
if(hson[u])
{
dfs2(hson[u], topp);
}
for(int i = head[u]; i; i = edge[i].nxt)
{
int v = edge[i].v;
if(v == fa[u] || v == hson[u])
{
continue;
}
dfs2(v, v);
}
}
int l2[N * 2 + 5];
void STP()
{
l2[1] = 0;
for(int i = 2; i <= cnts; i++)
{
l2[i] = l2[i / 2] + 1;
}
for(int i = cnts; i >= 1; i--)
{
for(int j = 1; j <= LG; j++)
{
if(i + (1 << j) - 1 > cnts)
{
break;
}
st[i][j] = min(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
}
}
}
int LCA(int x, int y)
{
if(ed[x] > sta[y])
{
swap(x, y);
}
int s = ed[x], t = sta[y];
int tmp = l2[t - s + 1];
return min(st[s][tmp], st[t - (1 << tmp) + 1][tmp]).id;
}
int dis(int x, int y)
{
return dep[x] + dep[y] - 2 * dep[LCA(x, y)];
}
struct Seg
{
ll k, b;
Seg()
{
k = INF, b = INF;
}
Seg(ll kk, ll bb)
{
k = kk, b = bb;
}
ll calc(ll x)
{
if(k == INF)
{
return INF;
}
return k * x + b;
}
};
struct Tr
{
Seg x;
}lc[N * 4 + 5];
void add(int x, int l, int r, int s, int t, Seg k)
{
if(l >= s && r <= t)
{
int z1 = dep[rk[l]], z2 = dep[rk[mid]], z3 = dep[rk[r]];
// if(lc[x].x.k == INF)
// {
// lc[x].x = k;
// // printf("%d %d %lld %lld 111\n", l, r, k.k, k.b);
// return;
// }
if(k.calc(z2) <= lc[x].x.calc(z2))
{
swap(k, lc[x].x);
}
if(k.calc(z1) >= lc[x].x.calc(z1) && k.calc(z3) >= lc[x].x.calc(z3))
{
return;
}
if(l == r)
{
return;
}
if(k.calc(z1) <= lc[x].x.calc(z1))
{
add(lx, l, mid, s, t, k);
}
else
{
add(rx, mid + 1, r, s, t, k);
}
return;
}
if(s <= mid)
{
add(lx, l, mid, s, t, k);
}
if(t > mid)
{
add(rx, mid + 1, r, s, t, k);
}
}
ll ask(int x, int l, int r, int s)
{
if(l == r)
{
return lc[x].x.calc(dep[rk[s]]);
}
ll ret = lc[x].x.calc(dep[rk[s]]);
if(s <= mid)
{
ret = min(ret, ask(lx, l, mid, s));
}
else
{
ret = min(ret, ask(rx, mid + 1, r, s));
}
return ret;
}
struct TT
{
ll mx;
}tr[N * 4 + 5];
void pushup(int x)
{
tr[x].mx = min(tr[lx].mx, tr[rx].mx);
}
void build(int x, int l, int r)
{
if(l == r)
{
tr[x].mx = (ll)123456789123456789;
return;
}
build(lx, l, mid);
build(rx, mid + 1, r);
pushup(x);
}
void mdf(int x, int l, int r, int s, ll k)
{
if(l == r)
{
tr[x].mx = min(tr[x].mx, k);
return;
}
if(s <= mid)
{
mdf(lx, l, mid, s, k);
}
else
{
mdf(rx, mid + 1, r, s, k);
}
pushup(x);
return;
}
ll ask1(int x, int l, int r, int s, int t)
{
if(l >= s && r <= t)
{
return tr[x].mx;
}
ll ret = INF;
if(s <= mid)
{
ret = min(ret, ask1(lx, l, mid, s, t));
}
if(t > mid)
{
ret = min(ret, ask1(rx, mid + 1, r, s, t));
}
return ret;
}
void addchn(int x, int y, Seg k)
{
while(1)
{
// printf("%d\n", x);
if(dep1[tp[x]] > dep1[y])
{
add(1, 1, n, dfn[tp[x]], dfn[x], k);
// printf("%d %d 333\n", dfn[tp[x]], dfn[x]);
mdf(1, 1, n, dfn[x], k.calc(dep[x]));
mdf(1, 1, n, dfn[tp[x]], k.calc(dep[tp[x]]));
x = fa[tp[x]];
}
else
{
add(1, 1, n, dfn[y], dfn[x], k);
mdf(1, 1, n, dfn[x], k.calc(dep[x]));
mdf(1, 1, n, dfn[y], k.calc(dep[y]));
break;
}
}
}
ll askchn(int x, int y)
{
ll ret = INF;
while(1)
{
if(dep1[tp[x]] > dep1[y])
{
ret = min(ret, ask(1, 1, n, dfn[x]));
ret = min(ret, ask(1, 1, n, dfn[tp[x]]));
ret = min(ret, ask1(1, 1, n, dfn[tp[x]], dfn[x]));
x = fa[tp[x]];
}
else
{
ret = min(ret, ask(1, 1, n, dfn[x]));
ret = min(ret, ask(1, 1, n, dfn[y]));
ret = min(ret, ask1(1, 1, n, dfn[y], dfn[x]));
// printf("%d %d 222\n", dfn[y], dfn[x]);s
break;
}
}
return ret;
}
void init()
{
n = read(), q = read();
for(int i = 1; i < n; i++)
{
int u = read(), v = read();
ll w = (ll)read();
adde(u, v, w);
adde(v, u, w);
}
dfs1(1, 0);
STP();
dfs2(1, 1);
}
void solve()
{
// for(int i = 1; i <= n; i++)
// {
// printf("%d ", tp[i]);
// }
// printf("\n");
build(1, 1, n);
while(q--)
{
int op = read();
if(op == 1)
{
int x = read(), y = read(), k = read(), b = read();
int lca = LCA(x, y);
addchn(x, lca, Seg(-k, (ll)k * dep[x] + b));
addchn(y, lca, Seg(k, (ll)k * (dep[x] - dep[lca] - dep[lca]) + b));
// printf("%d %d %lld %lld\n", x, lca, -(ll)k, (ll)k * dep[x] + b);
// printf("%d %d %lld %lld\n", y, lca, (ll)k, (ll)k * (dep[x] - dep[lca] - dep[lca]) + b);
}
else
{
int x = read(), y = read();
int lca = LCA(x, y);
printf("%lld\n", min(askchn(x, lca), askchn(y, lca)));
}
// printf("suc %d\n", q);
}
}
int main()
{
// freopen("in.in", "r", stdin);
// freopen("my.out", "w", stdout);
init();
solve();
return 0;
}
vs 提示段错误