#include //#include //using namespace atcoder; using namespace std; typedef long long ll; typedef unsigned long long ull; typedef long double ld; #define pii pair #define pll pair #define rep(i,num,n) for(int i=num;i<(int)(n);i++) //for_loop #define REP(i,n) for(int i=0;i<(int)(n);i++) #define rrep(i,num,n) for(int i=num-1;i>=(int)(n);i--) //reverse_for> #define in(x,a,b) (a<=x && xb){a=b;return true;}return false;} bool chmax(ll &a,ll b){if(ab){a=b;return true;}return false;} bool chmax(int &a,int b){if(adpmax(200020,0),dpmin(200020,INFI); vectorused(200020,false); vector>g(200020); int dfs(int pos){ int ma=-INFI; int dep=0; used[pos]=true; for(auto e:g[pos]){ if(used[e])continue;//探索済み dep=max(dep,dfs(e)+1); ma=max(ma,dep); } if(dep==0){//葉 ma=0; } dpmax[pos]=ma; return dep; } int dfs2(int pos){//最小値 int mi=INFI; int dep=INFI; used[pos]=true; for(auto e:g[pos]){ if(used[e])continue;//探索済み dep=min(dep,dfs2(e)+1); mi=min(mi,dep); } if(dep==INFI){//葉 mi=0; } dpmin[pos]=mi; return mi; } int main(){ int n;cin>>n; rep(i,1,n){ int a,b;cin>>a>>b;a--,b--; g[a].push_back(b); g[b].push_back(a); } //戦略:先手:最小値の最大化、後手:最大値の最小化 //各頂点について葉までの距離の最小値/最大値がわかればよい。 //方法:木DP //DP[i]→iを根とする部分木において、最小の経路/最大の経路 used[0]=true; dfs(0); used.assign(200010,false); used[0]=true; dfs2(0); int pos=0; int teban=0; used.assign(200010,false); used[0]=true; while (1) { int to=-1; int tmp; if(teban%2==0){//先手,最小値の最大化 tmp=-1; for(auto e:g[pos]){ if(used[e])continue; used[e]=true; if(dpmin[e]>=tmp){ to=e; tmp=dpmin[e]; } } }else { tmp=INFI; for(auto e:g[pos]){ if(used[e])continue; used[e]=true; if(dpmax[e]<=tmp){ to=e; tmp=dpmax[e]; } } } //遷移 if(to==-1){//葉 break; } pos=to; teban++; } cout<=tmp){ to=e; tmp=dpmin[e]; } } }else { tmp=INFI; for(auto e:g[pos]){ if(used[e])continue; used[e]=true; if(dpmax[e]<=tmp){ to=e; tmp=dpmax[e]; } } } //遷移 if(to==-1){//葉 break; } pos=to; teban++; } cout<