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 <vector>
#include <algorithm>
using namespace std;
#define ref(i,x,y)for(int i=x;i<=y;++i)
const int N=100001;
int n,m,cnt,res,head[N],du[N],q[N],t[N];
struct edge{int to,nxt;}e[N*2];
vector<int>s[N];bool vis[N];
bool cmp(int a,int b){return a>b;}
void add(int x,int y){e[++cnt]=(edge){y,head[x]};head[x]=cnt;}
int main(){
	scanf("%d",&n);
	ref(i,2,n){
		int x,y;scanf("%d%d",&x,&y);
		add(x,y),add(y,x);du[x]++,du[y]++;
	}
	res=1;
	ref(i,1,n)if(du[i]==1)q[++m]=i;
	ref(i,1,n){
		int x=q[i];vis[x]=1;
		if(s[x].empty())s[x].push_back(1);else{
			int p=0,r=1,sz=s[x].size()-1;
			if(t[x]>1){
				sort(s[x].begin(),s[x].end(),cmp);
				ref(i,1,sz)if(s[x][i]==s[x][i-1]){p=i;break;}
				if(p){
					r=s[x][p]+1;
					while(sz>=p-1)s[x].pop_back(),sz--;
				}
			}
			while(sz>=0&&s[x][sz]==r)s[x].pop_back(),r++,sz--;
			s[x].push_back(r);if(r>res)res=r;
		}
		int sz=s[x].size()-1;
		for(int j=head[x];j;j=e[j].nxt){
			int y=e[j].to;
			if(!vis[y]){
				ref(I,0,sz)s[y].push_back(s[x][I]);
				du[y]--;t[y]++;if(du[y]==1)q[++m]=y;
			}
		}
	}
	printf("%d\n",res-1);
}