#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

#define mp make_pair
#define fr first
#define sc second

template<class T> T T_INF(){ return 1000000000000000000; }
template<> int T_INF<int>(){ return 1000000000; }

struct Tree{
	int n;
	vector<vector<pair<int,int>>> G;
	Tree(int n_){ init(n_); }
	Tree(){}
	void init(int n_){
		n=n_;
		G=vector<vector<pair<int,int>>>(n);
	}
	void add_edge(int u,int v,int i=0){
		G[u].push_back(mp(v,i));
	}
};

struct rooted_tree{
	Tree* Tr;
	int root;
	vector<pair<int,int>> par;
	vector<int> dep;
	vector<int> vs; //pre-orderにvertexを並べたもの
	vector<int> pre_order; //頂点iがpre-orderで何番目か
	rooted_tree(Tree* Tr_,int r=0):Tr(Tr_),root(r),par(Tr->n),dep(Tr->n),vs(Tr->n),pre_order(Tr->n,-1){ dfs(mp(r,-1),-1,0,0); }
	rooted_tree(){}
	int dfs(pair<int,int> e, int p,int d,int k){
		if(pre_order[e.fr]!=-1)return k;
		par[e.fr]=mp(p,e.sc);
		dep[e.fr]=d;
		vs[k]=e.fr;
		pre_order[e.fr]=k++;
		for(auto ed: Tr->G[e.fr])k=dfs(ed,e.fr,d+1,k);
		return k;
	}
};

template<class T> vector<T> dist_on_tree(const Tree &Tr, int s){
	vector<T> dist(Tr.n,-1);
	queue<int> que;
	dist[s]=0;
	que.push(s);
	while(!que.empty()){
		int v=que.front(); que.pop();
		for(auto ed: Tr.G[v]){
			if(dist[ed.fr]!=-1)continue;
			dist[ed.fr]=dist[v]+1;
			que.push(ed.fr);
		}
	}
	return dist;
}


int main(){
	int n,k;
	scanf("%d%d",&n,&k);
	Tree Tr(n);
	for(int i=0;i<n-1;i++){
		int u,v;
		scanf("%d%d",&u,&v); u--; v--;
		Tr.add_edge(u,v);
		Tr.add_edge(v,u);
	}
	rooted_tree rt(&Tr);
	
	vector<pair<int,int>> vs;
	for(int i=0;i<Tr.n;i++)vs.push_back(mp(rt.dep[i],i));
	sort(vs.begin(),vs.end(),greater<pair<int,int>>());
	
	int l=0,r=n-1;
	while(l<r){
		int m=(l+r)/2;
		bool ok=false;
		if(m<=800){
			static int d[200010];
			fill(d,d+n,-1);
			int cnt=0;
			for(auto p: vs){
				int v=p.sc;
				bool used=false;
				pair<int,int> loc(v,0);
				do{
					if(d[loc.fr]>=loc.sc){
						used=true;
						break;
					}
					loc.fr=rt.par[loc.fr].fr;
					loc.sc++;
				}while(loc.fr!=-1&&loc.sc<=m);
				if(!used){
					for(int i=0;i<m&&v!=-1;i++)v=rt.par[v].fr;
					if(v==-1)v=0;
					cnt++; if(cnt>k)break;
					loc=mp(v,0);
					do{
						d[loc.fr]=m-loc.sc;
						loc.fr=rt.par[loc.fr].fr;
						loc.sc++;
					}while(loc.fr!=-1&&loc.sc<=m);
				}
			}
			ok=cnt<=k;
		}
		else {
			static bool used[200010];
			fill(used,used+n,false);
			int cnt=0;
			for(auto p: vs){
				int v=p.sc;
				if(!used[v]){
					for(int i=0;i<m&&v!=-1;i++)v=rt.par[v].fr;
					if(v==-1)v=0;
					cnt++; if(cnt>k)break;
					auto d=dist_on_tree<int>(Tr,v);
					for(int i=0;i<n;i++)if(d[i]<=m)used[i]=true;
				}
			}
			ok=cnt<=k;
		}
		if(ok)r=m;
		else l=m+1;
	}
	cout<<l<<endl;
}


