#include <bits/stdc++.h>
using namespace std;
int node_time[200005];
vector<vector<int> > graph;
bool visit[200005];
set<pair<int, int> >::iterator it;
set<pair<int, int> >::reverse_iterator rit;
struct state {
  set<pair<int, int> > max_depth;
  int max_subtree;
  bool take_all_subtree;
  void insert_to_set(pair<int, int> p) {
    max_depth.insert(p);
    if ((int)max_depth.size() > 2) {
      max_depth.erase(max_depth.begin());
    }
  }
  int get_max_depth() {
    int ret = 0;
    if ((int)max_depth.size() != 0) {
      rit = max_depth.rbegin();
      ret = (rit->first);
    }
    return ret;
  }
  int get_answer() {
    int ret = 1;
    if (take_all_subtree) {
      ret += max_subtree;
    } else {
      ret += max_subtree + get_max_depth();
    }
    return ret;
  }
  void clear_all() {
    max_depth.clear();
    max_subtree = 0;
    take_all_subtree = 0;
  }
  void print(int node) {
    cout << node << " " << max_subtree << " " << take_all_subtree << " ";
    for (it = max_depth.begin(); it != max_depth.end(); it++) {
      cout << "(" << (it->first) << ", " << (it->second) << ") ";
    }
    cout << endl;
  }
};
state dp[200005];
state dfs_1(int node, int &value) {
  visit[node] = 1;
  dp[node].take_all_subtree = 1;
  state temp, ret;
  for (int i = 0; i < (int)graph[node].size(); i++) {
    int child = graph[node][i];
    if (!visit[child]) {
      temp = dfs_1(child, value);
      if (temp.take_all_subtree) {
        dp[node].max_subtree += temp.max_subtree;
      } else {
        dp[node].insert_to_set(
            {temp.get_max_depth() + temp.max_subtree, child});
        dp[node].take_all_subtree = 0;
      }
    }
  }
  if (node_time[node] < value) {
    dp[node].max_depth.clear();
    dp[node].max_subtree = 0;
    dp[node].take_all_subtree = 0;
    ret = dp[node];
  } else {
    ret = dp[node];
    ret.max_subtree++;
  }
  return ret;
}
void dfs_2(int node, state temp, int parent, int value) {
  visit[node] = 1;
  if (node_time[node] >= value && parent != -1) {
    if (temp.take_all_subtree) {
      dp[node].max_subtree += temp.max_subtree;
    } else {
      dp[node].insert_to_set({temp.get_max_depth() + temp.max_subtree, parent});
      dp[node].take_all_subtree = 0;
    }
  }
  state ret = dp[node];
  for (int i = 0; i < (int)graph[node].size(); i++) {
    int child = graph[node][i];
    if (!visit[child]) {
      if (dp[child].take_all_subtree) {
        if (node_time[node] >= value) {
          int temp2 = dp[child].max_subtree;
          ret.max_subtree -= dp[child].max_subtree;
          ret.max_subtree -= 1;
          dfs_2(child, ret, node, value);
          ret.max_subtree += temp2;
          ret.max_subtree += 1;
        } else {
          dfs_2(child, ret, node, value);
        }
      } else if (node_time[node] >= value) {
        set<pair<int, int> > temp2 = ret.max_depth;
        pair<int, int> inserted = {dp[child].get_max_depth() +
                                       dp[child].max_subtree +
                                       (node_time[child] >= value),
                                   child};
        ret.max_depth.erase(inserted);
        if ((int)ret.max_depth.size() == 0) {
          ret.take_all_subtree = 1;
          ret.max_subtree += 1;
          dfs_2(child, ret, node, value);
          ret.take_all_subtree = 0;
          ret.max_subtree -= 1;
        } else {
          ret.max_subtree += 1;
          dfs_2(child, ret, node, value);
          ret.max_subtree -= 1;
        }
        ret.max_depth = temp2;
      } else {
        dfs_2(child, ret, node, value);
      }
    }
  }
}
bool valid(int n, int k, int value) {
  int mx = 0;
  memset(visit, 0, sizeof(visit));
  for (int i = 1; i <= n; i++) {
    dp[i].clear_all();
  }
  dfs_1(1, value);
  memset(visit, 0, sizeof(visit));
  dfs_2(1, dp[1], -1, value);
  for (int i = 1; i <= n; i++) {
    if (node_time[i] >= value) {
      mx = max(mx, dp[i].get_answer());
    }
  }
  return mx >= k;
}
int bs(int n, int k) {
  int st = 1, ed = 1e6;
  while (st < ed) {
    int mid = st + (ed - st + 1) / 2;
    if (valid(n, k, mid)) {
      st = mid;
    } else {
      ed = mid - 1;
    }
  }
  return st;
}
int main() {
  int n, k;
  int a;
  int u, v;
  int answer;
  scanf("%d%d", &n, &k);
  graph.resize(n + 1);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a);
    node_time[i] = a;
  }
  for (int i = 1; i < n; i++) {
    scanf("%d%d", &u, &v);
    graph[u].push_back(v);
    graph[v].push_back(u);
  }
  answer = bs(n, k);
  printf("%d\n", answer);
  return 0;
}
