#include <bits/stdc++.h>
using namespace std;
long long int powm(long long int a, int b, int n) {
  long long int rm = 1;
  while (b) {
    if (b % 2) {
      rm = (rm * a) % n;
    }
    a = (a * a) % n;
    b /= 2;
  }
  return rm;
}
vector<int> edge[int(2e5 + 1000)], branch[int(2e5 + 1000)],
    prefix[int(2e5 + 1000)], suffix[int(2e5 + 1000)];
vector<bool> blocked_ball[int(2e5 + 1000)];
int a[int(2e5 + 1000)], k, up[int(2e5 + 1000)], n, ans = 0;
pair<bool, int> dfs1(int vertex, int parent, int cutOff) {
  pair<bool, int> return_block = make_pair(false, 0);
  int mxadd = 0;
  for (int i = 0; i < edge[vertex].size(); ++i) {
    int vr = edge[vertex][i];
    if (vr != parent) {
      pair<bool, int> block = dfs1(vr, vertex, cutOff);
      if (block.first) {
        return_block.first = true;
        blocked_ball[vertex][i] = true;
        branch[vertex][i] = block.second;
        mxadd = max(mxadd, block.second);
      } else {
        return_block.second += block.second;
        blocked_ball[vertex][i] = false;
        branch[vertex][i] = block.second;
      }
    } else {
      up[vertex] = i;
    }
  }
  return_block.second += mxadd;
  if (a[vertex] < cutOff) {
    return_block.first = true;
    return_block.second = 0;
  } else {
    return_block.second++;
  }
  return return_block;
}
void dfs2(int vertex, int parent, int cutOff, pair<bool, int> block) {
  if (vertex != 1) {
    if (block.first) {
      branch[vertex][up[vertex]] = block.second;
      blocked_ball[vertex][up[vertex]] = true;
    } else {
      branch[vertex][up[vertex]] = block.second;
      blocked_ball[vertex][up[vertex]] = false;
    }
  }
  int proper = 0, sofar = 0;
  int L = int(1e9 + 7), R = -1;
  for (int i = 0; i < edge[vertex].size(); ++i) {
    if (blocked_ball[vertex][i] == false) {
      proper += branch[vertex][i];
    } else {
      sofar = max(sofar, branch[vertex][i]);
      if (L == int(1e9 + 7)) L = i;
    }
    prefix[vertex][i] = sofar;
  }
  sofar = 0;
  for (int i = edge[vertex].size() - 1; i >= 0; i--) {
    if (blocked_ball[vertex][i] == true) {
      sofar = max(sofar, branch[vertex][i]);
      if (R == -1) R = i;
    }
    suffix[vertex][i] = sofar;
  }
  pair<bool, int> send;
  for (int i = 0; i < edge[vertex].size(); ++i) {
    int vr = edge[vertex][i];
    if (vr != parent) {
      send = make_pair(false, 0);
      if (i > 0) send.second = prefix[vertex][i - 1];
      if (i < edge[vertex].size() - 1)
        send.second = max(send.second, suffix[vertex][i + 1]);
      if (L < i) send.first = true;
      if (R > i) send.first = true;
      if (blocked_ball[vertex][i] == false)
        send.second += proper - branch[vertex][i];
      else
        send.second += proper;
      if (a[vertex] < cutOff) {
        send = make_pair(true, 0);
      } else {
        send.second++;
      }
      dfs2(vr, vertex, cutOff, send);
    }
  }
  if (a[vertex] >= cutOff) {
    ans = max(ans, proper + prefix[vertex][edge[vertex].size() - 1] + 1);
  }
}
bool go(int cutOff) {
  ans = 0;
  dfs1(1, 0, cutOff);
  dfs2(1, 0, cutOff, make_pair(false, 0));
  return (ans >= k);
}
int main() {
  int u, v, f = 0;
  scanf("%d", &n);
  ;
  scanf("%d", &k);
  ;
  for (int i = int(1); i <= (int)n; i++) {
    scanf("%d", &a[i]);
    ;
    f = max(f, a[i]);
  }
  for (int i = int(1); i <= (int)n - 1; i++) {
    scanf("%d", &u);
    ;
    scanf("%d", &v);
    ;
    edge[u].push_back(v);
    edge[v].push_back(u);
  }
  for (int i = int(1); i <= (int)n; i++) {
    branch[i].resize(edge[i].size() + 2);
    blocked_ball[i].resize(edge[i].size() + 2);
    prefix[i].resize(edge[i].size() + 2);
    suffix[i].resize(edge[i].size() + 2);
  }
  int it = 1, m;
  while (it != f) {
    m = (it + f) / 2;
    if (go(m + 1))
      it = m + 1;
    else
      f = m;
  }
  printf("%d\n", f);
  return 0;
}
