#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline T getMax(const T &a, const T &b) {
  return a > b ? a : b;
}
template <typename T, typename... Args>
inline T getMax(const T &a, const Args &...args) {
  return getMax(a, getMax(args...));
}
template <typename T>
inline void checkMax(T &a, const T &b) {
  if (a < b) a = b;
}
template <typename T, typename... Args>
inline void checkMax(T &a, const Args &...args) {
  checkMax(a, getMax(args...));
}
template <typename T>
inline T getMin(const T &a, const T &b) {
  return a < b ? a : b;
}
template <typename T, typename... Args>
inline T getMin(const T &a, const Args &...args) {
  return getMin(a, getMin(args...));
}
template <typename T>
inline void checkMin(T &a, const T &b) {
  if (a > b) a = b;
}
template <typename T, typename... Args>
inline void checkMin(T &a, const Args &...args) {
  checkMin(a, getMin(args...));
}
const int INF = 0x3f3f3f3f;
const long long llINF = 0x3f3f3f3f3f3f3f3f;
const int MAXN = 1e5 + 5;
struct Graph {
  static const int MAXM = MAXN << 1;
  int len, head[MAXN], to[MAXM], nxt[MAXM], w[MAXM];
  Graph() { memset(head, -1, sizeof(head)); }
  void add_edge(int u, int v, int _w) {
    to[++len] = v;
    nxt[len] = head[u];
    head[u] = len;
    w[len] = _w;
    to[++len] = u;
    nxt[len] = head[v];
    head[v] = len;
    w[len] = _w;
  }
} G;
struct SegmentTree {
  static const int MAXM = MAXN << 2;
  int tag[MAXM];
  pair<int, int> val[MAXM];
  void build(int k, int l, int r) {
    tag[k] = 0;
    val[k] = {-INF, 0};
    if (l == r) return;
    int mid = (l + r) >> 1;
    build(k << 1, l, mid);
    build(k << 1 | 1, mid + 1, r);
  }
  void apply(int k, int v) { tag[k] += v, val[k].first += v; }
  void push_down(int k) {
    if (tag[k]) apply(k << 1, tag[k]), apply(k << 1 | 1, tag[k]), tag[k] = 0;
  }
  void push_up(int k) { val[k] = max(val[k << 1], val[k << 1 | 1]); }
  void modify(int k, int l, int r, int x, pair<int, int> v) {
    if (l == r) {
      checkMax(val[k], v);
      return;
    }
    push_down(k);
    int mid = (l + r) >> 1;
    if (x <= mid)
      modify(k << 1, l, mid, x, v);
    else
      modify(k << 1 | 1, mid + 1, r, x, v);
    push_up(k);
  }
  void modify(int k, int l, int r, int ql, int qr, int v) {
    if (l >= ql && r <= qr) {
      apply(k, v);
      return;
    }
    push_down(k);
    int mid = (l + r) >> 1;
    if (ql <= mid) modify(k << 1, l, mid, ql, qr, v);
    if (qr > mid) modify(k << 1 | 1, mid + 1, r, ql, qr, v);
    push_up(k);
  }
  pair<int, int> query(int k, int l, int r, int x) {
    if (l == r) return val[k];
    push_down(k);
    int mid = (l + r) >> 1;
    if (x <= mid)
      return query(k << 1, l, mid, x);
    else
      return query(k << 1 | 1, mid + 1, r, x);
  }
  pair<int, int> query(int k, int l, int r, int ql, int qr) {
    if (ql > qr) return {-INF, 0};
    if (l >= ql && r <= qr) return val[k];
    push_down(k);
    int mid = (l + r) >> 1;
    pair<int, int> res = {-INF, 0};
    if (ql <= mid) checkMax(res, query(k << 1, l, mid, ql, qr));
    if (qr > mid) checkMax(res, query(k << 1 | 1, mid + 1, r, ql, qr));
    return res;
  }
} T;
int n, L, R, tim, tot;
pair<int, int> res;
int len[MAXN], son[MAXN], wson[MAXN], dfn[MAXN], par[MAXN], a[MAXN];
void dfs1(int u, int fa) {
  for (int i = G.head[u]; i != -1; i = G.nxt[i]) {
    int v = G.to[i];
    if (v == fa) continue;
    dfs1(v, u);
    if (len[v] > len[son[u]]) son[u] = v, wson[u] = G.w[i];
  }
  len[u] = len[son[u]] + 1;
  par[u] = fa;
}
void dfs2(int u) {
  dfn[u] = ++tim;
  if (son[u]) dfs2(son[u]);
  for (int i = G.head[u]; i != -1; i = G.nxt[i]) {
    int v = G.to[i];
    if (v != son[u] && v != par[u]) dfs2(v);
  }
}
void dfs(int u, int mid, int &flag) {
  T.modify(1, 1, tim, dfn[u], {0, u});
  if (!son[u]) return;
  dfs(son[u], mid, flag);
  if (flag) return;
  T.modify(1, 1, tim, dfn[u] + 1, dfn[u] + len[u] - 1, wson[u] >= mid ? 1 : -1);
  pair<int, int> p =
      T.query(1, 1, tim, dfn[u] + L, dfn[u] + min(len[u] - 1, R));
  if (p.first >= 0) {
    flag = 1;
    res = {u, p.second};
    return;
  }
  for (int i = G.head[u]; i != -1; i = G.nxt[i]) {
    int v = G.to[i];
    if (v == par[u] || v == son[u]) continue;
    dfs(v, mid, flag);
    if (flag) return;
    int w = G.w[i] >= mid ? 1 : -1;
    for (int j = 1; j <= len[v]; j++) {
      pair<int, int> x = T.query(1, 1, tim, dfn[v] + j - 1);
      x.first += w;
      pair<int, int> y = T.query(1, 1, tim, dfn[u] + max(0, L - j),
                                 dfn[u] + min(len[u] - 1, R - j));
      if (x.first + y.first >= 0) {
        res = {x.second, y.second};
        flag = 1;
        return;
      }
    }
    for (int j = 1; j <= len[v]; j++) {
      pair<int, int> x = T.query(1, 1, tim, dfn[v] + j - 1);
      x.first += w;
      T.modify(1, 1, tim, dfn[u] + j, x);
    }
  }
}
bool check(int mid) {
  T.build(1, 1, n);
  int flag = 0;
  dfs(1, mid, flag);
  return flag;
}
int main() {
  scanf("%d%d%d", &n, &L, &R);
  for (int i = 1, u, v, w; i < n; i++) {
    scanf("%d%d%d", &u, &v, &w);
    G.add_edge(u, v, w);
    a[++tot] = w;
  }
  dfs1(1, 0);
  dfs2(1);
  sort(a + 1, a + 1 + tot);
  tot = unique(a + 1, a + 1 + tot) - a - 1;
  int l = 1, r = tot;
  pair<int, int> ans = {0, 0};
  while (l <= r) {
    int mid = (l + r) >> 1;
    if (check(a[mid]))
      ans = res, l = mid + 1;
    else
      r = mid - 1;
  }
  printf("%d %d\n", ans.first, ans.second);
  return 0;
}
