#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i = 0; i < (int)n; i++)
using ll = long long;
const int INF = 1e9;

int main(){
  int n, k;
  cin >> n >> k;
  vector<vector<int>> g(n);
  rep(i,n-1) {
    int u, v;
    cin >> u >> v;
    u--; v--;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  int l = -1, r = n, m;
  vector<int> dp(n), yet(n), done(n);
  auto dfs = [&](auto&& self, int u, int p) -> void {
    dp[u] = 0; yet[u] = 0; done[u] = INF;
    for(auto x : g[u]) {
      if(x == p) continue;
      self(self,x,u);
      dp[u] += dp[x];
      done[u] = min(done[u],done[x]+1);
    }
    if(done[u] <= m) yet[u] = -1;
    for(auto x : g[u]) {
      if(x == p) continue;
      if(yet[x]+1+done[u] > m) yet[u] = max(yet[u],yet[x]+1);
    }
    if(yet[u] == m) {
      dp[u]++; done[u] = 0; yet[u] = -1;
    }
  };
  while(r - l > 1) {
    m = (l + r) / 2;
    dfs(dfs,0,-1);
    if(yet[0] != -1) dp[0]++;
    (dp[0] <= k ? r : l) = m;
  }
  cout << r << endl;
  return 0;
}

#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;
}
