#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fbo find_by_order
#define ook order_of_key

typedef long long ll;
typedef pair<ll,ll> ii;
typedef vector<int> vi;
typedef long double ld; 
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;
typedef set<int>::iterator sit;
typedef map<int,int>::iterator mit;
typedef vector<int>::iterator vit;

vi adj[100001];
/*
int h[100001];
ll dp[100001];

void dfs(int u, int p)
{
	if(p==-1) h[u]=0;
	else h[u]=h[p]+1;
	for(int i = 0; i < adj[u].size(); i++)
	{
		if(adj[u][i]==p) continue;
		dfs(adj[u][i],u);
	}
}
*/
/*
const int N = 1e5 + 3;

int subsize[N];
bool visited[N];
int treesize;
void dfs(int u, int par)
{
	subsize[u] = 1;
	for(int i = 0; i < adj[u].size(); i++)
	{
		int v = adj[u][i];
		if(visited[v]) continue;
		if(v == par) continue;
		dfs(v, u);
		subsize[u] += subsize[v];
	}
	treesize=subsize[u];
}

int centroid(int u, int par)
{
	int best = 0;
	for(int i = 0; i < adj[u].size(); i++)
	{
		int v = adj[u][i];
		if(visited[v]) continue;
		if(v == par) continue;
		best=max(best,subsize[v]);
	}
	for(int i = 0; i < adj[u].size(); i++)
	{
		int v = adj[u][i];
		if(visited[v]) continue;
		if(v == par) continue;
		int maxsize = treesize-subsize[v];
		for(int j = 0; j < adj[v].size(); j++)
		{
			int w = adj[v][j];
			if(w==u) continue;
			if(visited[w]) continue;.
			maxsize=max(maxsize,subsize[w]);
		}
		//if(subsize[v]>treesize-subsize[v]) return centroid(v, u);
		if(maxsize<best) return centroid(v,u);
	}
	return u;
}

int compsolve(int u)
{
	dfs(u, -1);
	int cent = centroid(u, -1);
	//cerr<<u<<' '<<cent<<'\n';
	visited[cent]=1;
	int ans = -1;
	for(int i = 0; i < adj[cent].size(); i++)
	{
		int v = adj[cent][i];
		if(visited[v]) continue;
		ans=max(ans,compsolve(v));
	}
	return ans+1;
}
*/

vi dp[100001];
int best[100001];
int par[100001];
void dfs(int u, int p)
{
	par[u]=p;
	for(int i = 0; i < adj[u].size(); i++)
	{
		int v = adj[u][i];
		if(v==p) continue;
		dfs(v,u);
	}
	int a = -1;
	map<int,int> ma;
	for(int i = 0; i < adj[u].size(); i++)
	{
		int v = adj[u][i];
		if(v==p) continue;
		for(vit it = dp[v].begin(); it != dp[v].end(); it++)
		{
			ma[(*it)]++;
		}
	}
	for(mit it = ma.begin(); it != ma.end(); it++)
	{
		if(it->se>=2) a = it->fi;
	}
	int b = a + 1;
	while(ma[b]>0)
	{
		b++;
	}
	dp[u].pb(b);
	for(mit it = ma.begin(); it != ma.end(); it++)
	{
		if(it->fi>b) dp[u].pb(it->fi);
	}
	/*
	best[u] = u;
	if(child>=0)
	{
		int z = best[child];
		best[u] = z;
		while(best[u]!=u)
		{
			int p = par[best[u]];
			int gain = dp[best[u]]+1;
			
		}
	}
	*/
}

int main()
{
	ios_base::sync_with_stdio(0); cin.tie(0);
	int n; cin>>n;
	for(int i = 0; i < n - 1; i++)
	{
		int u, v; cin>>u>>v;
		u--; v--;
		adj[u].pb(v); adj[v].pb(u);
	}
	dfs(0,-1);
	vit it = dp[0].end();
	it--;
	cout<<(*it)<<'\n';
	//cout<<compsolve(0)<<'\n';
	/*
	dp[1] = 2;
	for(int i = 2; i <= 60; i++)
	{
		dp[i] = (dp[i-1]*2+2);
	}
	dfs(0,-1);
	int best = 0; int idx = 0;
	for(int i = 0; i < n; i++)
	{
		if(h[i]>best)
		{
			best=h[i];
			idx=i;
		}
	}
	dfs(idx,-1);
	best=0;
	for(int i = 0; i < n; i++)
	{
		if(h[i]>best)
		{
			best=h[i];
		}
	}
	//cerr<<best<<'\n';
	for(int i = 1; i <= 60; i++)
	{
		if(best<=dp[i])
		{
			cout<<i<<'\n';
			return 0;
		}
	}
	*/
	
}


Measured memory_bytes: 26752