#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:512000000")
using namespace std;
void solve();
void precalc();
clock_t start;
int testNumber = 1;
bool todo = true;
int main() {
  start = clock();
  int t = 1;
  cout.sync_with_stdio(0);
  cin.tie(0);
  precalc();
  cout.precision(10);
  cout << fixed;
  int testNum = 1;
  while (t--) {
    solve();
    ++testNumber;
  }
  return 0;
}
template <typename T>
T binpow(T q, T w, T mod) {
  if (!w) return 1 % mod;
  if (w & 1) return q * 1LL * binpow(q, w - 1, mod) % mod;
  return binpow(q * 1LL * q % mod, w / 2, mod);
}
void precalc() {}
template <typename T>
T gcd(T q, T w) {
  while (w) {
    q %= w;
    swap(q, w);
  }
  return q;
}
template <typename T>
T lcm(T q, T w) {
  return q / gcd(q, w) * w;
}
int n, k;
vector<int> a;
vector<vector<int>> g;
vector<int> cnt;
vector<int> max_down;
vector<vector<pair<int, int>>> best_rest;
vector<int> have_all;
void dfs_down(int v, int p, int min_val) {
  cnt[v] = 1;
  have_all[v] = 1;
  max_down[v] = 1;
  for (int to : g[v]) {
    if (to == p) {
      continue;
    }
    dfs_down(to, v, min_val);
    cnt[v] += cnt[to];
    if (max_down[to] == cnt[to]) {
      have_all[v] += cnt[to];
      max_down[v] += max_down[to];
    } else {
      best_rest[v].push_back(make_pair(max_down[to], to));
    }
  }
  sort(best_rest[v].begin(), best_rest[v].end());
  reverse(best_rest[v].begin(), best_rest[v].end());
  if (best_rest[v].size() > 2) {
    best_rest[v].resize(2);
  }
  if (!best_rest[v].empty()) {
    max_down[v] += best_rest[v][0].first;
  }
  if (a[v] < min_val) {
    max_down[v] = 0;
    best_rest[v].clear();
    have_all[v] = 0;
    return;
  }
}
void dfs_up(int v, int p, bool good_up, int sum_up, int min_val) {
  if (good_up) {
    if (a[v] >= min_val) {
      have_all[v] += (n - cnt[v]);
    }
  } else {
    if (a[v] >= min_val) {
      best_rest[v].push_back(make_pair(sum_up, p));
      sort(best_rest[v].begin(), best_rest[v].end());
      reverse(best_rest[v].begin(), best_rest[v].end());
    }
  }
  for (int to : g[v]) {
    if (to == p) {
      continue;
    }
    bool new_good = best_rest[v].empty() ||
                    best_rest[v].size() == 1 && best_rest[v][0].second == to;
    int new_sum_up = have_all[v];
    if (max_down[to] == cnt[to]) {
      new_sum_up -= cnt[to];
    }
    for (auto item : best_rest[v]) {
      if (item.second != to) {
        new_sum_up += item.first;
        break;
      }
    }
    if (a[v] >= min_val) {
      dfs_up(to, v, new_good, new_sum_up, min_val);
    } else {
      dfs_up(to, v, false, 0, min_val);
    }
  }
}
bool check(int min_val) {
  cnt.assign(n, 0);
  max_down.assign(n, 0);
  best_rest.clear();
  best_rest.resize(n);
  have_all.assign(n, 0);
  dfs_down(0, 0, min_val);
  dfs_up(0, 0, true, 0, min_val);
  for (int v = 0; v < n; ++v) {
    if (a[v] < min_val) {
      continue;
    }
    if (have_all[v] >= k) {
      return true;
    }
    if (!best_rest[v].empty() && have_all[v] + best_rest[v][0].first >= k) {
      return true;
    }
  }
  return false;
}
void solve() {
  cin >> n >> k;
  a.resize(n);
  for (int i = 0; i < n; ++i) {
    cin >> a[i];
  }
  g.resize(n);
  for (int i = 1; i < n; ++i) {
    int u, v;
    cin >> u >> v;
    --u;
    --v;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  int L = 0, R = 1e6 + 1;
  while (L + 1 < R) {
    int M = (L + R) / 2;
    if (check(M)) {
      L = M;
    } else {
      R = M;
    }
  }
  cout << L << "\n";
}
