Link to this code: https://cses.fi/paste/f28a122b3601afbbd98287/
/* 777 */
#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 2e5 + 5;
int dp[MAX_N][2];
vector<int> g[MAX_N];

// dp(u, x) -> maximum matchings you can get at node `u`

int dfs(int u, int par, int x) {
    if (dp[u][x] != -1) return dp[u][x];
    int ans = 0, xt = 0;  // xt - extra
    for (int v : g[u]) {
        if (v == par) continue;
        int pick = dfs(v, u, 0);
        int notpick = dfs(v, u, 1);
        ans += max(pick, notpick);
        xt = max(xt, 1 + pick - max(pick, notpick));
    }
    return dp[u][x] = ans + (x * xt);
}

void solve() {
    memset(dp, -1, sizeof(dp));
    int N;
    cin >> N;
    for (int i = 0; i < N - 1; ++i) {
        int u, v;
        cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    cout << max(dfs(1, 0, 1), dfs(1, 0, 0));
}

int32_t main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int T = 1;
    // cin >> T;
    while (T--) solve();
}

/*
- dp(u, x) -> denotes a state where we can get maximum matchings at node `u`
given that
    if `x` is 1 -> you can make a pair (u, v) with any of the neighbor `v`
    if `x` is 0 -> you can't make a pair involving node `u` anymore

- for each node `u` you can either choose dp(v, 0) or dp(v, 1) so we choose the max of both

dp(u, 0) -> sum(max(dp(v, 1), dp(v, 0)))

dp(u, 1) -> sum(max(dp(v, 1), dp(v, 0))) for all neighbors except the chosen one `v`
            we consider on dp(v, 0) for that

            S - max(pick, not pick) + pick <-----maximise
            so we need the maximum (pick - max(pick, not pick)) which is extra
*/