#ifdef DBG1
  #define LOCAL
#endif

#ifdef LOCAL
  #define _GLIBCXX_DEBUG
#endif

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cassert>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <set>

#ifdef DBG1
    #define dbg(...) fprintf(stderr, __VA_ARGS__)
#else
    #define dbg(...)
#endif

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> pii;

vector <int> recolor(const vector <int> & col, const vector <int> & dist) {
  int n = int(col.size());
  vector <int> col2(n);
  vector <pair<pii, int>> tr(n);
  for (int i = 0; i < n; ++i) {
    tr[i] = make_pair(pii(col[i], dist[i]), i);
  }
  sort(tr.begin(), tr.end());
  for (int i = 0, j = -1; i < n; ++i) {
    if (i == 0 || tr[i - 1].first != tr[i].first) {
      ++j;
    }
    col2[tr[i].second] = j;
  }
  return col2;
}

void dfs(int s, int par, const vector <vector<int>> & ed, vector <int> & dist) {
  for (int v : ed[s]) {
    if (v == par) { continue; }
    dist[v] = dist[s] + 1;
    dfs(v, s, ed, dist);
  }
}

vector <int> findDist(int s, const vector<vector <int>> & ed) {
  vector <int> dist(ed.size(), -1);
  dist[s] = 0;
  dfs(s, -1, ed, dist);
  return dist;
}

bool is_good_col(const vector <int> & col) {
  vector <bool> used(col.size(), false);
  for (int x : col) {
    if (used[x]) { return false; }
    used[x] = true;
  }
  return true;
}

pii dfs2(int s, int par, const vector<vector<int>> & ed, const vector<bool> &onDiam) {
  vector <pii> childs;
  for (int v : ed[s]) {
    if (v == par || onDiam[v]) { continue; }
    childs.push_back(dfs2(v, s, ed, onDiam));
  }

  if (childs.empty()) {
    return pii(0, 1);
  }
  if (int(childs.size()) == 1) {
    return childs[0];
  }

  int cntBamboo = 0;
  int res = 0;
  for (auto x : childs) {
    if (x.second) {
      cntBamboo += 1;
    } else {
      res += x.first;
    }
  }
  return pii(res + max(cntBamboo - 1, 0), 0);
}

int solve2(int u, int v, const vector<vector<int>> & ed, 
           const vector<int> & distU,
           const vector<int> & distV
           ) {
  int n = int(ed.size());
  assert(distU[u] == 0);
  assert(distV[v] == 0);
  assert(distU[v] == distV[u]);
  int diam = distU[v];
  vector <int> path(diam + 1);
  for (int i = 0; i < n; ++i) {
    if (distU[i] + distV[i] == diam) {
      path[distU[i]] = i;
    }
  }
  vector <bool> onDiam(n, false);
  dbg("diam: \n");
  for (int v : path) {
    onDiam[v] = true;
    dbg("%d ", v);
  }
  dbg("\n");
  assert(path[0] == u && path.back() == v);
  int res = 0;
  for (int v : path) {
    auto cur = dfs2(v, -1, ed, onDiam);
    dbg("v %d cur %d %d\n", v, cur.first, cur.second);
    res += cur.first;
  }
  return res;
}

bool solve() {
  int n;
  if (scanf("%d", &n) != 1) { return false; }

  vector <vector<int>> ed(n);
  for (int i = 0; i < n - 1; ++i) {
    int u, v;
    scanf("%d%d", &u, &v);
    ed[u].push_back(v);
    ed[v].push_back(u);
  }

  vector <int> dist = findDist(0, ed);

  int u = 0;
  for (int i = 0; i < n; ++i) {
    if (dist[i] > dist[u]) {
      u = i;
    }
  }
  vector <bool> onDiam(n, false);
  int res = 1 + dfs2(u, -1, ed, onDiam).first;

  printf("%d\n", res);

  return true;
}

int main() {
  while (solve());
  return 0;
}

Measured memory_bytes: 18560