0pts,WA和TLE
#include<bits/stdc++.h>
#define int long long
#define ls (x<<1)
#define rs ((x<<1)|1)
#define mid ((l+r)>>1)
using namespace std;
namespace IO{
char buff[1<<21],*p1=buff,*p2=buff;
char getch(){
return p1==p2&&(p2=((p1=buff)+fread(buff,1,1<<21,stdin)),p1==p2)?EOF:*p1++;
}
template<typename T>
void read(T &x){
char ch=getch();int fl=1;x=0;
while(ch>'9'||ch<'0'){if(ch=='-')fl=-1;ch=getch();}
while(ch<='9'&&ch>='0'){x=x*10+ch-48;ch=getch();}
x*=fl;
}
template<typename T,typename ...Args>
void read(T &x,Args& ...args){
read(x);read(args...);
}
char obuf[1<<21],*p3=obuf;
void putch(char ch){
if(p3-obuf<(1<<21))*p3++=ch;
else fwrite(obuf,p3-obuf,1,stdout),p3=obuf,*p3++=ch;
}
char ch[100];
template<typename T>
void write(T x){
if(!x)return putch('0');
if(x<0)putch('-'),x*=-1;
int top=0;
while(x)ch[++top]=x%10+48,x/=10;
while(top)putch(ch[top]),top--;
}
template<typename T,typename ...Args>
void write(T x,Args ...args){
write(x);write(args...);
}
void flush(){fwrite(obuf,p3-obuf,1,stdout);}
}
using namespace IO;
const int N=1e5;
int n,m;
int dep[N],s[N],siz[N],son[N],dfn[N],top[N],fa[N],tot,dfs[N];
struct Edge{
int to,w;
};
vector<Edge>to[N];
struct node{
int k,b;
}tree[(N<<2)+5];
int T[(N<<2)+5];
void dfs0(int x,int p){
siz[x]=1;
fa[x]=p;
for(auto e:to[x]){
int y=e.to;
int w=e.w;
if(y==p)continue;
dep[y]=dep[x]+1;
s[y]=s[x]+w;
dfs0(y,x);
siz[x]+=siz[y];
if(siz[son[x]]<siz[y])son[x]=y;
}
}
void dfs1(int x,int Top){
top[x]=Top;
dfn[x]=++tot;
dfs[tot]=x;
if(son[x])dfs1(son[x],Top);
for(auto e:to[x]){
int y=e.to;
int w=e.to;
if(y==fa[x])continue;
if(y==son[x])continue;
dfs1(y,y);
}
}
int Lca(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
return x;
}
inline int F(node A,int x){return A.k*s[dfs[x]]+A.b;}
inline void UP_date(int x,int l,int r){
if(l==r){
T[x]=min(T[x],F(tree[x],l));
}else{
T[x]=min(T[x],min(F(tree[x],l),min(F(tree[x],r),min(T[ls],T[rs]))));
}
}
void update(int x,int l,int r,node A){
if((F(tree[x],l)>F(A,l))&&(F(tree[x],r)>F(A,r))){tree[x]=A;UP_date(x,l,r);return;}
if((F(tree[x],l)<=F(A,l))&&(F(tree[x],r)<=F(A,r)))return;
if(F(tree[x],mid)>F(A,mid))swap(tree[x],A);
if(F(tree[x],l)>F(A,l))update(ls,l,mid,A);
else update(rs,mid+1,r,A);
UP_date(x,l,r);
}
void modify(int x,int l,int r,int L,int R,node A){
if(L<=l&&r<=R){
update(x,l,r,A);
return;
}
if(mid>=R)modify(ls,l,mid,L,R,A);
else if(mid<L)modify(rs,mid+1,r,L,R,A);
else modify(ls,l,mid,L,R,A),modify(rs,mid+1,r,L,R,A);
UP_date(x,l,r);
}
int query(int x,int l,int r,int W){
if(l==r)return F(tree[x],l);
if(W<=mid)return min(F(tree[x],W),query(ls,l,mid,W));
else return min(F(tree[x],W),query(rs,mid+1,r,W));
}
int ask(int x,int l,int r,int L,int R){
if(L<=l&&r<=R)return T[x];
if(mid>=R)return ask(ls,l,mid,L,R);
else if(mid<L)return ask(rs,mid+1,r,L,R);
else return min(ask(ls,l,mid,L,R),ask(rs,mid+1,r,L,R));
}
void Modify_tree(int x,int y,int a,int b){
int lca=Lca(x,y);
node A={-a,b+a*s[x]};
node B={a,b+a*s[x]-2*a*s[lca]};
while(top[x]!=top[y]){
if(dep[top[x]]>dep[top[y]]){
modify(1,1,n,dfn[top[x]],dfn[x],A);
x=fa[top[x]];
}else{
modify(1,1,n,dfn[top[y]],dfn[y],B);
y=fa[top[y]];
}
}
if(dep[x]<dep[y])modify(1,1,n,dfn[x],dfn[y],B);
else modify(1,1,n,dfn[y],dfn[x],A);
}
int Ask_tree(int x,int y){
int maxn=123456789123456789;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
maxn=min(maxn,ask(1,1,n,dfn[top[x]],dfn[x]));
}
if(dep[x]>dep[y])swap(x,y);
maxn=min(maxn,ask(1,1,n,dfn[x],dfn[y]));
return maxn;
}
signed main(){
for(int i=0;i<=(N<<2);i++)tree[i].b=123456789123456789,T[i]=123456789123456789;
read(n,m);
for(int i=1;i<n;i++){
int u,v,w;
read(u,v,w);
to[u].push_back({v,w});
to[v].push_back({u,w});
}
dfs0(1,0);
dfs1(1,1);
while(m--){
int ops;
read(ops);
if(ops==1){
int u,v,a,b;
read(u,v,a,b);
Modify_tree(u,v,a,b);
}else{
int u,v;
read(u,v);
write(Ask_tree(u,v)),putch('\n');
}
}
flush();
return 0;
}