10
6 8
3 10
1 9
6 1
8 2
5 7
3 6
10 4
3 5
 1
 5
1 2
2 3
3 4
4 5
 7
2 3
2 6
1 2
3 7
6 5
3 4
 10
8 4
8 10
8 1
8 2
5 9
5 3
5 7
8 5
5 6
 10
8 6
3 4
10 9
7 10
1 3
4 2
6 1
5 8
9 5
 10
1 10
6 9
5 4
1 3
1 2
3 8
6 7
8 6
1 5
 20
13 4
7 6
9 13
9 2
9 16
4 18
16 5
11 15
16 14
13 12
13 8
16 17
7 1
9 19
17 3
15 20
1 11
2 7
5 10
 3
1 2
1 3
 50
18 47
18 12
42 16
21 44
43 39
20 27
25 1
11 29
9 24
19 42
3 34
16 38
14 48
23 41
8 43
29 2
40 4
45 36
43 9
49 3
41 17
41 15
35 49
43 20
5 32
34 46
8 21
43 45
29 40
39 26
27 33
24 50
38 7
39 19
43 31
24 10
3 14
39 22
43 23
47 13
20 11
25 8
16 30
44 18
19 37
39 5
49 28
25 35
46 6
 15
11 2
5 13
9 4
5 7
11 5
13 14
2 10
3 11
7 1
7 6
10 15
9 12
2 9
10 8
 31
15 2
23 19
11 4
26 6
1 20
14 11
19 13
26 12
12 27
20 14
22 21
4 16
10 18
5 23
4 31
12 8
2 17
19 30
14 26
2 28
22 7
23 9
20 5
5 15
9 29
15 10
6 25
6 24
9 3
11 22
 63
34 40
43 62
33 43
49 6
17 47
26 13
35 15
40 16
17 44
37 34
18 55
57 10
16 14
39 56
36 5
4 33
4 59
54 24
37 45
21 31
57 2
19 8
43 41
49 48
15 19
35 4
15 63
30 50
11 30
59 18
20 46
18 1
33 17
31 22
40 54
63 49
29 25
46 9
16 3
42 23
59 7
54 53
42 38
8 60
8 58
7 51
36 28
63 36
21 57
25 37
45 20
25 35
19 26
20 42
30 32
11 39
7 12
31 52
45 21
26 27
34 11
46 61

9
 1
 1
 1
 1
 2
 10
 18
 2
 13
 1
 3
 1

