#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <iostream>
#include <cassert>
#include <cmath>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <cstdlib>

using namespace std;

#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define li long long
#define pii pair<int, int>
#define vi vector<int>
#define li long long

#define forn(i, n) for (int i = 0; i < (int)n; i++)
#define fore(i, b, e) for (int i = (int)b; i <= (int)e; i++)

const int MAXP = 18;
const int MAXN = 2e5 + 5;

vi edges[MAXN];
int jmp[MAXP + 1][MAXN];
int depth[MAXN];
vector<pii> order;
int n, k, root;
bool covered[MAXN];
int t;

int lcm(int u, int v) {
	if (depth[u] > depth[v]) {
		swap(u, v);
	}
	int delta = depth[v] - depth[u];
	fore(j, 0, MAXP) {
		if (delta & (1  << j)) {
			v = jmp[j][v];
		}
	}
	if (u == v) {
		return v;
	}

	for (int level = MAXP; level >= 0; --level) {
		int nextu = jmp[level][u];
		int nextv = jmp[level][v];
		if (nextu != nextv) {
			u = nextu;
			v = nextv;
		}
	}
	assert(jmp[0][v] == jmp[0][u]);
	return jmp[0][v];
}

int dist(int u, int v) {
	int l = lcm(u, v);
	return depth[u] - 2 * depth[l] + depth[v];
}

void paint(int v, int anc, int d) {
	covered[v] = true;
	if (d == t) {
		return;
	}
	for (int u : edges[v]) {
		if (u != anc) {
			paint(u, v, d + 1);
		}
	}
}

bool check() {
	memset(covered, false, sizeof(covered));
	vi chosen;
	for (auto p : order) {
		int v = p.se;
		/*bool covered = false;
		for (int u : chosen) {
			if (dist(v, u) <= t) {
				covered = true;
				break;
			}
		}*/
		if (!covered[v]) {
			if ((int)chosen.size() == k) {
				return false;
			}
			int anc = v;
			forn(j, MAXP + 1) {
				if (t & (1 << j)) {
					anc = jmp[j][anc];
				}
			}
			if (anc <= 0) {
				anc = root;
			}
			chosen.pb(anc);
			paint(anc, -1, 0);
		}
	}
	return true;
}

void dfs(int v, int anc) {
	depth[v] = anc == -1 ? 0 : depth[anc] + 1;
	jmp[0][v] = anc;
	fore(level, 1, MAXP) {
		jmp[level][v] = jmp[level - 1][jmp[level - 1][v]];
	}
	for (int u : edges[v]) {
		if (u != anc) {
			dfs(u, v);
		}
	}
}

int main() {
	scanf("%d%d", &n, &k);
	forn(i, n - 1) {
		int u, v;
		scanf("%d%d", &u, &v);
		edges[u].pb(v);
		edges[v].pb(u);
	}
	root = rand() % n + 1;
	dfs(root, -1);
	order.resize(n);
	forn(j, n) {
		order[j] = {depth[j + 1], j + 1};
	}
	sort(order.begin(), order.end());
	reverse(order.begin(), order.end());

	int start = 0;
	int finish = order[0].fi;
	while (start < finish) {
		int middle = (start + finish) / 2;
		t = middle;
		if (check()) {
			finish = middle;
		} else {
			start = middle + 1;
		}
	}
	printf("%d", start);
}
#include "bits/stdc++.h"

#define MOD 1000000007
#define rep(i, n) for(ll i=0; i < (n); i++)
#define rrep(i, n) for(ll i=(n)-1; i >=0; i--)
#define ALL(v) v.begin(),v.end()
#define rALL(v) v.rbegin(),v.rend()
#define FOR(i, j, k) for(ll i=j;i<k;i++)
#define debug_print(var) cerr << #var << "=" << var <<endl;
#define DUMP(i, v)for(ll i=0;i<v.size();i++)cerr<<v[i]<<" "
#define fi first
#define se second

using namespace std;
typedef long long int ll;
typedef vector<ll> llvec;
typedef vector<double> dvec;
typedef pair<ll, ll> P;
typedef long double ld;
struct edge{ll x, c;};

ll mod(ll a, ll mod){
  ll res = a%mod;
  if(res<0)res=res + mod;
  return res;
}

ll modpow(ll a, ll n, ll mod){
  ll res=1;
  while(n>0){
    if(n&1) res=res*a%mod;
    a=a*a%mod;
    n>>=1;
  }
  return res;
}

ll modinv(ll a, ll mod){
  ll b=mod, u=1, v=0;
  while(b){
    ll t=a/b;
    a-=t*b; swap(a, b);
    u-=t*v; swap(u, v);
  }
  u%=mod;
  if(u<0)u+=mod;
  return u;
}

ll gcd(ll a, ll b){
  ll r = a%b;
  if(r==0) return b;
  else return gcd(b, a%b);
}

bool is_prime(ll n){
  ll i = 2;
  if(n==1)return false;
  if(n==2)return true;
  bool res = true;
  while(i*i <n){
    if(n%i==0){
      res = false;
    }
    i = i+1;
  }

  //if(i==1)res = false;
  if(n%i==0)res=false;
  return res;
}

struct UnionFind{
  ll N;
  llvec p;
  llvec cnt;
  UnionFind(ll n){
    N = n;
    p=llvec(N);
    cnt=llvec(N, 0);
    rep(i, N){
      p[i] = i;
      cnt[i] = 1;
    }
  }

  void con(ll a, ll b){
    P at = root(a);
    P bt = root(b);
    if(at.second!=bt.second){
      if(at.first>bt.first){
        swap(at, bt);
        swap(a, b);
      }
      p[at.second] = bt.second;
      cnt[bt.second]+=cnt[at.second];
      p[a]=bt.second;
    }
  }

  P root(ll a){
    ll atmp = a;
    ll c=0;
    while(atmp!=p[atmp]){
      atmp = p[atmp];
      c++;
    }
    p[a] = atmp;
    return {c, atmp};
  }

  bool is_con(ll a, ll b){
    P at=root(a);
    P bt=root(b);
    return at.second == bt.second;
  }
  
};


/**************************************
** A main function starts from here  **
***************************************/
int main(){
  ll N;
  cin >> N;
  llvec x(N), y(N);
  rep(i, N)cin >> x[i]>>y[i];

  ld ok = 1e-10;
  ld ng = 300;
  while(abs(ok-ng)>1e-9){
    ld r= (ok+ng)*0.5;
    UnionFind uf(N+2);
    for(ll i=0;i<N;i++){
      for(ll j=i+1;j<N;j++){
        if(sqrt(pow(x[i] - x[j], 2) + pow(y[i] - y[j], 2)) <2 * r){
          uf.con(i, j);
        }
      }
      
      if(abs(y[i]-100)<2*r)uf.con(N, i);
      if(abs(y[i]+100)<2*r)uf.con(N+1, i);
    }
    if(uf.is_con(N, N+1)){
      ng=r;
    }else{
      ok=r;
    }
    
  }

  cout << setprecision(15)<<ok;

  
  
  return 0;
}
