#include <bits/stdc++.h>   using namespace std;   template <typename T>   bool readInteger(T& x) {     char c, r = 0, n = 0;     x = 0;     for (;;) {       c = getchar();       if ((c < 0) && (!r))         return (0);       else if ((c ==  - ) && (!r))         n = 1;       else if ((c >=  0 ) && (c <=  9 ))         x = x * 10 + c -  0 , r = 1;       else if (r)         break;     }     if (n) x = -x;     return (1);   }   template <typename T, T MOD>   struct ModInt {     T value;     ModInt() : value(0) {}     ModInt(T x) {       x %= MOD;       if (x < 0) x += MOD;       value = x;     }       private:     T __________________(T ___, T ____) {       if (!____) return ___;       return __________________(____, ___ % ____);     }     T _____________(T _, T __, T ____, T ___) {       T _____, ______, _______ = ____ - _;       assert(!(_______ % __________________(__, ___)));       for (_____ = ______ = 0; _____ - ______ != _______;) {         _____ = (_______ + ______ + __ - 1) / __ * __;         ______ = (_____ - _______ + ___ - 1) / ___ * ___;       }       return _____ + _;     }       public:     ModInt& operator+=(ModInt x) {       value += x.value;       if (value >= MOD) value -= MOD;       return *this;     }     ModInt& operator-=(ModInt x) {       value -= x.value;       if (value < 0) value += MOD;       return *this;     }     ModInt& operator*=(ModInt x) {       value *= x.value;       value %= MOD;       return *this;     }     ModInt& operator/=(ModInt x) {       x.invert();       return *this *= x;     }     ModInt operator+(ModInt x) const {       ModInt o = *this;       o += x;       return o;     }     ModInt operator-(ModInt x) const {       ModInt o = *this;       o -= x;       return o;     }     ModInt operator*(ModInt x) const {       ModInt o = *this;       o *= x;       return o;     }     ModInt operator/(ModInt x) const {       ModInt o = *this;       o /= x;       return o;     }     bool operator==(ModInt x) const { return value == x.value; }     bool operator!=(ModInt x) const { return !(*this == x); }     ModInt operator-() const { return ModInt(0) - *this; }     ModInt operator^(long long x) const {       ModInt ret = 1;       ModInt mul = *this;       while (x) {         if (x & 1) ret *= mul;         mul *= mul;         x >>= 1;       }       return ret;     }     ModInt& operator^=(long long x) { return *this = *this ^ x; }       private:     void invert() { *this ^= MOD - 2; }       public:     void answer() { std::cout << value << std::endl; }   };   const int MX = 2.1e5;   int N, K;   int ai[MX];   vector<int> E[MX];   vector<int> child[MX];   bool light[MX];   long long dp[MX][5];   const int NINF = -1e9;   void solve(int x) {     for (auto& o : (child[x])) solve(o);     long long useNow = NINF;     {       long long& ans = dp[x][4];       ans = NINF;       if (light[x]) {         {           long long sum = 1;           long long bestDelta = 0;           for (auto& o : (child[x])) {             sum += dp[o][3];             bestDelta = max(bestDelta, dp[o][4] - dp[o][3]);           }           sum += bestDelta;           ans = max(ans, sum);         }         {           long long sum = 1;           long long bestA = 0;           long long bestB = 0;           for (auto& o : (child[x])) {             long long v1 = max(0LL, dp[o][3]);             long long v2 = dp[o][2];             sum += v1;             long long delta = v2 - v1;             if (delta > bestA) {               bestB = bestA;               bestA = delta;             } else               bestB = max(bestB, delta);           }           useNow = sum + bestA + bestB;           ans = max(ans, useNow);         }       }     }     {       long long& ans = dp[x][3];       ans = NINF;       if (light[x]) {         long long sum = 1;         for (auto& o : (child[x])) sum += dp[o][3];         ans = max(ans, sum);       }     }     {       long long& ans = dp[x][2];       ans = NINF;       if (light[x]) {         long long sum = 1;         long long bestDelta = 0;         for (auto& o : (child[x])) {           long long v1 = max(0LL, dp[o][3]);           long long v2 = dp[o][2];           sum += v1;           bestDelta = max(bestDelta, v2 - v1);         }         sum += bestDelta;         ans = max(ans, sum);       }     }     {       long long& ans = dp[x][1];       ans = useNow;       for (auto& o : (child[x])) ans = max(ans, dp[o][1]);     }   }   int ROOT = 0;   bool ok(int threshold) {     for (int i = (0); i < int(N); i++) light[i] = ai[i] >= threshold;     if (light[ROOT]) return true;     solve(ROOT);     return dp[ROOT][1] >= K;   }   void init(int x, int par) {     for (auto& o : (E[x]))       if (o != par) {         child[x].push_back(o);         init(o, x);       }   }   int main() {     readInteger(N);     readInteger(K);     for (int i = (0); i < int(N); i++) readInteger(ai[i]);     for (int k = (0); k < int(N - 1); k++) {       int u, v;       readInteger(u);       readInteger(v);       --u, --v;       E[u].push_back(v);       E[v].push_back(u);     }     for (int i = (0); i < int(N); i++)       if (ai[i] < ai[ROOT]) ROOT = i;     init(ROOT, -1);     vector<int> vals(N);     for (int i = (0); i < int(N); i++) vals[i] = ai[i];     sort(vals.begin(), vals.end());     reverse(vals.begin(), vals.end());     int lo = K - 1;     int hi = N - 1;     while (lo != hi) {       int mid = (lo + hi) / 2;       if (ok(vals[mid]))         hi = mid;       else         lo = mid + 1;     }     printf( %d n , vals[lo]);   }