#include <bits/stdc++.h>
using namespace std;
void getre() {
  int x = 0;
  printf("%d\n", 1 / x);
}
void gettle() {
  int res = 1;
  while (1) res <<= 1;
  printf("%d\n", res);
}
template <typename T, typename S>
inline bool upmin(T &a, const S &b) {
  return a > b ? a = b, 1 : 0;
}
template <typename T, typename S>
inline bool upmax(T &a, const S &b) {
  return a < b ? a = b, 1 : 0;
}
template <typename N, typename PN>
inline N flo(N a, PN b) {
  return a >= 0 ? a / b : -((-a - 1) / b) - 1;
}
template <typename N, typename PN>
inline N cei(N a, PN b) {
  return a > 0 ? (a - 1) / b + 1 : -(-a / b);
}
template <typename N>
N gcd(N a, N b) {
  return b ? gcd(b, a % b) : a;
}
template <typename N>
inline int sgn(N a) {
  return a > 0 ? 1 : (a < 0 ? -1 : 0);
}
inline void gn(long long &x) {
  int sg = 1;
  char c;
  while (((c = getchar()) < '0' || c > '9') && c != '-')
    ;
  c == '-' ? (sg = -1, x = 0) : (x = c - '0');
  while ((c = getchar()) >= '0' && c <= '9') x = x * 10 + c - '0';
  x *= sg;
}
inline void gn(int &x) {
  long long t;
  gn(t);
  x = t;
}
inline void gn(unsigned long long &x) {
  long long t;
  gn(t);
  x = t;
}
inline void gn(double &x) {
  double t;
  scanf("%lf", &t);
  x = t;
}
inline void gn(long double &x) {
  double t;
  scanf("%lf", &t);
  x = t;
}
inline void gs(char *s) { scanf("%s", s); }
inline void gc(char &c) {
  while ((c = getchar()) > 126 || c < 33)
    ;
}
inline void pc(char c) { putchar(c); }
inline long long sqr(long long a) { return a * a; }
inline double sqrf(double a) { return a * a; }
const int inf = 0x3f3f3f3f;
const double pi = 3.14159265358979323846264338327950288L;
const double eps = 1e-6;
const long long mo = long long(1e18) + 3;
long long mul(long long x, long long y) {
  x %= mo, y %= mo;
  return (x * y - (long long)(x / (long double)mo * y) * mo + mo) % mo;
}
namespace myrand {
unsigned int x[5] = {107896582, 1107972621, 1195573091, 1224749359, 241825441};
unsigned int get16() {
  unsigned long long tmp = (107374182ll * x[0] + 104480ll * x[4]);
  unsigned int res = (tmp >> 31) + (tmp & 0x7fffffffu);
  x[0] = x[1], x[1] = x[2], x[2] = x[3], x[3] = x[4];
  return x[4] = res >= 2147483647 ? res - 2147483647 : res;
}
void mysrand(unsigned int seed) {
  for (int i = 0; i < 5; i++) seed = (seed + 1) % 2147483647, x[i] = seed;
  for (int i = 0; i < 5; i++) get16();
}
int randint() {
  int res = 0;
  res += int(get16());
  res += int(get16()) << 16;
  return res;
}
long long randll() {
  long long res = 0;
  res += (long long)(get16());
  res += (long long)(get16()) << 16;
  res += (long long)(get16()) << 32;
  res += (long long)(get16()) << 48;
  return res;
}
int randbit() { return ((get16()) >> 7) & 1; }
int myrand() {
  int x = randint();
  if (x < 0) return ~x;
  return x;
}
template <typename RandomAccessIterator>
void my_randomshuffle(RandomAccessIterator first, RandomAccessIterator last) {
  int n = last - first;
  for (int i = 1; i < n; i++) {
    int to = myrand() % (i + 1);
    swap(first[to], first[i]);
  }
}
};  // namespace myrand
long long wei[111111];
const int TREE_MAXV = 300000 + 5;
struct edge {
  int v, next;
} e[TREE_MAXV * 2];
int g[TREE_MAXV], etot;
int qu[TREE_MAXV], pre[TREE_MAXV];
int h[333333];
long long has[333333];
int n;
void ae(int u, int v) {
  e[etot].v = v;
  e[etot].next = g[u];
  g[u] = etot++;
}
void tree_init() {
  static bool ini = 0;
  if (!ini) {
    ini = 1;
    memset(g, -1, sizeof(g));
  } else {
    for (int i = 0; i <= n; i++) g[i] = -1;
  }
  etot = 0;
}
void readedge() {
  for (int i = 1; i < n; i++) {
    int x, y;
    gn(x);
    gn(y);
    ae(x, y);
    ae(y, x);
  }
}
void dfs(int u, int pr) {
  for (int i = g[u]; ~i; i = e[i].next)
    if (e[i].v != pr) {
      dfs(e[i].v, u);
      upmax(h[u], h[e[i].v] + 1);
    }
  long long ret = 1;
  for (int i = g[u]; ~i; i = e[i].next)
    if (e[i].v != pr) {
      ret = mul(ret, wei[h[u]] + has[e[i].v]);
    }
  has[u] = ret;
}
long long has2[333333];
long long hasful[333333];
int h2[333333];
long long lef1[333333], rig1[333333];
long long lef2[333333], rig2[333333];
void dfs2(int u, int pr) {
  int mh = 0, sh = 0;
  for (int i = g[u]; ~i; i = e[i].next)
    if (e[i].v != pr) {
      int tmp = h[e[i].v] + 1;
      if (tmp >= mh) {
        sh = mh;
        mh = tmp;
      } else if (tmp >= sh) {
        sh = tmp;
      }
    }
  if (pr != 0) {
    int tmp = h2[pr] + 1;
    if (tmp >= mh) {
      sh = mh;
      mh = tmp;
    } else if (tmp >= sh) {
      sh = tmp;
    }
  }
  int deg = 0;
  for (int i = g[u]; ~i; i = e[i].next)
    if (e[i].v != pr) {
      ++deg;
      rig1[deg] = lef1[deg] = (has[e[i].v] + wei[mh]) % mo;
      rig2[deg] = lef2[deg] = (has[e[i].v] + wei[sh]) % mo;
    }
  if (pr == 0)
    lef1[0] = lef2[0] = 1;
  else
    lef1[0] = (has2[pr] + wei[mh]) % mo, lef2[0] = (has2[pr] + wei[sh]) % mo;
  rig1[deg + 1] = rig2[deg + 1] = 1;
  for (int i = (1), _ed = (deg + 1); i < _ed; i++)
    lef1[i] = mul(lef1[i - 1], lef1[i]), lef2[i] = mul(lef2[i - 1], lef2[i]);
  for (int i = (deg + 1) - 1, _ed = (1); i >= _ed; i--)
    rig1[i] = mul(rig1[i + 1], rig1[i]), rig2[i] = mul(rig2[i + 1], rig2[i]);
  if (u == 1)
    hasful[u] = has[u];
  else
    hasful[u] = lef1[deg];
  int curd = 0;
  for (int i = g[u]; ~i; i = e[i].next)
    if (e[i].v != pr) {
      ++curd;
      if (h[e[i].v] + 1 == mh) {
        has2[e[i].v] = mul(lef1[curd - 1], rig1[curd + 1]);
        h2[e[i].v] = mh;
      } else {
        has2[e[i].v] = mul(lef2[curd - 1], rig2[curd + 1]);
        h2[e[i].v] = sh;
      }
    }
  for (int i = g[u]; ~i; i = e[i].next)
    if (e[i].v != pr) {
      dfs2(e[i].v, u);
    }
}
map<long long, int> ma;
int cnt = 0;
int an = 0;
int out;
void add(long long x) {
  if ((++ma[x]) == 1) cnt++;
}
void del(long long x) {
  if ((--ma[x]) == 0) cnt--;
}
void dfs3(int u, int pr) {
  ;
  if (upmax(an, cnt)) out = u;
  for (int i = g[u]; ~i; i = e[i].next)
    if (pr != e[i].v) {
      del(hasful[u]);
      del(has[e[i].v]);
      add(has2[e[i].v]);
      add(hasful[e[i].v]);
      dfs3(e[i].v, u);
      add(hasful[u]);
      add(has[e[i].v]);
      del(has2[e[i].v]);
      del(hasful[e[i].v]);
    }
}
int main() {
  for (int i = (0), _ed = (101111); i < _ed; i++) {
    wei[i] = myrand::randll() % mo;
  }
  gn(n);
  tree_init();
  readedge();
  dfs(1, 0);
  dfs2(1, 0);
  for (int u = (1), _ed = (n + 1); u < _ed; u++) add(has[u]);
  dfs3(1, 0);
  printf("%d\n", out);
  return 0;
}
