#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 5e3 + 5;
int N, ROOT, p[MAXN], sz[MAXN], BAD;
vector<int> G[MAXN];
int dp[2][MAXN][MAXN];
void dfs(int u) {
  sz[u] = G[u].size() == 1;
  for (int i = 0; i < G[u].size(); i++) {
    int v = G[u][i];
    if (v == p[u]) continue;
    p[v] = u;
    dfs(v);
    sz[u] += sz[v];
  }
  for (int i = 0; i < sz[u] + 1; i++) dp[0][u][i] = dp[1][u][i] = INF;
  dp[0][u][0] = dp[1][u][0] = 0;
  if (G[u].size() == 1) dp[0][u][1] = 0, dp[0][u][0] = INF;
  int su = 0;
  for (int i = 0; i < G[u].size(); i++) {
    int v = G[u][i];
    if (v == p[u]) continue;
    su = su + sz[v];
    for (int cnt = su; cnt > -1; cnt--) {
      dp[0][u][cnt] = min(dp[0][v][0], 1 + dp[1][v][0]) + dp[0][u][cnt];
      dp[1][u][cnt] = min(dp[1][v][0], 1 + dp[0][v][0]) + dp[1][u][cnt];
      for (int cntv = 1; cntv < min(sz[v], cnt) + 1; cntv++) {
        dp[0][u][cnt] =
            min(dp[0][u][cnt],
                min(dp[0][v][cntv], 1 + dp[1][v][cntv]) + dp[0][u][cnt - cntv]);
        dp[1][u][cnt] =
            min(dp[1][u][cnt],
                min(dp[1][v][cntv], 1 + dp[0][v][cntv]) + dp[1][u][cnt - cntv]);
      }
    }
  }
}
int main() {
  scanf("%d", &N);
  for (int i = 0; i < N - 1; i++) {
    int u, v;
    scanf("%d", &u), scanf("%d", &v);
    ;
    u--;
    v--;
    G[u].push_back(v);
    G[v].push_back(u);
  }
  if (N == 2) {
    printf("1\n");
    return 0;
  }
  for (int u = 0; u < N; u++) BAD += G[u].size() == 1;
  for (int u = 0; u < N; u++)
    if (G[u].size() > 1) {
      ROOT = u;
      break;
    }
  p[ROOT] = -1;
  dfs(ROOT);
  printf("%d\n", min(dp[0][ROOT][BAD / 2], dp[1][ROOT][BAD / 2]));
}
