#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define all(x) (x).begin(), (x).end()
#define sz(x) (int)(x).size()
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
template<class X, class Y> bool maximize (X &x, const Y &y) {return x < y ? x = y, 1 : 0;}
template<class X, class Y> bool minimize (X &x, const Y &y) {return x > y ? x = y, 1 : 0;}
const int maxn = 2e5 + 5;
const int MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int n;
vector<int> adj[maxn];
int sizes[maxn];
multiset<int> s1, s2;
void dfs1(int u, int p) {
sizes[u] = 1;
for (auto v : adj[u]) {
if (v == p) continue;
dfs1(v, u);
sizes[u] += sizes[v];
}
}
int getval(int a, int b, int c) {return max({a, b, c}) - min({a, b, c});}
int ans = INT_MAX;
void dfs2(int u, int p) {
auto it1 = s1.lower_bound((n + sizes[u]) / 2);
auto it2 = s2.lower_bound((n - sizes[u]) / 2);
if (it1 != s1.end()) minimize(ans, getval(sizes[u], *it1 - sizes[u], n - *it1));
if (it1 != s1.begin()) minimize(ans, getval(sizes[u], *prev(it1) - sizes[u], n - *prev(it1)));
if (it2 != s2.end()) minimize(ans, getval(sizes[u], *it2, n - *it2 - sizes[u]));
if (it2 != s2.begin()) minimize(ans, getval(sizes[u], *prev(it2), n - *prev(it2) - sizes[u]));
s1.insert(sizes[u]);
for (auto v : adj[u]) {
if (v != p) dfs2(v, u);
}
s1.erase(s1.find(sizes[u]));
s2.insert(sizes[u]);
}
int main()
{
ios::sync_with_stdio(false); cin.tie(0);
//freopen(".INP", "r", stdin);
//freopen(".OUT", "w", stdout);
cin >> n;
for (int i = 1; i < n; ++i) {
int u, v; cin >> u >> v;
adj[u].pb(v);
adj[v].pb(u);
}
dfs1(1, 0);
dfs2(1, 0);
cout << ans;
return 0;
}