#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline T abs(T t) {
  return t < 0 ? -t : t;
}
const long long modn = 1000000007;
inline long long mod(long long x) { return x % modn; }
int distr(int, int, int, bool);
vector<pair<int, int> > adj[5009];
int memo[5002][2502][2];
int solve(int u, int l, bool bf) {
  if (adj[u].empty()) {
    if (l > 1) return 1000000;
    if (l == 1)
      return !bf;
    else
      return bf;
  }
  int &r = memo[u][l][bf];
  if (r != -1) return r;
  r = min(distr(u, adj[u].size(), l, true) + !bf,
          distr(u, adj[u].size(), l, false) + bf);
  return r;
}
int memo2[5002][2502][2];
int distr(int u, int m, int l, bool b) {
  int &r = memo2[adj[u][m - 1].first][l][b];
  if (r != -1) return r;
  if (m == 1) return r = solve(adj[u][0].first, l, b);
  r = 1000000;
  for (int i = max(l - adj[u][m - 2].second, 0);
       i <= l && i <= adj[u][m - 1].second - adj[u][m - 2].second; i++)
    r = min(r, solve(adj[u][m - 1].first, i, b) + distr(u, m - 1, l - i, b));
  return r;
}
int dfs(int u, int p) {
  if (p != -1) {
    int i;
    for (i = 0; adj[u][i].first != p; i++)
      ;
    swap(adj[u][i], adj[u].back());
    adj[u].pop_back();
  }
  if (adj[u].empty()) return 1;
  for (pair<int, int> &e : adj[u]) e.second += dfs(e.first, u);
  for (int i = 1; i < adj[u].size(); i++)
    adj[u][i].second += adj[u][i - 1].second;
  return adj[u].back().second;
}
int main() {
  int i, n, a, b;
  scanf("%d", &n);
  int l = 0;
  for (i = 0; i < n - 1; i++) {
    scanf("%d %d", &a, &b);
    adj[--a].push_back(pair<int, int>(--b, 0));
    adj[b].push_back(pair<int, int>(a, 0));
  }
  for (i = 0; i < n; i++) l += adj[i].size() == 1;
  if (n == 2) {
    puts("1");
    return 0;
  }
  memset(memo, -1, sizeof memo);
  memset(memo2, -1, sizeof memo2);
  for (i = 0; adj[i].size() == 1; i++)
    ;
  dfs(i, -1);
  printf("%d\n", min(distr(i, adj[i].size(), l / 2, true),
                     distr(i, adj[i].size(), l / 2, false)));
}
