Problem:
Tree Separator
You are given a tree $T$ and an integer $K$. You can choose arbitrary distinct two vertices $u$ and $v$ on $T$. Let $P$ be the simple path between $u$ and $v$. Then, remove vertices in $P$, and edges such that one or both of its end vertices is in $P$ from $T$. Your task is to choose $u$ and $v$ to maximize the number of connected components with $K$ or more vertices of $T$ after that operation.
Input
The input consists of a single test case formatted as follows.
$N$ $K$
$u_1$ $v_1$
:
$u_{N-1}$ $v_{N-1}$
The first line consists of two integers $N, K$ ($2 \leq N \leq 100,000, 1 \leq K \leq N$). The following $N-1$ lines represent the information of edges. The ($i+1$)-th line consists of two integers $u_i, v_i$ ($1 \leq u_i, v_i \leq N$ and $u_i \ne v_i $ for each $i$). Each $\{u_i, v_i\}$ is an edge of $T$. It's guaranteed that these edges form a tree.
Output
Print the maximum number of connected components with $K$ or more vertices in one line.
Sample Input 1
2 1
1 2
Output for Sample Input 1
0
Sample Input 2
7 3
1 2
2 3
3 4
4 5
5 6
6 7
Output for Sample Input 2
1
Sample Input 3
12 2
1 2
2 3
3 4
4 5
3 6
6 7
7 8
8 9
6 10
10 11
11 12
Output for Sample Input 3
4
Sample Input 4
3 1
1 2
2 3
Output for Sample Input 4
1
Sample Input 5
3 2
1 2
2 3
Output for Sample Input 5
0
Sample Input 6
9 3
1 2
1 3
1 4
4 5
4 6
4 7
7 8
7 9
Output for Sample Input 6
2

Submitted solutions:

code_snippet: #include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
int n,K,h[1001010],m1,g[1001010],f[1001010];
int siz[1001010],ans;
struct edge{
	int next,to;
	edge(int next=0,int to=0):
	next(next),to(to){}
}q[2020200];
void Addedge(){
	int x,y; scanf("%d %d",&x,&y);
	q[++m1]=edge(h[x],y); h[x]=m1;
	q[++m1]=edge(h[y],x); h[y]=m1;
}
void Dfs1(int x,int fa){
	siz[x]=1;
	for (int i=h[x];i;i=q[i].next){
		int y=q[i].to;
		if (y==fa) continue;
		Dfs1(y,x); siz[x]+=siz[y];
	}
}
void Dfs2(int x,int fa){
	int Max1=-21001010,Max2=-21001010;
	for (int i=h[x];i;i=q[i].next){
		int y=q[i].to;
		if (y==fa) continue;
		Dfs2(y,x);
		if (siz[y]>=K) f[x]++;
		if (f[y]-g[y]>Max1) Max2=Max1,Max1=f[y]-g[y];
		else if (f[y]-g[y]>Max2) Max2=f[y]-g[y];
	}
	
	if (siz[x]>=K) g[x]=1;
	ans=max(ans,f[x]+Max1+(n-siz[x]>=K)); 
	ans=max(ans,f[x]+Max1+Max2+(n-siz[x]>=K));
	f[x]=max(f[x],f[x]+Max1);
}
int main(){
	scanf("%d %d",&n,&K);
	for (int i=1;i<n;i++) Addedge();
	Dfs1(1,0); Dfs2(1,0);
	cout<<ans<<endl;
}
accuracy: 1
time_ms: 10
memory_kb: 31012
final_rank: 14

code_snippet: #include<bits/stdc++.h>
using namespace std;

int N,K,an=0;
vector<int> C,DP;
vector<vector<int>> G;

void dfs(int n,int p){
    C[n]++;
    int cnt=0,tp=-1e6,sc=-1e6;
    for(int v:G[n])if(v!=p){
        dfs(v,n);
        if(C[v]>=K)cnt++;
        int r=DP[v]-(C[v]>=K);
        sc=max(sc,r);
        if(tp<sc)swap(tp,sc);
        C[n]+=C[v];        
    }
    DP[n]=cnt;
    an=max(an,DP[n]+tp+(N-C[n]>=K));
    an=max(an,DP[n]+tp+sc+(N-C[n]>=K));
    DP[n]=max(DP[n],DP[n]+tp);
}

