#define ENABLE_DEBUG 0
// Kana's kitchen {{{
#include<bits/stdc++.h>
#define ALL(v) std::begin(v),std::end(v)
#define LOOP(k) for(i64 ngtkana_is_a_genius=0; ngtkana_is_a_genius<(i64)k; ngtkana_is_a_genius++)

using i32 = std::int_least32_t;
using i64 = std::int_least64_t;
using u32 = std::uint_least32_t;
using u64 = std::uint_least64_t;
using usize = std::size_t;

template <class T> using vec = std::vector<T>;
template <class T> using numr = std::numeric_limits<T>;

#ifdef NGTKANA
#include<debug.hpp>
#else
#define DEBUG(...)(void)0
#endif
/*}}}*/
auto cmn=[](auto&x,auto y){if(x>y){x=y;return true;}return false;};
// diameter{{{
struct no_weight;

template <class Weight>
struct tree_diameter_adapter {
    using weight_type = Weight;
    using edge_type = std::pair<usize, weight_type>;
    static usize to(edge_type const& e) { return e.first; }
    static weight_type weight(edge_type const& e) { return e.second; }
};

template <>
struct tree_diameter_adapter<no_weight> {
    using weight_type = usize;
    using edge_type = usize;
    static usize to(edge_type e) { return e; }
    static weight_type weight(edge_type) { return 1; }
};

template <class> class tree_diameter;

template <class Weight=no_weight>
class tree_diameter {
    using adapter_type = tree_diameter_adapter<Weight>;
    using edge_type = typename adapter_type::edge_type;
    using weight_type = typename adapter_type::weight_type;
    using this_type = tree_diameter<Weight>;

    bool built = false;

    weight_type inf() { return std::numeric_limits<weight_type>::max(); }

public:
    vec<vec<edge_type>> g;
    vec<weight_type> dist;
    usize s, t;

    tree_diameter()=default;
    tree_diameter(tree_diameter const&)=default;
    tree_diameter(tree_diameter&&)=default;
    tree_diameter& operator=(tree_diameter const&)=default;
    tree_diameter& operator=(tree_diameter&&)=default;
    ~tree_diameter()=default;

    tree_diameter(usize n)
        : g(n), dist(n) {}

    // FIXME: 実装の注入で書き直せそうです。
    void insert_with_weight(usize u, usize v, Weight w) {
        assert(u < size());
        assert(v < size());
        g.at(u).emplace_back(v, w);
        g.at(v).emplace_back(u, w);
    }

    // FIXME: 実装の注入で書き直せそうです。
    void insert_without_weight(usize u, usize v) {
        assert(u < size());
        assert(v < size());
        g.at(u).push_back(v);
        g.at(v).push_back(u);
    }

    tree_diameter(vec<vec<edge_type>> const& g_)
        : g(g_), dist(g_.size())
    {}

    usize size() const { return g.size(); }

    this_type& build(usize s_ = 0) {
        assert(!built);
        built = true;
        s = s_;

        for (usize i=0; i<2; i++) {
            dist.assign(size(), inf());
            dist.at(s) = 0;
            vec<usize> que = {s};

            for (usize j=0; j<que.size(); j++) {
                usize x = que.at(j);
                for (auto&& e: g.at(x)) if (dist.at(adapter_type::to(e))==inf()) {
                    dist.at(adapter_type::to(e)) = dist.at(x) + adapter_type::weight(e);
                    que.push_back(adapter_type::to(e));
                }
            }
            t = std::max_element(dist.begin(), dist.end()) - dist.begin();
            std::swap(s, t);
        }
        return *this;
    }

    this_type& build(usize s_, vec<usize> const& dead) {
        assert(!built);
        assert(dead.size()==size());
        assert(!dead.at(s_));
        built = true;
        s = s_;

        for (usize i=0; i<2; i++) {
            dist.assign(size(), inf());
            dist.at(s) = 0;
            vec<usize> que = {s};

            for (usize j=0; j<que.size(); j++) {
                usize x = que.at(j);
                for (auto&& e: g.at(x)) if (dist.at(adapter_type::to(e))==inf() && !dead.at(adapter_type::to(e))) {
                    dist.at(adapter_type::to(e)) = dist.at(x) + adapter_type::weight(e);
                    que.push_back(adapter_type::to(e));
                }
            }
            t = s;
            for (usize j=0; j<size(); j++) if (dist.at(j)!=inf()) {
                if (dist.at(t) < dist.at(j)) t = j;
            }
            std::swap(s, t);
        }
        return *this;
    }

    weight_type len() {
        if (!built) build();
        assert(dist.at(t)==0 && dist.at(s)!=inf());
        return dist.at(s);
    }

    std::pair<usize, usize> extremals()  {
        if (!built) build();
        assert(dist.at(t)==0 && dist.at(s)!=inf());
        return std::make_pair(s, t);
    }

    vec<usize> verticies() {
        if (!built) build();
         vec<usize> ans = {s};
         while (ans.back()!=t) {
             auto&& v = g.at(ans.back());

             usize y =
                 adapter_type::to(*std::find_if(
                     v.begin(),
                     v.end(),
                     [this, dx=dist.at(ans.back())](usize y_){
                         return dist.at(y_) == dx - 1;
                     }
                 ));

             ans.push_back(y);
         }
         assert(ans.size()==len()+1);
         assert([&]{
             for (usize i=0; i<=len(); i++) {
                 assert(i==len()-dist.at(ans.at(i)));
             }
             return true;
         }());
         return ans;
    }
};
/*}}}*/
template <
usize N, class T, class... Args,
      std::enable_if_t<N==0, int> = 0
      >
      auto mkvec(Args... args) {
          return T(args...);
      }

template <
usize N, class T, class... Args,
      std::enable_if_t<N!=0, int> = 0
      >
      auto mkvec(usize sz, Args... args) {
          using value_type = std::decay_t<decltype(mkvec<N-1, T>(args...))>;
          return vec<value_type>(sz, value_type(args...));
      }
int main(){
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);
    std::cout << std::setprecision(15) << std::fixed;

    usize n, k;
    std::cin >> n >> k;
    vec<vec<usize>> g(n);
    for (usize i=0; i<n-1; i++) {
        usize u, v;
        std::cin >> u >> v;
        u--, v--;
        g.at(u).push_back(v);
        g.at(v).push_back(u);
    }
    DEBUG(matrix_style(g));

    if (tree_diameter<>(g).len() <= k) {
        std::cout << 0 << '\n';
        return 0;
    }

    usize ans = n;
    for (usize s0=0; s0<n; s0++) {
        for (usize s1: (k%2==0 ? vec<usize>{s0} : g.at(s0))) {
            vec<usize> dist(n, -1), que = {s0, s1};
            dist.at(s0) = k/2;
            dist.at(s1) = k/2;
            for (usize i=0; i<que.size(); i++) {
                usize x = que.at(i);
                if (dist.at(x)==0) continue;
                for (usize y: g.at(x)) if (dist.at(y)==-1) {
                    dist.at(y) = dist.at(x) - 1;
                    que.push_back(y);
                }
            }

            vec<usize> dead(n);
            for (usize i=0; i<n; i++) {
                dead.at(i) = dist.at(i) == -1;
            }
            DEBUG(s0, s1, dist);
            DEBUG();

            if (tree_diameter<>(g).build(s0, dead).len() < k) continue;

            cmn(ans, std::count_if(ALL(dist), [](usize x){ return x==-1; }));
        }
    }
    std::cout << ans << '\n';
}


Measured memory_bytes: 648