#include <cstdio>
#include <algorithm>
#include <vector>
#include <limits>
#include <queue>
#include <cstddef>

template <class Weight>
struct Edge {
    const size_t src, dst;
    const Weight cost;
    Edge(size_t src, size_t dst, Weight cost):
        src(src), dst(dst), cost(cost)
    {}
};

template <class Weight>
bool operator <(const Edge<Weight> &e, const Edge<Weight> &f) {
    if (e.cost != f.cost) {
        return e.cost > f.cost;
    } else {
        return (e.src != f.src)? (e.src < f.src) : (e.dst < f.dst);
    }
}

template <class Weight>
using Edges=std::vector<Edge<Weight>>;
template <class Weight>
using Vertex=std::vector<Edge<Weight>>;

template <class Weight>
struct Graph: public std::vector<Vertex<Weight>> {
    static constexpr Weight INF=std::numeric_limits<Weight>::max()/4;
    Graph(): std::vector<Vertex<Weight>>() {}
    Graph(size_t v): std::vector<Vertex<Weight>>(v) {}
    void connect_u(size_t s, size_t d, Weight c=1) {
        (*this)[s].emplace_back(s, d, c);
        (*this)[d].emplace_back(d, s, c);
    }
    void connect_d(size_t s, size_t d, Weight c=1) {
        (*this)[s].emplace_back(s, d, c);
    }
};

template <class Weight>
ptrdiff_t vertices_within(const Graph<Weight> &g, size_t v, Weight c) {
    // the number of vertices of `g`; within `c` (inclusive) from vertex `v`
    ptrdiff_t res=1;
    std::vector<Weight> d(g.size(), Graph<Weight>::INF);
    d[v] = 0;
    std::queue<size_t> q;
    q.emplace(v);
    while (!q.empty()) {
        size_t u=q.front();
        q.pop();
        for (const Edge<Weight> &e: g[u])
            if (d[e.dst] >= Graph<Weight>::INF) {
                d[e.dst] = d[e.src] + e.cost;
                if (d[e.dst] <= c) {
                    ++res;
                    q.emplace(e.dst);
                }
            }
    }

    return res;
}

template <class Weight>
ptrdiff_t vertices_within(
    const Graph<Weight> &g, const Edge<Weight> &e, Weight c
) {
    // the number of vertices of `g`; within `c` (inclusive) from edge `e`
    ptrdiff_t res=2;
    std::vector<Weight> d(g.size(), Graph<Weight>::INF);
    d[e.src] = d[e.dst] = 0;
    std::queue<size_t> q;

    auto bfs=[&](std::queue<size_t> &q)->void {
        while (!q.empty()) {
            size_t u=q.front();
            q.pop();
            for (const Edge<Weight> &f: g[u])
                if (d[f.dst] >= Graph<Weight>::INF) {
                    d[f.dst] = d[f.src] + f.cost;
                    if (d[f.dst] <= c) {
                        ++res;
                        q.emplace(f.dst);
                    }
                }
        }
    };

    // one side of the edge
    for (const Edge<Weight> &f: g[e.src]) 
        if (f.dst != e.dst) {
            d[f.dst] = d[f.src] + f.cost;
            if (d[f.dst] <= c) {
                ++res;
                q.emplace(f.dst);
            }
        }

    bfs(q);

    // another side of the edge
    for (const Edge<Weight> &f: g[e.dst])
        if (f.dst != e.src) {
            d[f.dst] = d[f.src] + f.cost;
            if (d[f.dst] <= c) {
                ++res;
                q.emplace(f.dst);
            }
        }

    bfs(q);

    return res;
}

int main() {
    size_t N;
    int K;
    scanf("%zu %d", &N, &K);

    Graph<int> g(N);
    for (size_t i=1; i<N; ++i) {
        size_t A, B;
        scanf("%zu %zu", &A, &B);
        --A, --B;

        g.connect_u(A, B);
    }

    ptrdiff_t n=0;
    if (K & 1) {
        for (const Vertex<int> &v: g)
            for (const Edge<int> &e: v) {
                ptrdiff_t w=vertices_within(g, e, (K-1)/2);
                if (n < w)
                    n = w;
            }
    } else {
        for (size_t i=0; i<g.size(); ++i) {
            ptrdiff_t w=vertices_within(g, i, K/2);
            if (n < w)
                fprintf(stderr, "%zu\n", i),
                n = w;
        }
    }

    printf("%td\n", N-n);
    return 0;
}


Measured memory_bytes: 384