#include <bits/stdc++.h>
using namespace std;
int i, i0, n, m, dp[100005][2], ans;
multiset<int> s[100005][2];
vector<int> mp[100005];
int get1(int x, bool f) {
  if (s[x][f].size())
    return *--s[x][f].end();
  else
    return 0;
}
void dfs(int now, int root) {
  for (int x : mp[now]) {
    if (x == root) continue;
    dfs(x, now);
    s[now][0].insert(max(dp[x][0], dp[x][1]));
    s[now][1].insert(dp[x][0]);
  }
  dp[now][1] = 1 + get1(now, 1);
  dp[now][0] =
      mp[now].size() - 1 - (now != 1 && mp[now].size() != 1) + get1(now, 0);
}
void solve(int now, int root);
void change_root(int nowa, int nowb) {
  int tmpa[2] = {dp[nowa][0], dp[nowa][1]},
      tmpb[2] = {dp[nowb][0], dp[nowb][1]};
  s[nowa][0].erase(s[nowa][0].find(max(dp[nowb][0], dp[nowb][1])));
  s[nowa][1].erase(s[nowa][1].find(dp[nowb][0]));
  dp[nowa][1] = 1 + get1(nowa, 1);
  dp[nowa][0] = mp[nowa].size() - 2 + get1(nowa, 0);
  s[nowb][0].insert(max(dp[nowa][0], dp[nowa][1]));
  s[nowb][1].insert(dp[nowa][0]);
  dp[nowb][1] = 1 + get1(nowb, 1);
  dp[nowb][0] = mp[nowb].size() - 2 + get1(nowb, 0);
  solve(nowb, nowa);
  dp[nowb][0] = tmpb[0], dp[nowb][1] = tmpb[1];
  dp[nowa][0] = tmpa[0], dp[nowa][1] = tmpa[1];
}
void solve(int now, int root) {
  ans = max(ans, max(dp[now][1], dp[now][0]));
  for (auto i : mp[now]) {
    if (i == root) continue;
    change_root(now, i);
  }
}
int main() {
  scanf("%d", &n);
  for (i = 1; i < n; i++) {
    int a, b;
    scanf("%d %d", &a, &b);
    mp[a].push_back(b);
    mp[b].push_back(a);
  }
  dfs(1, -1);
  solve(1, -1);
  printf("%d\n", ans);
  return 0;
}
