#include <bits/stdc++.h>
using namespace std;
const int maxn = 100005;
int end_at_root_without[maxn];
int end_at_root_with[maxn];
int max_subtree_without[maxn];
int max_subtree[maxn];
vector<vector<int> > neighbours(maxn);
void inline dfs(int u, int parent) {
  int node;
  for (int i = 0; i < neighbours[u].size(); i++) {
    node = neighbours[u][i];
    if (node == parent)
      continue;
    else
      dfs(node, u);
  }
  if ((u != 0) && (neighbours[u].size() == 1)) {
    end_at_root_with[u] = 1, end_at_root_without[u] = 0,
    max_subtree_without[u] = 0, max_subtree[u] = 1;
  } else {
    vector<int> child_end_at_root_wo, child_end_at_root, child_max_subtree,
        child_max_subtree_wo;
    int degree = 0;
    for (int i = 0; i < neighbours[u].size(); i++) {
      node = neighbours[u][i];
      if (node != parent) {
        child_end_at_root_wo.push_back(end_at_root_without[node]);
        child_end_at_root.push_back(
            max(end_at_root_without[node], end_at_root_with[node]));
        child_max_subtree_wo.push_back(max_subtree_without[node]);
        child_max_subtree.push_back(max_subtree[node]);
        degree++;
      }
    }
    sort(child_end_at_root_wo.begin(), child_end_at_root_wo.end(),
         greater<int>());
    sort(child_end_at_root.begin(), child_end_at_root.end(), greater<int>());
    sort(child_max_subtree.begin(), child_max_subtree.end(), greater<int>());
    sort(child_max_subtree_wo.begin(), child_max_subtree_wo.end(),
         greater<int>());
    end_at_root_with[u] = 1 + child_end_at_root_wo[0];
    end_at_root_without[u] = degree - 1 + child_end_at_root[0];
    max_subtree_without[u] = end_at_root_without[u];
    if (degree >= 2)
      max_subtree_without[u] =
          max(max_subtree_without[u],
              degree - 2 + child_end_at_root[0] + child_end_at_root[1]);
    max_subtree[u] = max(max(max(end_at_root_with[u], end_at_root_without[u]),
                             child_max_subtree[0]),
                         1 + child_max_subtree_wo[0]);
    if (degree >= 2) {
      max_subtree[u] = max(max_subtree[u], 1 + child_end_at_root_wo[0] +
                                               child_end_at_root_wo[1]);
      max_subtree[u] = max(max_subtree[u], degree - 2 + child_end_at_root[0] +
                                               child_end_at_root[1]);
    }
  }
}
int main() {
  int n;
  cin >> n;
  int a, b;
  for (int i = 0; i < n - 1; i++) {
    cin >> a >> b;
    a--, b--;
    neighbours[a].push_back(b), neighbours[b].push_back(a);
  }
  dfs(0, -1);
  cout << max_subtree[0] << endl;
}
