#if defined(_USE_PCH_)
#include "pch.hpp"
#else
#include <bits/stdc++.h>
#endif
#define RNG(V_, A_, B_, ...) for(int V_=(A_), V_##_END=(B_) __VA_OPT__(,) __VA_ARGS__; V_<=V_##_END; V_++)
#define IRNG(V_, A_, B_) for(int V_=(A_), V_##_END=(B_); V_>=V_##_END; V_--)
#ifdef _WIN32
#define long __int64
#endif
#if defined(_LOCAL_)
#undef assert
#define assert(expr) ({ if(!(expr)) asm("int3"); 0; })
#endif
using namespace std;
const int MAXN=1e5; const long INFL=1e18;
int n,qn;
vector<int> G[MAXN];
// Tree divide
int fa[MAXN],dep[MAXN],siz[MAXN],son[MAXN],top[MAXN],tail[MAXN],dfn[MAXN],dfnc;
void dfs1(int u,int fa_){
fa[u]=fa_,dep[u]=dep[fa_]+1,siz[u]=1;
for(int v:G[u]){
if(v==fa_) continue;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[v]>siz[son[u]]) son[u]=v;
}
}
void dfs2(int u,int top_){
top[u]=top_,tail[top_]=u,dfn[u]=++dfnc;
if(son[u]) dfs2(son[u],top_);
for(int v:G[u]){
if(v!=fa[u]&&v!=son[u]) dfs2(v,v);
}
}
int lca(int u,int v){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
u=fa[top[u]];
}
return dep[u]<dep[v]?u:v;
}
struct Mat{
long a,b,c,d;
Mat operator*(const Mat& o)const { return {max(-INF,a+o.a),max({-INF,a+o.b,b}),max({-INF,c+o.a,o.c}),max({-INF,c+o.b,d,o.d})}; }
};
struct Tag{
long a;
void apply(Mat& x){ x.b+=x,x.d+=x; }
Tag operator+(Tag o){ return {a+o.a}; }
};
struct SGT{
#define ls (u*2)
#define rs (u*2+1)
#define mid ((l+r)/2)
Mat T[MAXN*4]; Tag tag[MAXN*4];
void build(int u,int l,int r){
T[u]={0,0,0,0};
if(l==r) return;
build(ls,l,mid),build(rs,mid+1,r);
}
void pushup(int u){ T[u]=T[rs]*T[ls]; }
void upd(int u,Tag t){ t.apply(T[u]),tag[u]=tag[u]+t; }
void pushdown(int u){ upd(ls,tag[u]),upd(rs,tag[u]),tag[u]={0}; }
void set(int u,int l,int r,int i,const Mat& x){
if(l==r){ T[u]=x; return; }
pushdown(u);
i<=mid ? set(ls,l,mid,i,x) : set(rs,mid+1,r,i,x);
pushup(u);
}
void upd(int u,int l,int r,int ql,int qr,Tag t){
if(ql<=l&&r<=qr){ upd(u,t); return; }
pushdown(u);
if(ql<=mid) upd(ls,l,mid,ql,qr,t);
if(mid<qr) upd(rs,mid+1,r,ql,qr,t);
pushup(u);
}
Mat qry(int u,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr) return T[u];
pushdown(u);
Mat ret {0,-INF,-INF,-INF};
if(mid<qr) ret=qry(ls,l,mid,ql,qr);
if(ql<=mid) ret=ret*qry(rs,mid+1,r,ql,qr);
return ret;
}
#undef ls
#undef rs
#undef mid
} sgt;
multiset<int> S[MAXN],ans;
long F[MAXN],H[MAXN];
void pushup(int u){
S[fa[u]].erase(S[fa[u]].find(F[u])),ans.erase(ans.find(H[u]));
auto x=sgt.qry(1,1,n,dfn[u],dfn[tail[u]]);
F[u]=x.a+x.c,H[u]=x.b+x.d;
}
int main(){
#if defined(_LOCAL_)
freopen("in","r",stdin);
freopen("out","w",stdout);
#else
// freopen("b6e7.in","r",stdin);
// freopen("b6e7.out","w",stdout);
#endif
ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
cin>>n>>qn;
RNG(_,1,n-1,u,v) cin>>u>>v,G[u].push_back(v),G[v].push_back(u);
dfs1(1,0),dfs2(1,1);
}