Problem:
Score : 1400 points

Problem Statement

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.

Sample Input 1

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

Sample Output 1

2

A tree of uninity 1 consisting of vertices 1, 2, 3 and 4 can be constructed from the following: a tree of uninity 0 consisting of vertex 1, a tree of uninity 0 consisting of vertex 3, a tree of uninity 0 consisting of vertex 4, and vertex 2.

A tree of uninity 1 consisting of vertices 5 and 7 can be constructed from the following: a tree of uninity 1 consisting of vertex 5, and vertex 7.

A tree of uninity 2 consisting of vertices 1, 2, 3, 4, 5, 6 and 7 can be constructed from the following: a tree of uninity 1 consisting of vertex 1, 2, 3 and 4, a tree of uninity 1 consisting of vertex 5 and 7, and vertex 6.

Sample Input 2

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

Sample Output 2

3

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <bits/stdc++.h>

using namespace std;
//#define int long long
typedef pair<int,int> pii;
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
#define X first
#define Y second
#define endl '\n'
#define IOS ios::sync_with_stdio(0), cin.tie(0)
#define all(o) o.begin(), o.end()
const int maxn = 1e5 + 10;
bool bad[maxn];
vi adj[maxn];
int sz[maxn];
vi comp;
bool mark[maxn];
void dfs(int v,int p){
	if(bad[v]) return;
	if(v == p) comp.clear();
	comp.push_back(v);
	sz[v] = 1;
	mark[v] = true;
	for(auto u : adj[v]){
		if(u == p) continue;
		dfs(u, v);
		sz[v] += sz[u];
	}
}
main(){
	IOS;
	int n;
	cin >> n;
	for(int i=0; i<n-1; i++){
		int u, v;
		cin >> u >> v;
		u--, v--;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}
	int rem = n;
	int tim = 0;
	while(rem){
		memset(sz, 0, sizeof sz);
		memset(mark, 0, sizeof mark);
		tim++;
		for(int i=0; i<n; i++){
			if(bad[i] || mark[i]) continue;
			dfs(i, i);
			int mn = 1e9, id = -1;
			for(auto v : comp){
				int mx = 0;
				for(auto u : adj[v]){
					if(bad[u]) continue;
					int t;
					if(sz[v] > sz[u]) t = sz[u];
					else t = sz[i] - 1 - sz[v];
					mx = max(mx, t);
				}
				if(mx < mn){
					mn = mx;
					id = v;
				}
			}
			bad[id] = true;
			rem--;
		}
	}
	cout << tim - 2 << endl;

}