#include <bits/stdc++.h>
using namespace std;
void fastIO() {
  std::ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
}
template <typename T, typename U>
inline void amin(T &x, U y) {
  if (y < x) x = y;
}
template <typename T, typename U>
inline void amax(T &x, U y) {
  if (x < y) x = y;
}
void _scan(int &x) { scanf("%d", &x); }
void _scan(long long &x) { scanf("%lld", &x); }
void _scan(double &x) { scanf("%lf", &x); }
void _scan(char &x) { scanf(" %c", &x); }
void _scan(char *x) { scanf("%s", x); }
void scan() {}
template <typename T, typename... U>
void scan(T &head, U &...tail) {
  _scan(head);
  scan(tail...);
}
template <typename T>
void _dbg(const char *sdbg, T h) {
  cerr << sdbg << "=" << h << "\n";
}
template <typename T, typename... U>
void _dbg(const char *sdbg, T h, U... t) {
  while (*sdbg != ',') cerr << *sdbg++;
  cerr << "=" << h << ",";
  _dbg(sdbg + 1, t...);
}
const int MAXN = 5003;
const int INF = 0x3f3f3f3f;
int n, sz[MAXN], c[MAXN];
vector<int> G[MAXN];
int dp[MAXN][2][MAXN];
void dfs(int v, int p) {
  for (auto u : G[v]) {
    if (u == p) continue;
    dfs(u, v);
    sz[v] += sz[u];
  }
  if (G[v].size() == 1) {
    memset(dp[v], INF, sizeof(dp[v]));
    sz[v]++;
    dp[v][0][1] = dp[v][1][0] = 0;
    return;
  }
  int sv = 0;
  vector<int> prv[2], nxt[2];
  for (int i = 0; i < (int)2; i++) prv[i] = vector<int>(sv + 1, INF);
  prv[0][0] = prv[1][0] = 0;
  for (int u : G[v]) {
    if (p == u) continue;
    for (int i = 0; i < (int)2; i++) nxt[i] = vector<int>(sv + sz[u] + 1, INF);
    for (int vk = 0; vk < (int)sv + 1; vk++)
      for (int uk = 0; uk < (int)sz[u] + 1; uk++) {
        amin(nxt[0][vk + uk], prv[0][vk] + dp[u][0][uk]);
        amin(nxt[0][vk + uk], prv[0][vk] + dp[u][1][uk] + 1);
        amin(nxt[1][vk + uk], prv[1][vk] + dp[u][1][uk]);
        amin(nxt[1][vk + uk], prv[1][vk] + dp[u][0][uk] + 1);
      }
    for (int i = 0; i < (int)2; i++) prv[i] = nxt[i];
    sv += sz[u];
  }
  for (int i = 0; i < (int)2; i++)
    for (int k = 0; k < (int)sv + 1; k++) dp[v][i][k] = prv[i][k];
}
int main() {
  scan(n);
  for (int i = 0; i < (int)n - 1; i++) {
    int v, u;
    scan(v, u);
    v--;
    u--;
    G[v].push_back(u);
    G[u].push_back(v);
  }
  if (n == 2) {
    printf("1\n");
    return 0;
  }
  int leaves = 0, root = -1;
  for (int v = 0; v < (int)n; v++) {
    if (G[v].size() == 1)
      leaves++;
    else
      root = v;
  }
  dfs(root, -1);
  leaves /= 2;
  printf("%d\n", min(dp[root][0][leaves], dp[root][1][leaves]));
}
