#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=1;i<=n;++i)
#define mp make_pair
#define pb push_back
#define size sze
#define inf 998244353
int n,k;
vector<int> g[210000];
int v[210000],dep[210000];
int q[210000];
int f[210000][20],size[210000],son[210000],minp[210000];
int father[210000],root;
struct node
{
    int adj,valid,next;
}edge[2*210000];
int gh[210000],top;
void addedge(int x, int y) {
	edge[++top].adj = y;
	edge[top].valid = 1;
	edge[top].next = gh[x];
	gh[x] = top;
}
void get_size(int x, int root=0) {
	size[x] = 1; son[x] = 0;
	int dd = 0;
	for (int p=gh[x]; p; p=edge[p].next)
		if (edge[p].adj != root && edge[p].valid) {
			get_size(edge[p].adj, x);
			size[x] += size[edge[p].adj];
			if (size[edge[p].adj] > dd) {
				dd = size[edge[p].adj];
				son[x] = edge[p].adj;
			}
		}
}
int getroot(int x) {
	get_size(x);
	int sz = size[x];
	while (size[son[x]] > sz/2)
		x = son[x];
	return x;
}
int dc(int x,int fa) {
	x = getroot(x);
    father[x]=fa;
	for (int p=gh[x]; p; p=edge[p].next)
		if (edge[p].valid) {
			edge[p].valid = 0;
			edge[p^1].valid = 0;
			dc(edge[p].adj,x);
		}
    return x;
}
bool cmp(int x,int y)
{
    return dep[x]>dep[y];
}
void dfs(int x,int pre,int depp)
{
    f[x][0]=pre;
    for(int i=1;i<=17;i++)f[x][i]=f[f[x][i-1]][i-1];
    dep[x]=depp;
    for(int p=gh[x];p;p=edge[p].next)
        if (edge[p].adj!=pre)dfs(edge[p].adj,x,depp+1);
}
int jump(int x,int d)
{
    int delta=dep[x]-d;
    for(int i=17;i>=0;i--)
        if (delta & (1<<i))x=f[x][i];
    return x;
}
int lca(int x,int y)
{
    if (dep[x]<dep[y])swap(x,y);
    x=jump(x,dep[y]);
   // cout<<x<<" "<<y<<endl;
    if (x==y)return x;
    for(int i=17;i>=0;i--)
        if (f[x][i]!=f[y][i])
        {
            x=f[x][i];
            y=f[y][i];
        }
    return f[x][0];
}
int dis(int x,int y)
{
    return dep[x]+dep[y]-2*dep[lca(x,y)];
}
void insert(int x)
{
    int now=x;
    while (now!=0)
    {
        if (minp[now]==n+1 || dis(now,x)<dis(now,minp[now]))minp[now]=x;
        now=father[now];
    }
}
int get(int x)
{
    int ret=2147483647;
    int now=x;
    while (now!=0)
    {
        if (minp[now]!=n+1)ret=min(ret,dis(x,minp[now]));
        now=father[now];
    }
    return ret;
}
bool check(int lim)
{   
    for(int i=1;i<=n;i++)minp[i]=n+1;
    int tot=0;
    for(int i=1;i<=n;i++)
    {
        //cout<<q[i]<<endl;
        if (get(q[i])>lim)
        {
            int fa=jump(q[i],max(dep[q[i]]-lim,0));
            insert(fa);
            tot++;
        }
        if (tot>k)return 0;
    }
    return 1;
}

int main()
{
    cin>>n>>k; top=1;
    for(int i=1;i<n;i++)
    {
        int x,y; 
        scanf("%d%d",&x,&y);
        addedge(x,y);
        addedge(y,x);
    }

    dfs(1,0,0);

    root=dc(1,0);
    //cout<<lca(3,2)<<" "<<lca(3,5)<<" "<<lca(4,5)<<endl;
    for(int i=1;i<=n;i++)q[i]=i;
    sort(q+1,q+n+1,cmp);
    long long l=1; long long r=n;

    
    //for(int i=1;i<=n;i++)cout<<father[i]<<" "; puts("");
    while (l<r)
    {
        int mid=(l+r)/2;
       // cout<<mid<<endl;
        if (check(mid))r=mid;
        else l=mid+1;
    }
    cout<<l<<endl;
    return 0;
}
//Code by oryon
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;

#define pb push_back
#define ppb pop_back
#define int long long
#define vi vector<int>
#define vvi vector<vector<int>>
#define mii map<int, int>
#define pii pair<int, int>
#define sz(a) (a).size()
#define FOR(i, a, b) for(int i=a; i<b; i++)
#define ROF(i, a, b) for(int i=b-1; i>=a; i--)
#define all(x) (x).begin(), (x).end()
#define setbits(x) __builtin_popcountll(x)
#define zrobits(x) __builtin_ctzll(x)
#define LB lower_bound
#define UB upper_bound
#define FS first
#define SD second
#define INF 1e18
#define MAX_NUM 300001
#define ps(x,y) fixed<<setprecision(y)<<x
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
typedef long long ll;
const int MOD = 1e9 + 7;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;
#define deb(x) cout << #x << " " << x << endl;

ll max(ll a, ll b)
{
    if (a > b) return a;
    return b;
}

ll min(ll a, ll b)
{
    if (a < b) return a;
    return b;
}

int n, m;
vvi graph(22); vi visited(22, 0), comp, color(22, 0);

void DFS(int s) {
    visited[s] = 1;
    comp.pb(s);
    for (auto &c : graph[s]) if (!visited[c]) DFS(c);
}

int calc(int pos) {
    if (pos == sz(comp)) return 1;
    int ans = 0;
    FOR(i, 1, 4) {
        int skip = 0;
        for (auto &c : graph[comp[pos]]) {
            if (color[c] == i) {
                skip = 1;
                break;
            }
        }
        if (skip) continue;
        color[comp[pos]] = i;
        ans += calc(pos + 1);
    }
    color[comp[pos]] = 0;
    return ans;
}

int32_t main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    cin >> n >> m;

    FOR(i, 0, m) {
        int u, v;
        cin >> u >> v;
        graph[u].pb(v);
        graph[v].pb(u);
    }

    int ans = 1;

    FOR(i, 1, n + 1) {
        if (!visited[i]) {
            DFS(i);
            ans *= calc(0);
            comp.clear();
        }
    }

    cout << ans;

    return 0;
}

