Problem: Little Timofey has a big tree — an undirected connected graph with n vertices and no simple cycles. He likes to walk along it. His tree is flat so when he walks along it he sees it entirely. Quite naturally, when he stands on a vertex, he sees the tree as a rooted tree with the root in this vertex.

Timofey assumes that the more non-isomorphic subtrees are there in the tree, the more beautiful the tree is. A subtree of a vertex is a subgraph containing this vertex and all its descendants. You should tell Timofey the vertex in which he should stand to see the most beautiful rooted tree.

Subtrees of vertices u and v are isomorphic if the number of children of u equals the number of children of v, and their children can be arranged in such a way that the subtree of the first son of u is isomorphic to the subtree of the first son of v, the subtree of the second son of u is isomorphic to the subtree of the second son of v, and so on. In particular, subtrees consisting of single vertex are isomorphic to each other.

Input

First line contains single integer n (1 ≤ n ≤ 105) — number of vertices in the tree.

Each of the next n - 1 lines contains two integers ui and vi (1 ≤ ui, vi ≤ 105, ui ≠ vi), denoting the vertices the i-th edge connects.

It is guaranteed that the given graph is a tree.

Output

Print single integer — the index of the vertex in which Timofey should stand. If there are many answers, you can print any of them.

Examples

Input

3
1 2
2 3


Output

1


Input

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


Output

1


Input

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


Output

2

Note

In the first example we can stand in the vertex 1 or in the vertex 3 so that every subtree is non-isomorphic. If we stand in the vertex 2, then subtrees of vertices 1 and 3 are isomorphic.

In the second example, if we stand in the vertex 1, then only subtrees of vertices 4 and 5 are isomorphic.

In the third example, if we stand in the vertex 1, then subtrees of vertices 2, 3, 4, 6, 7 and 8 are isomorphic. If we stand in the vertex 2, than only subtrees of vertices 3, 4, 6, 7 and 8 are isomorphic. If we stand in the vertex 5, then subtrees of vertices 2, 3, 4, 6, 7 and 8 are isomorphic, and subtrees of vertices 1 and 9 are isomorphic as well: 
    
    
      
      1     9  
     /\    /\  
    7  8  4  2  
    

Solution (in JAVA):

