#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef pair<ll, ll> PP;
struct edge {
    ll to;     // 辺の行き先
    ll weight; // 辺の重み
    edge(ll t, ll w) : to(t), weight(w) { }
};
using Graph = vector<vector<ll>>;
using WeightedGraph = vector<vector<edge>>;

#define rep(i, n) for(int i = 0; i < (int)(n); i++)
#define all(v) v.begin(), v.end()
#define pb push_back
const ll INF = (1LL << 31) - 1;

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    ll n;
    cin >> n;
    vl a;
    ll sum=0;
    rep(i,n){
        ll x;
        cin >> x;
        sum += x;
        a.pb(sum);
    }
    vl s;
    ll y=0;
    s.pb(0);
    rep(i,n){
        y += a[i];
        s.pb(y);
    }
    vl m(n+1,0);
    for(ll i=1;i<n+1;i++){
        m[i]=max(m[i-1],a[i-1]);
    }
    ll ans = 0;
    for(ll i=1;i<n+1;i++){
        ans = max(ans, s[i-1]+m[i]);
    }
    cout<<ans<<endl;
    return 0;
}

#include <bits/stdc++.h>
#include <variant>

#define rep2(i,k,n) for(i64 i=(i64)(k);i<(i64)(n);i++)
#define rep(i,n) rep2(i,0,n)
#define all(x) begin(x),end(x)
#ifdef ENV_LOCAL
#define dump if (1) cerr
#else
#define dump if (0) cerr
#endif

using namespace std;
using namespace std::string_literals;

using i32 = int32_t;
using i64 = int64_t;
using f64 = double;
using f80 = long double;
using vi32 = vector<i32>;
using vi64 = vector<i64>;

//using namespace harudake;

tuple<i32,i32,i32> tree_dp(const vector<vi32>& g, i32 th, i32 i, i32 p = -1) {
  i32 ans = 0;
  i32 deepest = 0;
  i32 cover = -1e8;
  for (auto&& to : g[i]) {
    if (to == p) continue;
    auto [cst, dep, cov] = tree_dp(g, th, to, i);
    ans += cst;
    cover = max(cover, cov-1);
    deepest = max(deepest, dep+1);
  }
  if (deepest <= cover) deepest = -1e8;
  if (deepest == th) {
    ++ans;
    deepest = -1e8;
    cover = th;
  }
  return make_tuple(ans, deepest, cover);
}

//void dfs(const vector<vi32>& g, vi32& d, i32 i, i32 p = -1) {
//  for (auto&& to : g[i]) {
//    if (to == p) continue;
//    d[to] = d[i] + 1;
//    dfs(g, d, to, i);
//  }
//}
//
//i32 get_to_put(const vector<vi32>& g, const vector<bool>& covered, i32 th) {
//  i32 n = size(g);
//  rep(i,n) {
//    if (!covered[i]) {
//      vi32 d(n, -1);
//      d[i] = 0;
//      dfs(g, d, i);
//      i32 mx = -1;
//      i32 mxj = 0;
//      rep(j,n) {
//        if (!covered[j]) {
//          if (d[j] > mx) {
//            mx = d[j];
//            mxj = j;
//          }
//        }
//      }
//      vi32 d2(n, -1);
//      d2[mxj] = 0;
//      dfs(g, d2, mxj);
//      mx = -1;
//      i32 j2 = 0;
//      rep(j,n) {
//        if (!covered[j]) {
//          if (d[j] > mx) {
//            mx = d[j];
//            j2 = j;
//          }
//        }
//      }
//      if (mx <= th) {
//        return j2;
//      }
//      vi32 d3(n, -1);
//      d3[j2] = 0;
//      dfs(g, d3, j2);
//      rep(j,n) {
//        if (d2[j] == th && d2[j] + d3[j] == d2[j2]) {
//          return j;
//        }
//      }
//      return -1;
//    }
//  }
//  return -1;
//}

bool check(const vector<vi32>& g, i32 k, i32 th) {
  auto [ans, deepest, cover] = tree_dp(g, th, 0);
  if (deepest >= 0) ++ans;
  return ans <= k;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  i32 n,k;
  cin>>n>>k;
  vector<vi32> g(n);
  rep(i,n-1) {
    i32 u,v;
    cin>>u>>v;
    --u;--v;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  i32 lt = 0;
  i32 ge = n;
  while (ge - lt > 1) {
    i32 mid = (ge + lt) / 2;
    if (check(g, k, mid)) {
      ge = mid;
    } else {
      lt = mid;
    }
  }
  cout<<ge<<endl;
  return 0;
}