int main() {
    cin>>N>>K;
    G.resize(N);
    for(int i=0;i<N-1;i++){
        int u,v;
        cin>>u>>v;
        u--;v--;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    C.assign(N,0);
    DP.resize(N);
    dfs(0,-1);
    cout<<an<<endl;
}
accuracy: 1
time_ms: 40
memory_kb: 14332
final_rank: 7

code_snippet: //tekitou hash demo tooru to uresii
#include<bits/stdc++.h>
using namespace std;

using ll=long long;
#define rep(i,n) for(int i=0;i<n;i++)
#define rep2(i,s,t) for(int i=s;i<t;i++)

using vi=vector<int>;
int N,K,an=0;
vector<int> C,DP;
vector<vector<int>> G;

void dfs(int n,int p){
    C[n]++;
    int cnt=0;
    vector<int> R;
    for(int v:G[n]){
        if(v!=p){
            dfs(v,n);
            if(C[v]>=K)cnt++;
            R.push_back(DP[v]);
            if(C[v]>=K)R.back()--;
            C[n]+=C[v];
        }
    }
    sort(R.begin(),R.end());
    reverse(R.begin(),R.end());
    DP[n]=cnt;
    if(R.size()>0){
        
        an=max(an,DP[n]+R[0]+(N-C[n]>=K));
    }
    if(R.size()>1){
        an=max(an,DP[n]+R[0]+R[1]+(N-C[n]>=K));
    }
    if(R.size()>0)DP[n]=max(DP[n],DP[n]+R[0]);
}

int main() {
    
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    cin>>N>>K;
    G.resize(N);
    rep(i,N-1){
        int u,v;
        cin>>u>>v;
        u--;v--;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    C.assign(N,0);
    DP.resize(N);
    dfs(0,-1);
    // rep(i,N)cout<<i<<" "<<DP[i]<<endl;
    cout<<an<<endl;
}
accuracy: 1
time_ms: 20
memory_kb: 16436
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n, k; cin >> n >> k;
    int ans = 0;
    vector<vector<int>> v(n);
    rep(i, n - 1) {
        int x, y;
        cin >> x >> y;
        x --; y --;
        v[x].pb(y);
        v[y].pb(x);
    }
    auto dfs = [&](auto dfs, int now, int p) -> pair<int, int> { // サイズ, path_ans
        vector<pair<int, int>> ret;
        int sum = 1, cs = 0;
        foa(e, v[now]) {
            if(e == p) continue;
            ret.push_back(dfs(dfs, e, now));
            sum += ret.back().first;
            cs ++;
        }
        sort(all(ret), [&](pair<int, int> a, pair<int, int> b) {
            if(a.second == b.second) return a.first < b.first;
            return a.second > b.second;
        });
        bool f = 0;
        int psize = n - sum;
        int cnt = (psize >= k);
        for(auto [x, y] : ret) {
            if(x >= k) cnt ++;
            else f = 1;
        }
        int num = cnt - (psize >= k);
        if(cs >= 1) {
            num = max(num, cnt - 1 + ret[0].second - (psize >= k));
            ans = max(ans, cnt - 1 + ret[0].second);
            if(f) ans = max(ans, cnt);
        }
        if(cs >= 2) {
            ans = max(ans, cnt - 2 + ret[0].second + ret[1].second);
        }
        return {sum, num};
    };
    dfs(dfs, 0, -1);
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 18768
final_rank: 5

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>
#include <utility>
#include <set>
#include <random>

int N, K;
std::vector<int> g[100010];
int size[100010];
int calc_size(int v, int p) {
    size[v] = 1;
    for (auto x : g[v]) if (x != p) size[v] += calc_size(x, v);
    return size[v];
}

int solve() {
    calc_size(0, -1);
    int ans{}; 
    std::vector<int> dp(N, -1);
    auto dfs{[&](auto dfs, int v, int p) -> void {
        for (auto x : g[v]) if (x != p) dfs(dfs, x, v);
        // vを端点としないが, LCAである
        std::vector<int> ep(3, -1);
        ep[0] = 0;
        for (auto x : g[v]) if (x != p) {
            std::vector<int> next(3, -1);
            for (int j{} ; j <= 2 ; j++) {
                next[j] = std::max(next[j], ep[j] + (size[x] >= K ? 1 : 0));
            }
            for (int j{} ; j <= 1 ; j++) {
                next[j + 1] = std::max(next[j + 1], ep[j] + dp[x]);
            }
            ep = std::move(next);
        }
        // std::cout << v + 1 << ' ' << ep[2] << std::endl;
        if (ep[2] != -1) {
            ans = std::max(ans, ep[2] + (N - size[v] >= K ? 1 : 0));
        }
        int cnt{};
        for (auto x : g[v]) if (x != p and size[x] >= K) cnt++;
        // dpの計算
        for (auto x : g[v]) if (x != p) {
            int val{cnt + dp[x] - (size[x] >= K ? 1 : 0)};
            dp[v] = std::max(dp[v], val);
        }
        // vを端点とする
        if (dp[v] != -1) {
            ans = std::max(ans, dp[v] + (N - size[v] >= K ? 1 : 0));
        }
        dp[v] = std::max(dp[v], cnt);
    }};
    dfs(dfs, 0, -1);
    // for (auto d : dp) std::cout << d << ' '; std::cout << std::endl;
    return ans;
}

// bool findpath(int v, int p, int goal, std::set<int>& path) {
//     if (v == goal) {
//         path.insert(v);
//         return true;
//     }
//     for (auto x : g[v]) if (x != p and findpath(x, v, goal, path)) {
//         path.insert(v);
//         return true;
//     }
//     return false;
// }
// 
// int brute() {
//     int ans{};
//     for (int u{} ; u < N ; u++) for (int v{u + 1} ; v < N ; v++) {
//         std::set<int> path;
//         assert(findpath(u, -1, v, path)); 
//         assert(path.size() >= 2u and path.find(u) != path.end() and path.find(v) != path.end());
//         int val{};
//         auto dfs{[&](auto dfs, int v, int p) -> void {
//             for (auto x : g[v]) if (x != p) dfs(dfs, x, v); 
//             if (path.find(v) != path.end()) {
//                 if (path.find(p) == path.end()) val += (N - size[v] >= K ? 1 : 0);
//                 for (auto x : g[v]) if (x != p and path.find(x) == path.end()) {
//                     val += size[x] >= K ? 1 : 0;
//                 }
//             }
//         }};
//         dfs(dfs, 0, -1);
//         ans = std::max(ans, val);
//     }
//     return ans;
// }

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    std::cin >> N >> K;
    for (int i{} ; i < N - 1 ; i++) {
        int u, v;
        std::cin >> u >> v;
        u--; v--;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    std::cout << solve() << '\n';
    // check
    // std::mt19937 mt{std::random_device{}()};
    // while (true) {
    //     N = mt() % 150 + 1; 
    //     for (int i{} ; i < N ; i++) {
    //         g[i].clear();
    //         size[i] = 0;
    //     }
    //     K = mt() % N + 1;
    //     std::vector<std::pair<int, int>> E(N - 1);
    //     for (int i{1} ; i < N ; i++) {
    //         int p{mt() % i};
    //         g[p].push_back(i);
    //         g[i].push_back(p);
    //         E[i - 1] = { i + 1, p + 1 };
    //     }
    //     int you{solve()};
    //     int ans{brute()};
    //     if (you != ans) {
    //         std::cout << N << ' ' << K << '\n';
    //         for (auto [u, v] : E) std::cout << u << ' ' << v << '\n';
    //         std::cout << you << ' ' << ans << " wrong!!\n";
    //         std::exit(0);
    //     }
    //     std::cout << "clear" << std::endl;
    // }
}
accuracy: 1
time_ms: 20
memory_kb: 18472
final_rank: 4

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

int main() {
    int N, K;
    cin >> N >> K;
    vector<vector<int>> Child(N);
    vector<int> Par(N,-1);
    vector<int> Count(N,0);
    rep(i,0,N-1) {
        int A, B;
        cin >> A >> B;
        A--, B--;
        Child[A].push_back(B);
        Child[B].push_back(A);
    }
    auto DFS1 = [&](auto self, int V, int P) -> void {
        for (auto& it : Child[V]) {
            if (P == it) {
                Par[V] = P;
                swap(it,Child[V].back());
                Child[V].pop_back();
                break;
            }
        }
        for (int NV : Child[V]) {
            self(self,NV,V);
            Count[V] += Count[NV];
        }
        Count[V]++;
    };
    DFS1(DFS1,0,-1);
    vector<int> DP(N,0);
    int ANS = 0;
    auto DFS2 = [&](auto self, int V) -> void {
        vector<int> DP2(3,-inf);
        DP2[0] = 0;
        for (int NV : Child[V]) {
            self(self,NV);
            int D = DP[NV], C = (Count[NV] >= K ? 1 : 0);
            vector<int> NewDP(3,-inf);
            if (DP2[0] >= 0) chmax(NewDP[0], DP2[0]+C), chmax(NewDP[1], DP2[0]+D);
            if (DP2[1] >= 0) chmax(NewDP[1], DP2[1]+C), chmax(NewDP[2], DP2[1]+D);
            if (DP2[2] >= 0) chmax(NewDP[2], DP2[2]+C);
            rep(i,0,3) DP2[i] = NewDP[i];
        }
        int B = (N - Count[V] >= K ? 1 : 0);
        if (DP2[0] >= 0) chmax(DP[V], DP2[0]);
        if (DP2[1] >= 0) chmax(DP[V], DP2[1]);
        if (DP2[1] >= 0) chmax(ANS, DP2[1] + B);
        if (DP2[2] >= 0) chmax(ANS, DP2[2] + B);
    };
    DFS2(DFS2,0);
    cout << ANS << endl;
}
accuracy: 1
time_ms: 40
memory_kb: 19964
final_rank: 13

code_snippet: #include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;

int main() {
	// step #1. input
	int N, K;
	cin >> N >> K;
	vector<vector<int> > G(N);
	for (int i = 0; i < N - 1; i++) {
		int a, b;
		cin >> a >> b;
		G[a - 1].push_back(b - 1);
		G[b - 1].push_back(a - 1);
	}
	
	// step #2. tree dp
	const int INF = 1012345678;
	vector<vector<int> > child(N);
	vector<int> subsize(N);
	vector<vector<int> > dp(N, vector<int>(2, -INF));
	function<void(int, int)> dfs = [&](int pos, int pre) {
		subsize[pos] = 1;
		for (int i : G[pos]) {
			if (i != pre) {
				dfs(i, pos);
				subsize[pos] += subsize[i];
				child[pos].push_back(i);
			}
		}
		int large_comps = 0;
		for (int i : child[pos]) {
			if (subsize[i] >= K) {
				large_comps += 1;
			}
		}
		dp[pos][0] = large_comps;
		for (int i : child[pos]) {
			dp[pos][1] = max(dp[pos][1], max(dp[i][0], dp[i][1]) + large_comps - (subsize[i] >= K ? 1 : 0));
		}
	};
	dfs(0, -1);
	
	// step #3. calculate answer
	int answer = 0;
	for (int i = 0; i < N; i++) {
		answer = max(answer, dp[i][1] + (N - subsize[i] >= K ? 1 : 0));
	}
	for (int i = 0; i < N; i++) {
		int large_comps = 0;
		for (int j : child[i]) {
			if (subsize[j] >= K) {
				large_comps += 1;
			}
		}
		vector<int> v;
		for (int j : child[i]) {
			v.push_back(max(dp[j][0], dp[j][1]) - (subsize[j] >= K ? 1 : 0));
		}
		sort(v.begin(), v.end(), greater<int>());
		if (int(v.size()) >= 2) {
			answer = max(answer, large_comps + v[0] + v[1] + (N - subsize[i] >= K ? 1 : 0));
		}
	}
	
	// step #4. output
	cout << answer << endl;
	
	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 28972
final_rank: 19

code_snippet: #include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;

int main() {
	// step #1. input
	int N, K;
	cin >> N >> K;
	vector<vector<int> > G(N);
	for (int i = 0; i < N - 1; i++) {
		int a, b;
		cin >> a >> b;
		G[a - 1].push_back(b - 1);
		G[b - 1].push_back(a - 1);
	}
	
	// step #2. tree dp
	const int INF = 1012345678;
	vector<vector<int> > child(N);
	vector<int> subsize(N);
	vector<vector<int> > dp(N, vector<int>(2, -INF));
	int answer = 0;
	function<void(int, int)> dfs = [&](int pos, int pre) {
		subsize[pos] = 1;
		for (int i : G[pos]) {
			if (i != pre) {
				dfs(i, pos);
				subsize[pos] += subsize[i];
				child[pos].push_back(i);
			}
		}
		int large_comps = 0;
		for (int i : child[pos]) {
			if (subsize[i] >= K) {
				large_comps += 1;
			}
		}
		vector<int> v;
		for (int i : child[pos]) {
			v.push_back(max(dp[i][0], dp[i][1]) - (subsize[i] >= K ? 1 : 0));
		}
		sort(v.begin(), v.end(), greater<int>());
		dp[pos][0] = large_comps;
		if (int(v.size()) >= 1) {
			dp[pos][1] = large_comps + v[0];
			answer = max(answer, dp[pos][1] + (N - subsize[pos] >= K ? 1 : 0));
		}
		if (int(v.size()) >= 2) {
			answer = max(answer, large_comps + v[0] + v[1] + (N - subsize[pos] >= K ? 1 : 0));
		}
	};
	dfs(0, -1);
	
	// step #3. output
	cout << answer << endl;
	
	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 30964
final_rank: 20

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// Inputs
int N, K;
int U[100009], V[100009];
vector<int> G[100009], H[100009];

// Dynamic Programming
int siz[100009];
int dp[100009];

void dfs1(int pos, int par) {
	siz[pos] = 1;
	for (int i = 0; i < (int)G[pos].size(); i++) {
		if (par == G[pos][i]) continue;
		dfs1(G[pos][i], pos);
		siz[pos] += siz[G[pos][i]];
		H[pos].push_back(G[pos][i]);
	}
}

void dfs2(int pos) {
	int cnt = 0;
	for (int i = 0; i < (int)H[pos].size(); i++) {
		dfs2(H[pos][i]);
		if (siz[H[pos][i]] >= K) cnt += 1;
	}
	dp[pos] = cnt;
	
	// DP Transition
	for (int i = 0; i < (int)H[pos].size(); i++) {
		int val1 = cnt; if (siz[H[pos][i]] >= K) val1 -= 1;
		int val2 = dp[H[pos][i]];
		dp[pos] = max(dp[pos], val1 + val2);
	}
}

int main() {
	// Input
	cin >> N >> K;
	for (int i = 1; i <= N - 1; i++) {
		cin >> U[i] >> V[i];
		G[U[i]].push_back(V[i]);
		G[V[i]].push_back(U[i]);
	}
	
	// Initial DP
	dfs1(1, -1);
	
	// Tree DP
	dfs2(1);
	
	// Get Answer
	int Answer = 0;
	for (int i = 1; i <= N; i++) {
		vector<int> vec;
		for (int j = 0; j < (int)H[i].size(); j++) {
			int val1 = dp[H[i][j]];
			int val2 = 0; if (siz[H[i][j]] >= K) val2 = 1;
			vec.push_back(val1 - val2);
		}
		sort(vec.begin(), vec.end());
		reverse(vec.begin(), vec.end());
		
		// Latter Half
		int cnt = 0;
		for (int j = 0; j < (int)H[i].size(); j++) {
			if (siz[H[i][j]] >= K) cnt += 1;
		}
		if (N - siz[i] >= K) cnt += 1;
		if (vec.size() >= 1) Answer = max(Answer, vec[0] + cnt);
		if (vec.size() >= 2) Answer = max(Answer, vec[0] + vec[1] + cnt);
	}
	
	// Output
	cout << Answer << endl;
	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 21040
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;

int ans = 0;

pair<int,int> dfs(int n,int p,int &K,vector<vector<int>>&ki) {
    int sum = 1,cnt = 0;
    vector<int>res;
    for(int i:ki[n]) {
        if(i == p) {
            continue;
        }
        pair<int,int> a = dfs(i,n,K,ki);
        sum += a.first;
        cnt += (a.first >= K);
        res.push_back(a.second-(a.first >= K));
    }
    cnt += (ki.size()-sum >= K);
    res.push_back(0);
    sort(res.rbegin(),res.rend());
    if(res.size() >= 2) {
        ans = max(ans,cnt+res[0]+res[1]);
    }
    cnt -= (ki.size()-sum >= K);
    return {sum,cnt+res[0]};
}

int main() {
    int N,K;
    cin >> N >> K;
    vector<vector<int>>ki(N);
    for(int i = 0; i < N-1; i++) {
        int u,v;
        cin >> u >> v;
        u--;
        v--;
        ki[u].push_back(v);
        ki[v].push_back(u);
    }
    dfs(0,-1,K,ki);
    cout << ans << endl;
}
accuracy: 1
time_ms: 40
memory_kb: 16840
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using pii = pair<int, int>;
#define all(v) (v).begin(), (v).end()
#define rep(i, x) for(int i = 0; i < (x); i++)
#define rng(i, l, r) for(int i = (l); i < (r); i++)
#define sz(v) (int)(v).begin(), (v).end()
const int inf = 1 << 30;
int main() {
	int n, k;
	cin >> n >> k;
	vector<vi> g(n);
	rep(i, n - 1) {
		int u, v;
		cin >> u >> v;
		--u, --v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	vector subtree_size(n, 1);
	auto f = [&](auto f, int now, int per = -1) -> void {
		for(auto to : g[now]) {
			if(to == per) continue;
			f(f, to, now);
			subtree_size[now] += subtree_size[to];
		}
	};
	f(f, 0);

	vector dp(n, vector(2, 0));
	int res = 0;
	auto dfs = [&](auto dfs, int now, int per = -1) -> void {
		vector<int> ch(3, -inf);
		ch[0] = 0;
		for(auto to : g[now]) {
			if(to == per) continue;
			dfs(dfs, to, now);
			vector<int> nx(3, -inf);
			rep(j, 3) {
				rep(l, 2) {
					if(j + l > 2) continue;
					nx[j + l] = max(nx[j + l], ch[j] + dp[to][l]);
				}
			}
			ch = move(nx);
		}
		res = max(res, max(ch[1], ch[2]) + (n - subtree_size[now] >= k));
		dp[now][0] = (subtree_size[now] >= k);
		dp[now][1] = max(ch[0], ch[1]);
	};
	dfs(dfs, 0);
	cout << res << endl;
}
accuracy: 1
time_ms: 50
memory_kb: 25392
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T> bool chmax(T& a, const T& b) { return a < b ? (a = b, 1) : 0; }
template <typename T> bool chmin(T& a, const T& b) { return a > b ? (a = b, 1) : 0; }

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int N, K;
    cin >> N >> K;
    vector<vector<int>> G(N);
    rep(i,0,N-1) {
        int u, v;
        cin >> u >> v;
        --u, --v;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    vector<int> sz(N), dp(N);
    int ans = 0;

    auto dfs = [&](auto& dfs, int v, int p) -> void {
        sz[v] = 1;
        int cnt1 = 0, cnt0 = 0;
        int m1 = -1, m2 = -1;
        for (int c : G[v]) {
            if (c == p) continue;
            dfs(dfs, c, v);
            sz[v] += sz[c];
            if (sz[c] >= K) ++cnt1;
            else ++cnt0;
            if (m1 <= dp[c]) {
                m2 = m1;
                m1 = dp[c];
            } else if (m2 < dp[c]) {
                m2 = dp[c];
            }
        }
        int cnt2 = (N-sz[v] >= K ? 1 : 0);
        if (m1 == -1) {
            dp[v] = 0;
        } else if (m1 == 0) {
            if (cnt0 > 0) {
                chmax(ans, cnt1+cnt2);
            } else {
                chmax(ans, cnt1+cnt2-1);
            }
            dp[v] = cnt1;
        } else if (m2 <= 0) {
            chmax(ans, m1+cnt1-1+cnt2);
            dp[v] = m1+cnt1-1;
        } else {
            chmax(ans, m1+m2+cnt1-2+cnt2);
            dp[v] = m1+cnt1-1;
        }
    };

    dfs(dfs, 0, -1);
    cout << ans << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 16536
final_rank: 3

code_snippet: #include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
int n,K,h[1001010],m1,g[1001010],f[1001010];
int siz[1001010],ans;
struct edge{
	int next,to;
	edge(int next=0,int to=0):
	next(next),to(to){}
}q[2020200];
void Addedge(){
	int x,y; scanf("%d %d",&x,&y);
	q[++m1]=edge(h[x],y); h[x]=m1;
	q[++m1]=edge(h[y],x); h[y]=m1;
}
void Dfs1(int x,int fa){
	siz[x]=1;
	for (int i=h[x];i;i=q[i].next){
		int y=q[i].to;
		if (y==fa) continue;
		Dfs1(y,x); siz[x]+=siz[y];
	}
}
void Dfs2(int x,int fa){
	int Max1=-21001010,Max2=-21001010;
	for (int i=h[x];i;i=q[i].next){
		int y=q[i].to;
		if (y==fa) continue;
		Dfs2(y,x);
		if (siz[y]>=K) f[x]++;
		if (f[y]-g[y]>Max1) Max2=Max1,Max1=f[y]-g[y];
		else if (f[y]-g[y]>Max2) Max2=f[y]-g[y];
	}
	
	if (siz[x]>=K) g[x]=1;
	ans=max(ans,f[x]+Max1+(n-siz[x]>=K)); 
	ans=max(ans,f[x]+Max1+Max2+(n-siz[x]>=K));
	f[x]=max(f[x],f[x]+Max1);
}
int main(){
	scanf("%d %d",&n,&K);
	for (int i=1;i<n;i++) Addedge();
	Dfs1(1,0); Dfs2(1,0);
	cout<<ans<<endl;
}
accuracy: 1
time_ms: 20
memory_kb: 25584
final_rank: 12

code_snippet: #pragma GCC optimize("Ofast")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <cstdio>
#include <ctime>
#include <assert.h>
#include <chrono>
#include <random>
#include <numeric>
#include <set>
#include <deque>
#include <stack>
#include <sstream>
#include <utility>
#include <cstring>
#include <unordered_map>
#include <unordered_set>
#include <tuple>
#include <array>
#include <bitset>
using namespace std;
typedef long long int ll;
typedef unsigned long long ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline double time() {
    return static_cast<long double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n,k; cin >> n >> k;
    vector<vector<int>> g(n);
    for(int i=1;i<n;i++){
        int x,y; cin >> x >> y;
        x--; y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    int res = 0;
    vector<int> cnt(n);
    auto dfs=[&](auto dfs,int s,int p)->int{
        cnt[s] = 1;
        vector<int> v,vv;
        for(int t:g[s]){
            if(t == p)continue;
            int r = dfs(dfs,t,s);
            cnt[s] += cnt[t];
            if(cnt[t] >= k){
                v.push_back(r);
            }
            else{
                vv.push_back(r);
            }
        }
        sort(v.rbegin(), v.rend());
        sort(vv.rbegin(), vv.rend());
        int ad = (n-cnt[s] >= k);
        int c = v.size();

        // 2つ使う
        if(v.size() >= 2){
            res = max(res, v[0]+v[1]+c-2+ad);
        }
        if(v.size() and vv.size()){
            res = max(res, v[0]+vv[0]+c-1+ad);
        }
        if(vv.size() >= 2){
            res = max(res, vv[0]+vv[1]+c+ad);
        }
        // 1つ使う
        if(v.size()){
            res = max(res, v[0]+c-1+ad);
        }
        if(vv.size()){
            res = max(res, vv[0]+c+ad);
        }

        int val = c;
        if(v.size()){
            val = max(val, v[0]+c-1);
        }
        if(vv.size()){
            val = max(val, vv[0]+c);
        }

        return val;        
    };
    dfs(dfs,0,-1);
    cout << res << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 22356
final_rank: 9

code_snippet: #pragma GCC optimize("Ofast")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <cstdio>
#include <ctime>
#include <assert.h>
#include <chrono>
#include <random>
#include <numeric>
#include <set>
#include <deque>
#include <stack>
#include <sstream>
#include <utility>
#include <cstring>
#include <unordered_map>
#include <unordered_set>
#include <tuple>
#include <array>
#include <bitset>
using namespace std;
typedef long long int ll;
typedef unsigned long long ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline double time() {
    return static_cast<long double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n,k; cin >> n >> k;
    vector<vector<int>> g(n);
    for(int i=1;i<n;i++){
        int x,y; cin >> x >> y;
        x--; y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    int res = 0;
    vector<int> cnt(n);
    vector<int> dp1(n),dp2(n);
    auto dfs=[&](auto dfs,int s,int p)->void{
        cnt[s] = 1;
        int c = 0;
        for(int t:g[s]){
            if(t == p)continue;
            dfs(dfs,t,s);
            cnt[s] += cnt[t];
            c += (cnt[t] >= k);
        }

        dp1[s] = c;
        for(int t:g[s]){
            if(t == p)continue;
            dp1[s] = max(dp1[s], dp1[t]);
            dp2[s] = max(dp2[s], dp2[t]);
        }

        int u = -1, uu = -1;
        for(int t:g[s]){
            if(t == p)continue;
            dp2[s] = max(dp2[s], dp1[t]+c-(cnt[t]>=k));
            dp1[s] = max(dp1[s], dp1[t]+c-(cnt[t]>=k));

            int uuu = dp1[t] - (cnt[t] >= k);
            if(u < uuu){
                uu = u;
                u = uuu;
            }
            else if(uu < uuu){
                uu = uuu;
            }
        }
        dp2[s] = max(dp2[s], c+u+uu);

        if(cnt[s] != 1){
            res = max(res, dp2[s]+(n-cnt[s] >= k));
        }
    };
    dfs(dfs,0,-1);
    cout << res << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 19736
final_rank: 6

code_snippet: #include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#define _GLIBCXX_DEBUG
using namespace std;
using std::cout;
using std::cin;
using std::endl;
using ll=long long;
using ld=long double;
ll ILL=1167167167167167167;
const int INF=2100000000;
const ll mod=998244353;
#define rep(i,a) for (int i=0;i<a;i++)
#define all(p) p.begin(),p.end()
template<class T> using _pq = priority_queue<T, vector<T>, greater<T>>;
template<class T> ll LB(vector<T> &v,T a){return lower_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> ll UB(vector<T> &v,T a){return upper_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> bool chmin(T &a,const T &b){if(a>b){a=b;return 1;}else return 0;}
template<class T> bool chmax(T &a,const T &b){if(a<b){a=b;return 1;}else return 0;}
template<class T> void So(vector<T> &v) {sort(v.begin(),v.end());}
template<class T> void Sore(vector<T> &v) {sort(v.begin(),v.end(),[](T x,T y){return x>y;});}
void yneos(bool a){if(a) cout<<"Yes\n"; else cout<<"No\n";}
template<class T> void vec_out(vector<T> &p){for(int i=0;i<(int)(p.size());i++){if(i) cout<<" ";cout<<p[i];}cout<<"\n";}

void solve();
// oddloop
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	int t=1;
	//cin>>t;
	rep(i,t) solve();
}

void solve(){
	int N,K;
	cin>>N>>K;
	vector<vector<int>> G(N);
	rep(i,N-1){
		int a,b; 
		cin>>a>>b; 
		a--,b--;
		G[a].push_back(b);
		G[b].push_back(a);
	}
	vector<int> order={0},pare(N,-1),siz(N,1),dp(N);
	pare[0]--;
	rep(i,N){
		int a=order[i];
		for(auto x:G[a]){
			if(pare[x]==-1){
				pare[x]=a;
				order.push_back(x);
			}
		}
	}
	int ans=0;
	for(int i=N-1;i>=0;i--){
		int A=-INF,B=-INF,ind=order[i];
		int tmp=0;
		for(auto x:G[ind]){
			if(pare[x]==ind){
				siz[ind]+=siz[x];
				int V=dp[x];
				if(siz[x]>=K) tmp++,V--;
				if(chmax(B,V)){
					if(A<B) swap(A,B);
				}
			}
		}
		int U=0;
		if(N-siz[ind]>=K) U=1;
		chmax(ans,tmp+A+U+max(0,B));
		dp[ind]=tmp+max(0,A);
	}
	cout<<ans<<"\n";
}
accuracy: 1
time_ms: 20
memory_kb: 10628
final_rank: 1

code_snippet: #include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;

//constexpr long long int MOD = 1000000007;
constexpr long long int MOD = 998244353;
constexpr long double EPS = 1e-12;

//int N, M, K, T, H, W, L, R;
long long int N, M, K, T, H, W, L, R;

pair<int, int>add(pair<int, int>a, pair<int, int>b) {
	return make_pair(a.first + b.first, a.second + b.second);
}

pair<int, int>add2(pair<int, int>a, pair<int, int>b) {
	return make_pair(a.first + b.first + (a.second >= K) + (b.second >= K), 0);
}

void func(vector<vector<int>>& edge, vector<vector<pair<int, int>>>& dp, int node = 0, int p = -1) {
	bool leaf = true;
	dp[node][0] = { 0,0 };
	vector<pair<int, int>>use(3, { -MOD,-MOD });
	use[0] = { 0,0 };
	for (auto i : edge[node]) {
		if (i == p)continue;
		leaf = false;
		func(edge, dp, i, node);
		dp[node][2] = max(add(dp[node][2], dp[i][0]), add(dp[node][0], dp[i][2]));
		dp[node][0] = add(dp[node][0], dp[i][0]);
		use[2] = max(add2(use[2], dp[i][0]), add2(use[1], dp[i][1]));
		use[1] = max(add2(use[1], dp[i][0]), add2(use[0], dp[i][1]));
		use[0] = add2(use[0], dp[i][0]);
	}
	if (leaf) {
		dp[node][0] = { 0,1 };
		dp[node][1] = { 0,0 };
	}
	else {
		dp[node][0].second++;
		dp[node][2].second++;
		dp[node][1] = max({ dp[node][1], use[0] ,use[1] });
		dp[node][2] = max({ dp[node][2], use[1] ,use[2] });
	}
}

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

	cin >> N >> K;
	vector<vector<int>>edge(N);
	for (int i = 1; i < N; i++) {
		cin >> L >> R;
		L--, R--;
		edge[L].push_back(R);
		edge[R].push_back(L);
	}
	vector<vector<pair<int, int>>>dp(N, vector<pair<int, int>>(3, { -MOD,-MOD }));
	func(edge, dp);
	//for (int i = 0; i < N; i++) {
	//	for (int j = 0; j < 3; j++) {
	//		cout << i << " " << j << " " << dp[i][j].first << " " << dp[i][j].second << endl;
	//	}
	//}
	cout << dp[0][2].first + (dp[0][2].second >= K) << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 23144
final_rank: 10

code_snippet: #pragma GCC ta g("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
//#include <atcoder/maxflow>
//using namespace atcoder;
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 510000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
const double pi = acos(-1);
const double eps = 1e-9;
//const int mod = 1e9 + 7;
const int mod = 998244353;

int main(){
	int n,k; cin >> n >> k;
	vvl G(n);
	rep(i,n-1){
		int u,v; cin >> u >> v; u--; v--;
		G[u].push_back(v);
		G[v].push_back(u);
	}
	vvl dp(n,vl(2,0)); //dp[x][0]は部分木のサイズ
	ll ans = 0;
	auto dfs = [&](auto &&dfs, int u, int p) -> void {
		vl diff;
		ll s = 0;
		dp[u][0] = 1;
		for(auto v : G[u]){
			if(v == p) continue;
			dfs(dfs,v,u);
			dp[u][0] += dp[v][0];
			diff.push_back(dp[v][1] - (dp[v][0] >= k));
			s += (dp[v][0] >= k);
		}
		sort(rall(diff));
		//debug(u,diff,s);
		if(diff.empty()) return;
		chmax(ans, diff[0] + s + (n - dp[u][0] >= k));
		chmax(dp[u][1], max(diff[0] + s, s));
		if(diff.size() < 2) return;
		chmax(ans, diff[0] + diff[1] + s + (n - dp[u][0] >= k));
	};
	dfs(dfs,0,-1);
	//debug(dp);
	cout << ans << endl;
}
accuracy: 1
time_ms: 50
memory_kb: 23112
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
#define R cin>>
#define Z class
#define ll long long
#define ln cout<<'\n'
#define in(a) insert(a)
#define pb(a) push_back(a)
#define pd(a) printf("%.10f\n",a)
#define mem(a) memset(a,0,sizeof(a))
#define all(c) (c).begin(),(c).end()
#define iter(c) __typeof((c).begin())
#define rrep(i,n) for(ll i=(ll)(n)-1;i>=0;i--)
#define REP(i,m,n) for(ll i=(ll)(m);i<(ll)(n);i++)
#define rep(i,n) REP(i,0,n)
#define tr(it,c) for(iter(c) it=(c).begin();it!=(c).end();it++)
template<Z A>void pr(A a){cout<<a;ln;}
template<Z A,Z B>void pr(A a,B b){cout<<a<<' ';pr(b);}
template<Z A,Z B,Z C>void pr(A a,B b,C c){cout<<a<<' ';pr(b,c);}
template<Z A,Z B,Z C,Z D>void pr(A a,B b,C c,D d){cout<<a<<' ';pr(b,c,d);}
template<Z A>void PR(A a,ll n){rep(i,n){if(i)cout<<' ';cout<<a[i];}ln;}
ll check(ll n,ll m,ll x,ll y){return x>=0&&x<n&&y>=0&&y<m;}
const ll MAX=1000000007,MAXL=1LL<<61,dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
typedef pair<int,int> P;

int n,m;
vector<P> v[100001];
int solve(int i,int p) {
  if(v[i].size()==1&&v[i][0].F==p) {
    v[i][0].S=n-1;
    return 1;
  }
  int q=0,k=-1;
  for(int j=0; j<v[i].size(); j++) {
    if(v[i][j].F!=p) {
      if(v[i][j].S==-1) {
        v[i][j].S=solve(v[i][j].F,i);
        q+=v[i][j].S;
      } else q+=v[i][j].S;
    } else k=j;
  }
  if(k!=-1) v[i][k].S=n-1-q;
  return q+1;
}

ll dp[111111],ans=0;
void dfs(ll x,ll p) {
  ll sum=0,q=0;
  rep(i,v[x].size()) {
    int y=v[x][i].F;
    if(y==p) {
      q=v[x][i].S;
      continue;
    }
    dfs(y,x);
    if(v[x][i].S>=m) sum++;
  }
  bool f=0;
  vector<int> vv;
  rep(i,v[x].size()) {
    int y=v[x][i].F;
    if(y==p) continue;
    vv.pb(dp[y]-(v[x][i].S>=m));
    if(v[x][i].S>=m) sum--;
    dp[x]=max(dp[x],sum+dp[y]);
    f=1;
    if(v[x][i].S>=m) sum++;
  }
  sort(all(vv),greater<int>());
  if(vv.size()>=2) ans=max(ans,sum+vv[0]+vv[1]+(q>=m));
  if(f) ans=max(ans,dp[x]+(q>=m));
  dp[x]=max(dp[x],sum);
}

void Main() {
  cin >> n >> m;
  rep(i,n-1) {
    int x,y;
    cin >> x >> y;
    x--,y--;
    v[x].pb(P(y,-1));
    v[y].pb(P(x,-1));
  }
  solve(0,-1);
  dfs(0,-1);
  pr(ans);
}

int main(){ios::sync_with_stdio(0);cin.tie(0);Main();return 0;}
accuracy: 1
time_ms: 30
memory_kb: 18584
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
int main(){
  int N, K;
  cin >> N >> K;
  vector<vector<int>> E(N);
  for (int i = 0; i < N - 1; i++){
    int u, v;
    cin >> u >> v;
    u--;
    v--;
    E[u].push_back(v);
    E[v].push_back(u);
  }
  vector<int> p(N, -1);
  vector<vector<int>> c(N);
  vector<int> b;
  queue<int> Q;
  Q.push(0);
  while (!Q.empty()){
    int v = Q.front();
    Q.pop();
    b.push_back(v);
    for (int w : E[v]){
      if (w != p[v]){
        p[w] = v;
        c[v].push_back(w);
        Q.push(w);
      }
    }
  }
  reverse(b.begin(), b.end());
  vector<int> sz(N, 1);
  for (int v : b){
    for (int w : c[v]){
      sz[v] += sz[w];
    }
  }
  vector<int> dp(N, 0);
  for (int v : b){
    int cnt = c[v].size();
    int sum = 0, mx = 0;
    for (int w : c[v]){
      int a = 0;
      if (sz[w] >= K){
        a = 1;
      }
      sum += a;
      mx = max(mx, dp[w] - a);
    }
    dp[v] = sum + mx;
  }
  int ans = 0;
  for (int v : b){
    if (!c[v].empty()){
      int sum = 0;
      vector<int> d;
      for (int w : c[v]){
        int a = 0;
        if (sz[w] >= K){
          a = 1;
        }
        sum += a;
        d.push_back(dp[w] - a);
      }
      sort(d.begin(), d.end(), greater<int>());
      int tmp = sum;
      if (d.size() == 1){
        tmp += d[0];
      } else if (d.size() >= 2){
        tmp += d[0] + max(d[1], 0);
      }
      if (N - sz[v] >= K){
        tmp++;
      }
      ans = max(ans, tmp);
    }
  }
  cout << ans << endl;
}
accuracy: 1
time_ms: 70
memory_kb: 15236
final_rank: 16