Problem: This winter is so... well, you've got the idea :-) The Nvodsk road system can be represented as n junctions connected with n - 1 bidirectional roads so that there is a path between any two junctions. The organizers of some event want to choose a place to accommodate the participants (junction v), and the place to set up the contests (junction u). Besides, at the one hand, they want the participants to walk about the city and see the neighbourhood (that's why the distance between v and u should be no less than l). On the other hand, they don't want the participants to freeze (so the distance between v and u should be no more than r). Besides, for every street we know its beauty — some integer from 0 to 109. Your task is to choose the path that fits in the length limits and has the largest average beauty. We shall define the average beauty as a median of sequence of the beauties of all roads along the path.

We can put it more formally like that: let there be a path with the length k. Let ai be a non-decreasing sequence that contains exactly k elements. Each number occurs there exactly the number of times a road with such beauty occurs along on path. We will represent the path median as number a⌊k / 2⌋, assuming that indexation starting from zero is used. ⌊x⌋ — is number х, rounded down to the nearest integer.

For example, if a = {0, 5, 12}, then the median equals to 5, and if a = {0, 5, 7, 12}, then the median is number 7.

It is guaranteed that there will be at least one path with the suitable quantity of roads.

Input

The first line contains three integers n, l, r (1 ≤ l ≤ r < n ≤ 105).

Next n - 1 lines contain descriptions of roads of the Nvodsk, each line contains three integers ai, bi, ci (1 ≤ ai, bi ≤ n, 0 ≤ ci ≤ 109, ai ≠ bi) — junctions ai and bi are connected with a street whose beauty equals ci.

Output

Print two integers — numbers of the junctions, where to accommodate the participants and set up the contests, correspondingly. If there are multiple optimal variants, print any of them.

Examples

Input

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


Output

4 1


Input

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


Output

6 3


Input

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


Output

4 3


Input

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


Output

5 1

Note

In the first sample all roads have the same beauty. That means that all paths of the positive length have the same median. Thus, any path with length from 3 to 4, inclusive will be valid for us.

