#include<bits/stdc++.h>
using namespace std;
#define int long long
#define inf 123456789123456789
const int sz=5e6,mod1=39989,mod2=1e9;
int read()
{
char c=getchar();
int r=0,f=1;
while((c<'0'||c>'9')&&c!='-')
c=getchar();
if(c=='-') {
f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
r=r*10+c-'0';
c=getchar();
}
return f*r;
}
int n,m,tot,head[sz],cnt,lx[sz],rx[sz];
int dep[sz],siz[sz],child[sz],dfn[sz],sum,a[sz],top[sz],F[sz],dis[sz],ns[sz];
struct node {
int to,nxt,dis;
} e[sz];
struct node2 {
int k,b,id;
}f[sz];
int clac(node2 id,int x)
{
return id.k*dis[ns[x]]+id.b;
}
void build(int l,int r,int p)
{
lx[p]=inf,rx[p]=inf;
f[p].k=0,f[p].b=123456789123456789;
if(l==r) return;
int mid=(l+r)>>1;
build(l,mid,p<<1);
build(mid+1,r,p<<1|1);
}
void update(int l,int r,node2 now,int p,int L,int R)
{
if(clac(now,l)>lx[p]&&clac(now,r)>rx[p]) return;
int mid=(L+R)>>1;
if(l<=L&&r>=R)
{
if(!f[p].id) {
f[p]=now,lx[p]=clac(now,l),rx[p]=clac(now,r);
return;
}
int l1=lx[p],l2=clac(now,l),r1=rx[p],r2=clac(now,r);
if(l2<=l1&&r2<=r1) {
f[p]=now,lx[p]=l2,rx[p]=r2;
return;
}
double cross=(double)1.0*(f[p].b-now.b)/(now.k-f[p].k);
if(l2<l1)
{
if(cross<=mid) update(l,r,now,p<<1,L,mid);
else{
update(l,r,f[p],p<<1|1,mid+1,R);
f[p]=now,lx[p]=l2,rx[p]=r2;
}
}
else
{
if(cross<=mid) update(l,r,f[p],p<<1,L,mid);
else{
update(l,r,f[p],p<<1,L,mid);
f[p]=now,lx[p]=l2,rx[p]=r2;
}
}
return;
}
if(mid>=l) update(l,r,now,p<<1,L,mid);
if(mid<r) update(l,r,now,p<<1|1,mid+1,R);
}
void add(int k,int b,int l,int r)
{
node2 now=(node2) {k,b,++tot};
update(l,r,now,1,1,n);
}
int query(int l,int r,int p,int L,int R)
{
if(l<=L&&R<=r) return min(clac(f[p],l),clac(f[p],r));
int mid=(L+R)>>1,ans=123456789123456789;
ans=min(ans,min(clac(f[p],l),clac(f[p],r)));
if(mid>=l) ans=min(ans,query(l,r,p<<1,L,mid));
if(mid<r) ans=min(ans,query(l,r,p<<1|1,mid+1,R));
return ans;
}
void add_edge(int x,int y,int w)
{
e[++cnt]=(node) {y,head[x],w};
head[x]=cnt;
}
void dfs1(int now,int fa)
{
siz[now]=1,dep[now]=dep[fa]+1,F[now]=fa;
int maxn=0;
for(int i=head[now]; i; i=e[i].nxt) {
if(e[i].to==fa) continue;
dis[e[i].to]+=dis[now]+e[i].dis;
dfs1(e[i].to,now);
if(siz[e[i].to]>maxn)
child[now]=e[i].to,maxn=siz[e[i].to];
siz[now]+=siz[e[i].to];
}
}
void dfs2(int now,int Top)
{
dfn[now]=++sum,top[now]=Top,ns[sum]=now;
if(!child[now]) return;
dfs2(child[now],Top);
for(int i=head[now]; i; i=e[i].nxt) {
if(e[i].to==F[now]||e[i].to==child[now]) continue;
dfs2(e[i].to,e[i].to);
}
}
int lca(int x,int y)
{
while(top[x]^top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
x=F[top[x]];
}
if(dep[x]>dep[y]) return y;
else return x;
}
void ADD(int x,int y,int k,int b)
{
while(top[x]^top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
add(k,b,dfn[top[x]],dfn[x]);
x=F[top[x]];
}
add(k,b,min(dfn[x],dfn[y]),max(dfn[x],dfn[y]));
}
void insert(int s,int t,int a,int b)
{
int LCA=lca(s,t);
ADD(LCA,s,-a,a*dis[s]+b);
ADD(LCA,t,a,(dis[s]-2*dis[LCA])*a+b);
}
int Query(int x,int y)
{
int ans=123456789123456789;
while(top[x]^top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
// cout<<top[x]<<":"<<x<<":"<<y<<":"<<top[y]<<endl;
ans=min(ans,query(dfn[top[x]],dfn[x],1,1,n));
x=F[top[x]];
}
ans=min(ans,query(min(dfn[x],dfn[y]),max(dfn[x],dfn[y]),1,1,n));
return ans;
}
signed main()
{
n=read(),m=read();
for(int i=1; i<n; i++) {
int u=read(),v=read(),w=read();
add_edge(u,v,w),add_edge(v,u,w);
// cout<<i<<endl;
}
// cout<<"giao"<<endl;
build(1,n,1);
dfs1(1,1);
dfs2(1,1);
for(int i=1; i<=m; i++) {
int op=read();
if(op==1) {
int s=read(),t=read(),a=read(),b=read();
insert(s,t,a,b);
}
else{
int s=read(),t=read();
cout<<Query(s,t)<<endl;
}
}
}
/*
31 9
1 3 20
1 4 20
3 2 30
3 5 40
2 23 20
23 25 10
25 27 30
25 24 40
23 26 20
5 21 40
21 20 40
5 18 30
21 22 30
22 28 20
22 29 10
18 19 20
19 31 10
19 30 30
4 6 40
6 12 20
12 13 10
12 14 30
14 15 40
14 16 20
4 8 30
8 10 60
8 7 50
10 17 40
7 9 20
7 11 10
1 25 22 10 40
1 22 19 10 40
1 21 14 42 53
1 14 12 23 123
1 2 31 221 2134
2 2 21
*/