#include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define task "text"
#define fi first
#define se second
const int N = 2e5+5;
vector<int> adj[N];
int sz[N];
multiset<int> s1,s2;
int n;
void pre_dfs(int u,int p){
sz[u]=1;
for(int v:adj[u]){
if(v==p) continue;
pre_dfs(v,u);
sz[u] += sz[v];
}
}
bool checkok(int x,int d,int dif,int type){
if(type == 1){
int l=max({x-d,n-2*x-d,(n-x-d+1)/2});
int r=min({x+d,n-2*x+d,(n-x+d)/2});
l+=dif;
r+=dif;
if(l>r) return 0;
auto it=s1.lower_bound(l);
if(it == s1.end()) return 0;
if(*it <= r) return 1;
return 0;
}else{
int l=max({x-d,n-2*x-d,(n-x-d+1)/2});
int r=min({x+d,n-2*x+d,(n-x+d)/2});
l+=dif;
r+=dif;
if(l>r) return 0;
auto it=s2.lower_bound(l);
if(it == s2.end()) return 0;
if(*it <= r) return 1;
return 0;
}
}
bool ok=0;
void dfs(int u,int p,int d){
s1.insert(sz[u]);
s2.erase(s2.find(sz[u]));
if(checkok(sz[u],d,sz[u],1)){
ok=1;
}
if(checkok(sz[u],d,0,2)){
ok=1;
}
for(int v:adj[u]){
if(v==p) continue;
dfs(v,u,d);
}
s1.erase(s1.find(sz[u]));
s2.insert(sz[u]);
}
bool check(int d){
ok=0;
dfs(1,0,d);
return ok;
}
signed main(){
ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
if(fopen(task".inp","r")){
freopen(task".inp","r",stdin);
//freopen(task".out","w",stdout);
}
cin>>n;
for(int i=1;i<n;i++){
int x,y;
cin>>x>>y;
adj[x].push_back(y);
adj[y].push_back(x);
}
pre_dfs(1,0);
for(int i=1;i<=n;i++) s2.insert(sz[i]);
int l=0,r=n,ans=n;
//cout<<check(1)<<'\n';
while(l<=r){
int mid=(l+r)>>1;
if(check(mid)){
r=mid-1;
ans=mid;
}else l=mid+1;
}
cout<<ans<<'\n';
}