We will recursively define uninity of a tree, as follows: (Uni is a Japanese word for sea urchins.)

* A tree consisting of one vertex is a tree of uninity 0.
* Suppose there are zero or more trees of uninity k, and a vertex v. If a vertex is selected from each tree of uninity k and connected to v with an edge, the resulting tree is a tree of uninity k+1.



It can be shown that a tree of uninity k is also a tree of uninity k+1,k+2,..., and so forth.

You are given a tree consisting of N vertices. The vertices of the tree are numbered 1 through N, and the i-th of the N-1 edges connects vertices a_i and b_i.

Find the minimum k such that the given tree is a tree of uninity k.

Constraints

* 2 ≦ N ≦ 10^5
* 1 ≦ a_i, b_i ≦ N(1 ≦ i ≦ N-1)
* The given graph is a tree.

Input

The input is given from Standard Input in the following format:


N
a_1 b_1
:
a_{N-1} b_{N-1}


Output

Print the minimum k such that the given tree is a tree of uninity k.

Examples

Input

7
1 2
2 3
2 4
4 6
6 7
7 5


Output

2


Input

12
1 2
2 3
2 4
4 5
5 6
6 7
7 8
5 9
9 10
10 11
11 12


Output

3
#include <cstdio>
#include <algorithm>
#define rep(i,j,k) for (i=j;i<=k;i++)
#define down(i,j,k) for (i=j;i>=k;i--)
using namespace std;
const int N=1e5+5,K=20;
int n,i,j,u,v,ans;
int En,used[N][K],fst[N],nxt[N*2],to[N*2];
void add(int u,int v) { En++; nxt[En]=fst[u]; fst[u]=En; to[En]=v; }
void dfs(int x,int fa)
{
	int i,j,v,g;
	for (j=fst[x];j;j=nxt[j])
	if (to[j]!=fa)
	{
		v=to[j];
		dfs(v,x);
		rep(i,0,K-1)
		  used[x][i]+=used[v][i];
	}
	down(g,K-1,0)
		if (used[x][g]>1) break;
	g++;
	while (used[x][g]) g++;
	used[x][g]=1;
	rep(i,0,g-1) used[x][i]=0;
	ans=max(ans,g);
}
int main()
{
//	freopen("uninity.in","r",stdin);
//	freopen("uninity.out","w",stdout);
	scanf("%d",&n);
	rep(i,1,n-1)
	{
		scanf("%d%d",&u,&v);
		add(u,v); add(v,u);
	}
	dfs(1,1);
	printf("%d\n",ans);
	return 0;
}