	#include <bits/stdc++.h>
	using namespace std;
	 
	void fast() {
	    ios_base::sync_with_stdio(false);
	    cin.tie(NULL);
	}
	 
	vector<string> vec_splitter(string s) {
		s += ',';
		vector<string> res;
		while(!s.empty()) {
			res.push_back(s.substr(0, s.find(',')));
			s = s.substr(s.find(',') + 1);
		}
		return res;
	}
	 
	void debug_out(
	vector<string> __attribute__ ((unused)) args,
	__attribute__ ((unused)) int idx, 
	__attribute__ ((unused)) int LINE_NUM) { cerr << endl; } 
	template <typename Head, typename... Tail>
	void debug_out(vector<string> args, int idx, int LINE_NUM, Head H, Tail... T) {
		if(idx > 0) cerr << ", "; else cerr << "Line(" << LINE_NUM << ") ";
		stringstream ss; ss << H;
		cerr << args[idx] << " = " << ss.str();
		debug_out(args, idx + 1, LINE_NUM, T...);
	}
	 
	#ifdef LOCAL
	#define debug(...) debug_out(vec_splitter(#__VA_ARGS__), 0, __LINE__, __VA_ARGS__)
	#else
	#define debug(...) 42
	#endif
	 
	double get_time() {
		return 1.0 * clock() / CLOCKS_PER_SEC;
	}

	const int MAX = 2E5 + 100, INF = 1E9 + 5;

	int n, k;
	vector<vector<int>> adj(MAX), at_h(MAX);
	int h[MAX], dp1[MAX], dp2[MAX];

	int DFS(int u, int p, int d) {
		int ret = 0;
		for(int v : adj[u]) {
			if(v == p)
				continue;
			ret += DFS(v, u, d);
			if(dp1[v] > -1 && dp1[v] < d) {
				if(dp1[u] == -1 || dp1[u] > dp1[v] + 1)
					dp1[u] = dp1[v] + 1;
			}
			if(dp2[v] > -1) {
				dp2[u] = max(dp2[u], dp2[v] + 1);
			}
			// h[u] = max(h[u], h[v] + 1);
		}

		if(dp2[u] > -1 && dp1[u] > -1 && d - dp1[u] >= dp2[u]) {
			dp2[u] = -1;
		}

		if(dp2[u] == d || (u == 0 && (dp1[u] == -1 || dp2[u] > -1))) {
			ret++;
			dp2[u] = -1;
			dp1[u] = 0;
		}

		if(dp1[u] == -1 && dp2[u] == -1) {
			dp2[u] = 0;
		}

		// if(dp2[u] == d || (u == 0 && (dp2[u] > -1 || dp1[u] == -1))) {
		// 	ret++;
		// 	dp2[u] = -1;
		// 	dp1[u] = 0;
		// }

		return ret;
	}

	int min_need(int d) {
		// int ret = 0;
		// int cur = -(d + 1);
		// while(h[0] >= cur + d + 1) {
		// 	cur += 2*d + 1;
		// 	ret += at_h[cur].size();
		// }
		// if(cur != h[0])
		// 	ret += 1;
		// return ret;
		fill(begin(dp1), end(dp1), -1);
		fill(begin(dp2), end(dp2), -1);
		return max(1, DFS(0, -1, d));
	}	

	int main() {
		cin >> n >> k;
		for(int i = 0; i < n - 1; i++) {
			int u, v;
			cin >> u >> v;
			--u, --v;
			adj[u].push_back(v);
			adj[v].push_back(u);
		}
		// DFS(0, -1);

		// for(int i = 0; i < n; i++)
		// 	at_h[h[i]].push_back(i);
		int lo = 1, hi = n - 1;
		while(lo < hi) {
			int mid = (lo + hi) / 2;
			if(min_need(mid) > k)
				lo = mid + 1;
			else
				hi = mid;
		}

		cout << lo << '\n';
	}
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstring>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <optional>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#ifdef ENVIRONMENT_LINKED_BOOST
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#endif

using namespace std;
using uint  = unsigned int;
using ll    = long long;
using ull   = unsigned long long;
using lpair = std::pair<ll, ll>;
#define REP(i, a, b)    for (ll i = a; i < b; ++i)
#define REPREV(i, a, b) for (ll i = a; i > b; --i)

const int _ = []() {
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);
    std::cout << std::fixed << std::setprecision(10);
    return 0;
}();

template <typename value_t>
void resize(value_t& v, const value_t& val) { v = val; }
template <typename vec_t, typename value_t, typename... arg_t>
void resize(std::vector<vec_t>& v, const value_t& val, int size, arg_t... arg) {
    v.resize(size);
    for (auto& c : v) resize(c, val, arg...);
}
template <typename A, typename B>
void chmin(A& a, const B& b) { a = min(a, static_cast<A>(b)); };
template <typename A, typename B>
void chmax(A& a, const B& b) { a = max(a, static_cast<A>(b)); };

vector<vector<int>> link;

/*
(x,y)

x
まだ被覆されてない最遠の頂点とparの距離
存在しなければ0

y
parから距離y以下の頂点は無条件で被覆される
存在しなければ負の値
*/
pair<int, int> dfs(int ind, int par, int& ans, int range) {
    int x = 0;
    int y = -1;
    for (int c : link[ind]) {
        if (c == par) continue;
        auto ret = dfs(c, ind, ans, range);
        chmax(x, ret.first);
        chmax(y, ret.second);
    }
    if (x == range) {
        ++ans;
        return {0, range - 1};
    }
    if (x <= y) {
        return {0, y - 1};
    }
    return {x + 1, y - 1};
}

int score(int range) {
    int ans  = 0;
    auto ret = dfs(0, -1, ans, range);
    if (ret.first) ++ans;
    return ans;
}

int main() {
    int N, K;
    cin >> N >> K;
    link.resize(N);
    REP(i, 0, N - 1) {
        int a, b;
        cin >> a >> b;
        --a;
        --b;
        link[a].push_back(b);
        link[b].push_back(a);
    }
    int l = -1;
    int r = N;
    while (r - l > 1) {
        int mid                   = l + (r - l) / 2;
        (score(mid) <= K ? r : l) = mid;
    }
    cout << r << endl;

    return 0;
}