#line 1 "main.cpp"
#include <iostream>
#include <vector>

using namespace std;

void solve() {
    int n, k;
    cin >> n >> k;

    vector<vector<int>> graph(n);
    for (int i = n - 1; i--;) {
        int u, v;
        cin >> u >> v;
        --u, --v;

        graph[u].push_back(v);
        graph[v].push_back(u);
    }

    // 伝達時刻で二分探索
    int ok = n, ng = 0;
    while (ok - ng > 1) {
        int mid = (ok + ng) / 2;

        int cnt = 0;  // 連絡先の個数

        // 部分木が全て被覆されている: -(連絡先の最小距離+1)
        // そうでない                : 被覆されていない子の最大距離
        auto dfs = [&](auto&& f, int v, int p) -> int {
            int uncovered_max = -1, center_min = n;

            for (auto u : graph[v]) {
                if (u == p) continue;

                auto d = f(f, u, v);
                if (d >= 0) {
                    uncovered_max = max(uncovered_max, d + 1);
                } else {
                    center_min = min(center_min, -d);
                }
            }

            // 葉の場合
            if (graph[v].size() <= 1) uncovered_max = 0;

            // 被覆されていない頂点を全て被覆できる場合
            if (uncovered_max + center_min <= mid) uncovered_max = -1;

            // 連絡先が既に無効の場合
            if (center_min > mid) uncovered_max = max(uncovered_max, 0);

            if (uncovered_max == mid) {
                ++cnt;  // vを連絡先にする
                uncovered_max = -1, center_min = 0;
            }

            return uncovered_max != -1 ? uncovered_max : -(center_min + 1);
        };

        // 根が被覆されていない場合は根を連絡先にする
        if (dfs(dfs, 0, -1) >= 0) ++cnt;

        if (cnt <= k) {
            ok = mid;
        } else {
            ng = mid;
        }
    }

    cout << ok << "\n";
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    solve();

    return 0;
}

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
//#define puts sdf
using std::vector;
//using std::cout;
//using std::endl;
using std::sort;
using std::swap;
using std::min;
using std::max;

int read(){//int 无负数 
	int h=0;char c=getchar();
	while(c<'0'||c>'9')c=getchar();
	while(c>='0'&&c<='9')h=(h<<1)+(h<<3)+c-'0',c=getchar();
	return h;
}

const int MAXN=200100;
int K,n;
struct Edge{
    int to;
    int nxt;
}edge[MAXN<<1];
int frm[MAXN];
int cnt_e;

void insert_e(int u,int v){
    cnt_e++;
    edge[cnt_e].to=v;
    edge[cnt_e].nxt=frm[u];
    frm[u]=cnt_e;
}
int Fa[MAXN];

int Rt,mns,S;
int siz[MAXN];
bool vis[MAXN];
void get_rt(int x,int ff){
    siz[x]=1;int mxs=0;
    for(int i=frm[x];i;i=edge[i].nxt){
        int v=edge[i].to;if(v==ff||vis[v])continue;
        get_rt(v,x);
        siz[x]+=siz[v];
        mxs=max(mxs,siz[v]);
    } 
    mxs=max(mxs,S-siz[x]);
    if(mxs<mns)Rt=x,mns=mxs;
} 

int Dt[MAXN];//点分树上的深度 
int dis[MAXN][21]; //x到点分树上深度为D的那个祖先的距离 
int mndis[MAXN];//距离他最近的点 

void get_dis1(int U,int x,int ff,int dep,int D){
    dis[x][D]=dep;
    for(int i=frm[x];i;i=edge[i].nxt){
        int v=edge[i].to;if(v==ff||vis[v])continue;
        get_dis1(U,v,x,dep+1,D);
    }
}

void divide(int x,int D){//D是点分树上的深度 
    vis[x]=true;
    Dt[x]=D;
    get_dis1(x,x,x,0,D);
    for(int i=frm[x];i;i=edge[i].nxt){
        int v=edge[i].to;if(vis[v])continue;

        S=siz[v],mns=siz[v],get_rt(v,v);
        Fa[Rt]=x;divide(Rt,D+1);
    }
}

void Modify(int x){
    int rt=x;
    for(;rt;rt=Fa[rt]){
        mndis[rt]=min(mndis[rt],dis[x][Dt[rt]]);
//        cout<<"MODIFY"<<x<<" "<<rt<<" "<<mndis[rt]<<endl;
    }
}

bool Query(int x,int mid){
    int rt=x;
    for(;rt;rt=Fa[rt]){
//    	cout<<"QUERY "<<x<<' '<<rt<<" "<<mndis[rt]<<' '<<dis[x][Dt[rt]]<<endl;
        if(mndis[rt]+dis[x][Dt[rt]]<=mid)return true;
    }
    return false;
}

int fa[MAXN][19];
int dep[MAXN];
int qwq[MAXN];//按深度排序 
bool cmp(int x,int y){
	return dep[x]>dep[y];
}
void pre_dfs(int x,int ff){
	fa[x][0]=ff;dep[x]=dep[ff]+1;
	for(int i=1;i<=18;i++)fa[x][i]=fa[fa[x][i-1]][i-1];
	for(int i=frm[x];i;i=edge[i].nxt){
		int v=edge[i].to;if(v==ff)continue;
		pre_dfs(v,x);
	}
}

int get_fa(int x,int k){
	int nw=x;
	for(int i=0;i<=18;i++){
		if(k&(1<<i))nw=fa[nw][i];
	}
	return nw;
}

bool ch_ck(int mid){
//	cout<<"MID"<<':'<<mid<<endl;
	memset(mndis,0x3f,sizeof(mndis));
//	for(int i=1;i<=n;i++)mndis[i]=-0x3f3f3f3f;
	int cnt=0;
	for(int i=1;i<=n;i++){
		int x=qwq[i];
		if(Query(x,mid))continue;
		int fk=get_fa(x,mid);
		cnt++;Modify(fk);
//		cout<<"WORK"<<x<<" "<<fk<<endl;
		if(cnt>K)return false;
	}
	return true;
}

int get_ans(){
	int l=0,r=n;
	while(l+1<r){
		int mid=(l+r)>>1;
		if(ch_ck(mid)){
			r=mid;
		}
		else l=mid+1;
	}
	if(l==r)return r;
	if(ch_ck(l))return l;
	return r;
}

int main(){
	n=read(),K=read();
    for(int i=1;i<=n-1;i++){
        int u=read(),v=read();
        insert_e(u,v),insert_e(v,u);
    }
    S=n,mns=n,get_rt(1,1);
    divide(Rt,0);
    pre_dfs(1,1);
    for(int i=1;i<=n;i++)qwq[i]=i;sort(qwq+1,qwq+n+1,cmp);
//    for(int i=1;i<=n;i++)cout<<qwq[i]<<" ";puts("");
//    for(int i=1;i<=n;i++){
//    	for(int j=0;j<=18;j++)cout<<fa[i][j]<<" ";puts("");
//	}
    printf("%d\n",get_ans());
	return 0;
}