In the second sample the city looks like that: 1 - 2 - 3 - 4 - 5 - 6. Two last roads are more valuable and we should choose any path that contains both of them and has the suitable length. It is either the path between 2 and 6 or the path between 3 and 6.

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
const int mod = 998244353, N = 1e5 + 10, INF = 0x3f3f3f3f;
template <typename T>
inline T read() {
  T x = 0;
  bool f = 0;
  char ch = getchar();
  while (!isdigit(ch)) {
    f = ch == '-';
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return f ? -x : x;
}
template <typename T>
inline T max(const T& x, const T& y) {
  return x > y ? x : y;
}
template <typename T>
inline T min(const T& x, const T& y) {
  return x < y ? x : y;
}
template <typename T>
inline T abs(const T& x) {
  return x > 0 ? x : -x;
}
inline int Mod(int x) {
  if (x >= mod) {
    return x - mod;
  } else if (x < 0) {
    return x + mod;
  } else {
    return x;
  }
}
template <typename T1, typename T2>
struct pair {
  T1 first;
  T2 second;
  pair(const T1& x = 0, const T2& y = 0) {
    first = x;
    second = y;
  }
  friend pair operator+(const pair& x, const pair& y) {
    return pair(x.first + y.first, x.second + y.second);
  }
  friend pair operator-(const pair& x, const pair& y) {
    return pair(x.first - y.first, x.second - y.second);
  }
  friend bool operator<(const pair& x, const pair& y) {
    return x.first < y.first || (x.first == y.first && x.second < y.second);
  }
  friend bool operator<=(const pair& x, const pair& y) {
    return x.first < y.first || (x.first == y.first && x.second <= y.second);
  }
  friend bool operator>(const pair& x, const pair& y) {
    return x.first > y.first || (x.first == y.first && x.second > y.second);
  }
  friend bool operator>=(const pair& x, const pair& y) {
    return x.first > y.first || (x.first == y.first && x.second >= y.second);
  }
  friend bool operator==(const pair& x, const pair& y) {
    return x.first == y.first && x.second == y.second;
  }
  friend bool operator!=(const pair& x, const pair& y) {
    return x.first != y.first || x.second != y.second;
  }
};
template <typename T1, typename T2>
inline pair<T1, T2> make_pair(const T1& x, const T2& y) {
  return pair<T1, T2>(x, y);
}
template <typename T>
struct stack {
  int top;
  T vals[N];
  bool empty() { return !top; }
  void push(T x) { vals[++top] = x; }
  void pop() {
    if (top > 0) {
      --top;
    }
    return;
  }
  void clear() { top = 0; }
  T TOP() { return top ? vals[top] : T(-1); }
};
inline int ksm(int x, int y) {
  int ret = 1;
  for (; y; y /= 2, x = 1LL * x * x % mod) {
    if (y & 1) {
      ret = 1LL * ret * x % mod;
    }
  }
  return ret;
}
inline int ksc(int x, int y) {
  int ret = 0;
  for (; y; y /= 2, x = Mod(x + x)) {
    if (y & 1) {
      ret = Mod(ret + x);
    }
  }
  return ret;
}
using std::cin;
using std::cout;
using std::endl;
using std::ios;
using std::map;
using std::set;
using std::vector;
int n, l, r, sz[N], mxdep[N], dep[N], val[N], a[N], b[N], path_a[N], path_b[N],
    que[N], hd, tl, t[N];
bool vis[N];
vector<int> son[N];
vector<pair<int, pair<int, int>>> edge[N];
bool cmp(int x, int y) { return mxdep[x] < mxdep[y]; }
int find_root(int u, int fa, int S) {
  int mx = 0;
  sz[u] = 1;
  for (auto& j : edge[u]) {
    if (!vis[j.first] && j.first != fa) {
      int tmp = find_root(j.first, u, S);
      if (tmp) {
        return tmp;
      }
      mx = max(mx, sz[j.first]);
      sz[u] += sz[j.first];
    }
  }
  return max(mx, S - sz[u]) <= S / 2 ? u : 0;
}
void calcsz(int u, int fa) {
  sz[u] = 1;
  for (auto& j : edge[u]) {
    if (!vis[j.first] && j.first != fa) {
      calcsz(j.first, u);
      sz[u] += sz[j.first];
    }
  }
  return;
}
void build_tree(int u) {
  calcsz(u, 0);
  vis[u] = 1;
  for (auto& j : edge[u]) {
    if (!vis[j.first]) {
      int rt = find_root(j.first, 0, sz[j.first]);
      son[u].push_back(rt);
      build_tree(rt);
    }
  }
  return;
}
void dfs(int u, int fa) {
  dep[u] = dep[fa] + 1;
  mxdep[u] = dep[u];
  for (auto& j : edge[u]) {
    if (!vis[j.first] && fa != j.first) {
      val[j.first] = val[u] + j.second.second;
      dfs(j.first, u);
      mxdep[u] = max(mxdep[u], mxdep[j.first]);
    }
  }
}
void dfs_1(int u, int fa) {
  if (val[u] > b[dep[u]]) {
    b[dep[u]] = val[u];
    path_b[dep[u]] = u;
  }
  for (auto& j : edge[u]) {
    if (!vis[j.first] && j.first != fa) {
      dfs_1(j.first, u);
    }
  }
}
int rt, A, B, ansA, ansB, flag;
vector<int> child;
void solve(int u) {
  vis[u] = 1;
  val[u] = 0;
  child.clear();
  dfs(u, 0);
  for (auto& j : edge[u]) {
    if (!vis[j.first]) {
      child.push_back(j.first);
    }
  }
  std::sort(child.begin(), child.end(), cmp);
  for (int i = 0; i <= mxdep[u]; ++i) {
    a[i] = -INF;
  }
  int hx = 0;
  path_a[0] = u;
  a[0] = 0;
  for (auto& j : child) {
    for (int i = 0; i <= mxdep[j]; ++i) {
      b[i] = -INF;
    }
    dfs_1(j, 0);
    hd = 1;
    tl = 0;
    for (int i = min(r - 1, hx); i >= l - 1; --i) {
      if (a[i] != -INF) {
        while (hd <= tl && a[que[tl]] <= a[i]) {
          --tl;
        }
        que[++tl] = i;
      }
    }
    for (int i = 1; i <= mxdep[j]; ++i) {
      while (hd <= tl && que[hd] + i > r) {
        ++hd;
      }
      if (l - i <= hx && l >= i && a[l - i] != -INF) {
        while (hd <= tl && a[que[tl]] <= a[l - i]) {
          --tl;
        }
        que[++tl] = l - i;
      }
      if (hd <= tl && b[i] + a[que[hd]] >= 0) {
        flag = 1;
        A = path_a[que[hd]];
        B = path_b[i];
        return;
      }
    }
    for (int i = 1; i <= mxdep[j]; ++i) {
      if (a[i] < b[i]) {
        a[i] = b[i];
        path_a[i] = path_b[i];
      }
    }
    hx = mxdep[j];
  }
  for (auto& j : son[u]) {
    solve(j);
  }
}
bool check(int x) {
  for (int i = 1; i <= n; ++i) {
    for (auto& j : edge[i]) {
      j.second.second = j.second.first >= x ? 1 : -1;
    }
  }
  memset(vis, 0, sizeof vis);
  flag = 0;
  solve(rt);
  return flag;
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout << std::fixed << std::setprecision(10);
  cin >> n >> l >> r;
  for (int i = 1, x, y, c; i < n; ++i) {
    cin >> x >> y >> c;
    t[i] = c;
    edge[x].emplace_back(y, make_pair(c, 0));
    edge[y].emplace_back(x, make_pair(c, 0));
  }
  std::sort(t + 1, t + 1 + n);
  int num = std::unique(t + 1, t + 1 + n) - t - 1;
  for (int i = 1; i <= n; ++i) {
    for (auto& j : edge[i]) {
      j.second.first = std::lower_bound(t + 1, t + 1 + num, j.second.first) - t;
    }
  }
  build_tree(rt = find_root(1, 0, n));
  dep[0] = -1;
  int L = 1, R = num;
  while (L <= R) {
    int mid = (L + R) / 2;
    if (check(mid)) {
      L = mid + 1;
      ansA = A;
      ansB = B;
    } else {
      R = mid - 1;
    }
  }
  solve(rt);
  cout << ansA << " " << ansB << endl;
  return 0;
}