#include <bits/stdc++.h>
using namespace std;
inline char nchar() {
  static const int bufl = 1 << 20;
  static char buf[bufl], *a = NULL, *b = NULL;
  return a == b && (b = (a = buf) + fread(buf, 1, bufl, stdin), a == b) ? EOF
                                                                        : *a++;
}
inline int read() {
  int x = 0, f = 1;
  char c = nchar();
  for (; !isdigit(c); c = nchar())
    if (c == '-') f = -1;
  for (; isdigit(c); c = nchar()) x = x * 10 + c - '0';
  return x * f;
}
const int maxn = 5e3 + 1;
int n, f[maxn][maxn][2], g[maxn][2], rt = 0;
template <typename T>
inline void Min(T &x, T y) {
  if (y < x) x = y;
}
namespace tree {
vector<int> t[maxn];
inline void add(int x, int y) { t[x].push_back(y); }
int dfs(int x, int fa) {
  if (x != fa) t[x].erase(find(t[x].begin(), t[x].end(), fa));
  int sx = 0, (&fx)[maxn][2] = f[x];
  if (t[x].empty()) {
    fx[0][1] = fx[1][0] = 0;
    return sx = 1;
  }
  fx[0][0] = fx[0][1] = 0;
  for (vector<int>::iterator it = t[x].begin(); it != t[x].end(); ++it) {
    int v = *it, sv = dfs(v, x);
    memcpy(g, fx, sizeof fx), memset(fx, 0x3f, sizeof fx);
    for (int i = 0; i <= sx; ++i)
      for (int j = 0; j <= sv; ++j)
        for (int c = 0; c < 2; ++c)
          Min(fx[i + j][c], g[i][c] + min(f[v][j][c], f[v][j][c ^ 1] + 1));
    sx += sv;
  }
  return sx;
}
}  // namespace tree
int main() {
  n = read();
  for (int i = 1; i < n; ++i) {
    int x = read(), y = read();
    tree::add(x, y);
    tree::add(y, x);
  }
  if (n == 2) puts("1"), exit(0);
  memset(f, 0x3f, sizeof f);
  for (rt = 1; rt <= n && tree::t[rt].size() == 1; ++rt)
    ;
  int cnt = tree::dfs(rt, rt) >> 1;
  printf("%d\n", min(f[rt][cnt][0], f[rt][cnt][1]));
  return 0;
}