//================code===================//

//#define TLE

#ifdef TLE
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#endif

#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>
#include <random>
#include <ctime>

#define ci(t) cin>>t
#define co(t) cout<<t
#define LL unsigned long long
#define ld long double
#define fa(i,a,b) for(LL i=(a);i<(LL)(b);++i)
#define fd(i,a,b) for(LL i=(a);i>(LL)(b);--i)
#define setp pair<pair<int,int>,int>
#define setl pair<LL,LL>
#define micro 0.000001

using namespace std;

//LL gcd(LL a, LL b) { return a % b ? gcd(b, a % b) : b; }
//LL lcm(LL a, LL b) { return (a * b) / gcd(a, b); }
#ifdef OHSOLUTION
#define ce(t) cerr<<t
#define AT cerr << "\n=================ANS=================\n"
#define AE cerr << "\n=====================================\n"
#define DB(a) cerr << __LINE__ << ": " << #a << " = " << (a) << endl;
#else
#define AT
#define AE
#define ce(t)
#define __popcnt64 __builtin_popcountll 
#define __popcnt __builtin_popcount  
#endif

pair <int, int> vu[9] = { {0,1},{1,0},{0,-1} ,{-1,0},{0,0},{1,0}, {-1,1} , {1,-1},{-1,-1} }; //RDLU EWSN

template<typename T, typename U> void ckmax(T& a, U b) { a = a < b ? b : a; }
template<typename T, typename U> void ckmin(T& a, U b) { a = a > b ? b : a; }
struct gcmp { bool operator()(LL a, LL b) { return a < b; } bool operator()(setl a, setl b) { return a.second < b.second; } };
struct lcmp { bool operator()(LL a, LL b) { return a > b; } bool operator()(setl a, setl b) { return a.second > b.second; } };

const int max_v = 2e5 + 7;
const int INF = 1e9 + 7;
const LL LNF = (LL)5e18 + 7ll;
const LL mod = 998244353;

vector <int> adj[max_v];
struct node
{
    int cn,sl,mr;        
};

node dfs(int idx,int dist,int par = -1)
{
    if (~par && adj[idx].size() == 1) return { 0,INF,0 };
    node ret = { 0,INF,-INF};

    for (auto& x : adj[idx]) if (x != par)
    {
         node tmp = dfs(x, dist, idx);
         ret.cn += tmp.cn;
         ckmin(ret.sl, tmp.sl+1);
         ckmax(ret.mr, tmp.mr+1);
    }

    //if (ret.mr == -INF) ret.mr = 0;

    if (ret.sl == INF)
    {
        if (ret.mr >= dist)
        {
            ret.sl = 0;
            ret.mr = -INF;
            ++ret.cn;
        }
    }
    else
    {
        if (ret.sl == 2 * dist + 1 || ret.mr>=dist)
        {
            ++ret.cn;
            ret.sl = 0;
            ret.mr = -INF;
        }
        else if (ret.sl > dist)
        {
            ckmax(ret.mr, ret.sl - dist - 1);
        }
        else if(ret.sl+ret.mr <=dist)
        {
            ret.mr = -INF;
        }
    }


    if (par == -1 && ret.mr!=-INF)
    {
        ++ret.cn;
    }
    
    return ret;
}

int main()
{
#ifdef OHSOLUTION
    freopen("input.txt", "r", stdin);
#endif	
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);        
    int n, k; ci(n >> k);

    vector <setl> test;

    fa(i, 0, n - 1)
    {
        int x, y; ci(x >> y); --x, --y;
        adj[x].push_back(y); adj[y].push_back(x);
        if (x > y) swap(x, y);
        test.push_back({ x,y });
    }

    if (n == k)
    {
        co(0);
        return 0;
    }

    int l = 1;
    int r = n;

    while (l != r)
    {
        int mid = l + r >> 1;    
        if (dfs(0,mid).cn <= k) r = mid;
        else l = mid + 1;
    }
    co(l << "\n");

    return 0;
}