Solution:
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.util.HashMap;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.Map;
import java.math.BigInteger;
import java.io.BufferedReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		FastScanner in = new FastScanner(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskD solver = new TaskD();
		solver.solve(1, in, out);
		out.close();
	}

	static class TaskD {
		public void solve(int testNumber, FastScanner in, PrintWriter out) {
			n = in.nextInt();
			prepareMod();
			adj = new List[n];
			for (int i = 0; i < n; i++) {
				adj[i] = new ArrayList<>();
			}
			was = new boolean[3 * n];
			hash = new int[3 * n];
			depth = new int[3 * n];
			for (int i = 0; i < n; i++) {
				registerEdgeId(-1, i);
			}
			for (int i = 0; i < n - 1; i++) {
				int a = in.nextInt() - 1;
				int b = in.nextInt() - 1;
				adj[a].add(b);
				adj[b].add(a);
				registerEdgeId(a, b);
				registerEdgeId(b, a);
			}
			dfs1(-1, 0);
			dfs2(-1, 0);
			ans = -1;
			best = -1;
			counter = new Counter();
			dfs3(-1, 0);
			dfs4(-1, 0);
			out.println(ans + 1);
		}

		int MOD;
		long[] X;
		int ans;
		int best;

		int n;
		List<Integer>[] adj;
		boolean[] was;
		int[] hash;
		int[] depth;
		Counter counter;

		// The tree is rooted at 0.
		// Calculate depths and hashes for all tree ("forward") edges.
		private void dfs1(int parent, int root) {
			int e = edgeId(parent, root);
			depth[e] = 0;
			for (int child : adj[root]) {
				if (child == parent) {
					continue;
				}
				dfs1(root, child);
				int c = edgeId(root, child);
				depth[e] = Math.max(depth[e], 1 + depth[c]);
			}
			long curHash = 1;
			for (int child : adj[root]) {
				if (child == parent) {
					continue;
				}
				int c = edgeId(root, child);
				curHash = curHash * (X[depth[e]] + hash[c]) % MOD;
			}
			hash[e] = (int)curHash;
		}

		// Invariant: we've arrived at root from parent
		// and we know depths and hashes for all children of root
		// (tree edges when the tree is rooted at 0)
		// and for the root-to-parent edge (which is going in the opposite direction).
		private void dfs2(int parent, int root) {
			if (parent != -1) {
				int c = edgeId(root, parent);
				int e = edgeId(-1, root);
				depth[e] = Math.max(depth[edgeId(parent, root)], 1 + depth[c]);
				hash[e] = (int)(hash[edgeId(parent, root)] * (X[depth[e]] + hash[c]) % MOD);
			}

			int maxDepthChild1 = -1;
			int maxDepthChild2 = -1;
			List<Integer> children = new ArrayList<>();
			for (int child : adj[root]) {
				if (child == parent) {
					continue;
				}
				children.add(child);
				int c = edgeId(root, child);
				if (maxDepthChild1 < 0 || depth[c] > depth[edgeId(root, maxDepthChild1)]) {
					maxDepthChild2 = maxDepthChild1;
					maxDepthChild1 = child;
				} else if (maxDepthChild2 < 0 || depth[c] > depth[edgeId(root, maxDepthChild2)]) {
					maxDepthChild2 = child;
				}
			}

			// At most 3 entries.
			Map<Integer, int[]> prefProds = new HashMap<>();
			Map<Integer, int[]> suffProds = new HashMap<>();
			for (int i = 0; i < children.size(); i++) {
				int child = children.get(i);
				int c = edgeId(child, root);
				// In order to maintain the invariant, |c| is the only
				// edge that we need to update info about.
				depth[c] = 0;
				if (parent >= 0) {
					depth[c] = Math.max(depth[c], 1 + depth[edgeId(root, parent)]);
				}
				if (child != maxDepthChild1 && maxDepthChild1 >= 0) {
					depth[c] = Math.max(depth[c], 1 + depth[edgeId(root, maxDepthChild1)]);
				}
				if (child != maxDepthChild2 && maxDepthChild2 >= 0) {
					depth[c] = Math.max(depth[c], 1 + depth[edgeId(root, maxDepthChild2)]);
				}

				int[] pref = prefProds.get(depth[c]);
				int[] suff = suffProds.get(depth[c]);
				if (pref == null) {
					pref = new int[children.size()];
					suff = new int[children.size()];
					for (int j = 0; j < children.size(); j++) {
						int ch = children.get(j);
						pref[j] = (int)((X[depth[c]] + hash[edgeId(root, ch)]) % MOD);
						if (j > 0) {
							pref[j] = (int)(pref[j] * (long)(pref[j - 1]) % MOD);
						}
					}
					for (int j = children.size() - 1; j >= 0; j--) {
						int ch = children.get(j);
						suff[j] = (int)((X[depth[c]] + hash[edgeId(root, ch)]) % MOD);
						if (j + 1 < children.size()) {
							suff[j] = (int)(suff[j] * (long)(suff[j + 1]) % MOD);
						}
					}
					prefProds.put(depth[c], pref);
					suffProds.put(depth[c], suff);
				}
				hash[c] = 1;
				if (i > 0) {
					hash[c] = (int)(hash[c] * (long)pref[i - 1] % MOD);
				}
				if (i + 1 < children.size()) {
					hash[c] = (int)(hash[c] * (long)suff[i + 1] % MOD);
				}
				if (parent >= 0) {
					hash[c] = (int)(hash[c] * (X[depth[c]] + hash[edgeId(root, parent)]) % MOD);
				}
				dfs2(root, child);
			}
		}

		// Once the hashes have been computed, dfs3 and dfs4 are really
		// simple and just do what the problem asks using
		// the same framework: calculate everything in one dfs for the tree
		// rooted at 0 at then use another dfs to find out the
		// answers for the trees rooted at other vertices.
		private void dfs3(int parent, int root) {
			for (int child : adj[root]) {
				if (child == parent) {
					continue;
				}
				counter.add(hash[edgeId(root, child)]);
				dfs3(root, child);
			}
		}

		private void dfs4(int parent, int root) {
			if (best < counter.numDifferent) {
				best = counter.numDifferent;
				ans = root;
			}
			for (int child : adj[root]) {
				if (child == parent) {
					continue;
				}
				int h1 = hash[edgeId(root, child)];
				int h2 = hash[edgeId(child, root)];
				counter.remove(h1);
				counter.add(h2);
				dfs4(root, child);
				counter.add(h1);
				counter.remove(h2);
			}
		}

		Map<Long, Integer> edgeIds = new HashMap<>();
		private int edgeId(int a, int b) {
			long key = (a + 1) * (long)(n + 1) + (b + 1);
			return edgeIds.get(key);
		}

		private void registerEdgeId(int a, int b) {
			long key = (a + 1) * (long)(n + 1) + (b + 1);
			if (!edgeIds.containsKey(key)) {
				int v = edgeIds.size();
				edgeIds.put(key, v);
			}
		}

		private void prepareMod() {
			Random random = new Random(System.currentTimeMillis());
			MOD = 1000000000 + random.nextInt(10000000);
			while (!BigInteger.valueOf(MOD).isProbablePrime(100)) {
				++MOD;
			}

			X = new long[n + 1];
			for (int i = 0; i < X.length; i++) {
				while (X[i] == 0) {
					X[i] = random.nextInt(MOD);
				}
			}
		}

		class Counter {
			Map<Integer, Integer> m = new HashMap<>();
			int numDifferent = 0;

			void add(int k) {
				int v = 0;
				if (m.containsKey(k)) {
					v = m.get(k);
				} else {
					++numDifferent;
				}
				m.put(k, v + 1);
			}

			void remove(int k) {
				int v = m.get(k);
				if (v == 1) {
					--numDifferent;
					m.remove(k);
				} else {
					m.put(k, v - 1);
				}
			}
		}
	}

	static class FastScanner {
		private BufferedReader in;
		private StringTokenizer st;

		public FastScanner(InputStream stream) {
			in = new BufferedReader(new InputStreamReader(stream));
		}

		public String next() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					String rl = in.readLine();
					if (rl == null) {
						return null;
					}
					st = new StringTokenizer(rl);
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
			return st.nextToken();
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

	}
}