Problem: 2063C - Remove Exactly Two
Language: C++20 (GCC 13-64)

Previous submission (verdict: Wrong answer on test 2):
#include<bits/stdc++.h>
using namespace std; typedef long long int ll; typedef long double ld; typedef unsigned long long int ull; typedef vector<vector<int> > vvi; typedef vector<ll> vll; typedef pair<long long int,long long int> pll; typedef vector<pll> vpll;
#define repi(i,s,e) for(ll i=s;i<e;i++)
#define repd(i,e,s) for(ll i=e;i>=s;i--)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define pb push_back
#define sp " "
#define nl "\n"
#define INF numeric_limits<float>::infinity()
const ll MOD = 1e9 + 7;
template <typename T> struct SumOperation {pair<T, int> operator()(pair<T, int> a, pair<T, int> b) const { return {a.first + b.first, a.second}; }pair<T, int> getNeutralElement() const { return {0, -1}; }};template <typename T>struct MinOperation {pair<T, int> operator()(pair<T, int> a, pair<T, int> b) const { return a.first < b.first ? pair<T, int> {a.first, a.second} : pair<T, int> {b.first, b.second}; }pair<T, int> getNeutralElement() const { return {numeric_limits<T>::max(), -1}; }};template <typename T>struct MaxOperation {pair<T, int> operator()(pair<T, int> a, pair<T, int> b) const { return a.first > b.first ? pair<T, int> {a.first, a.second} : pair<T, int> {b.first, b.second}; }pair<T, int> getNeutralElement() const { return {numeric_limits<T>::min(), -1}; }};template <typename T, typename MergeOperation = SumOperation<T>>
class SegmentTree {private:vector<pair<T, int>> tree;MergeOperation mergeOp;int n;void build(const vector<T>& v) {for(int i = 0; i < n; i++) {tree[n + i] = {v[i], i};}for(int i = n - 1; i > 0; i--) {tree[i] = mergeOp(tree[i << 1], tree[i << 1 | 1]);}}public:SegmentTree(const vector<T>& v, const MergeOperation& op = MergeOperation()) : mergeOp(op), n(v.size()), tree(vector<pair<T, int>>(2 * v.size(), op.getNeutralElement())) {build(v);}void update(int index, T value) {if(index < 0 || index >= n) return; for(tree[index += n].first = value; index > 1; index >>= 1) {tree[index >> 1] = mergeOp(tree[index], tree[index ^ 1]);}}pair<T, int> query(int l, int r) {pair<T, int> res = mergeOp.getNeutralElement();if(l < 0 || r > n) return res;for(l += n, r += n; l < r; l >>= 1, r >>= 1) {if(l & 1) res = mergeOp(res, tree[l++]);if(r & 1) res = mergeOp(res, tree[--r]);}return res;}};
class DSU{private:vll parent;vll rank;public:DSU(ll n){parent.resize(n);rank.resize(n,0);for(ll i=0;i<n;++i){parent[i]=i;}}ll find(ll x){if(parent[x]==x)return x;return parent[x]=find(parent[x]);}void union_sets(ll x, ll y){ll root_x = find(x);ll root_y = find(y);if (root_x != root_y){if (rank[root_x] < rank[root_y])parent[root_x] = root_y;else if (rank[root_x] > rank[root_y])parent[root_y] = root_x;else{parent[root_y] = root_x;rank[root_x]++;}}}};
bool isPrime(ll n){if (n <= 1)return false; if (n==2) return true; for (ll i = 2; i < sqrt(n)+1; i++)if (n % i == 0)return false;return true;}
bool isPowerOfTwo(ull n){return n && !(n & (n - 1));}
ll gcdExtended(ll a, ll b, ll &x, ll &y){if (a == 0) {x = 0;y = 1;return b;}ll x1, y1;ll gcd = gcdExtended(b % a, a, x1, y1);x = y1 - (b / a) * x1;y = x1;return gcd;}
ll modInverse(ll a, ll M){ll x, y;ll gcd = gcdExtended(a, M, x, y);if (gcd != 1) {return -1;} else {return (x % M + M) % M;}}
ll modPow(ll base, ll exponent, ll modulus){if (exponent == -1){return modInverse(base, modulus);}if (modulus == 1)return 0;ll result = 1;base %= modulus;while (exponent > 0){if (exponent & 1)result = (result * base) % modulus;base = (base * base) % modulus;exponent /= 2;}return result;}
ll round_pow2(ll x){return pow(2,ceil(log(x)/log(2)));}
ll binaryToDecimal(string num){ll dec_value = 0, base = 1, len = num.length();for (ll i = len - 1; i >= 0; i--){if (num[i] == '1')dec_value += base;base = base * 2;}return dec_value;}
string DecimalToBinary(ll num){string str;if (num == 0)return "0";while (num){if (num & 1)str += '1';else num >>= 1;}reverse(all(str));return str;}
vll manacher_odd(string s) {ll n = s.size();s = "$" + s + "^";vector<ll> p(n + 2);ll l = 1, r = 1;for(ll i = 1; i <= n; i++) {p[i] = max(ll(0), min(r - i, p[l + (r - i)]));while(s[i - p[i]] == s[i + p[i]]) {p[i]++;}if(i + p[i] > r) {l = i - p[i], r = i + p[i];}}return vector<ll>(begin(p) + 1, end(p) - 1);}
vll manacher(string s) {string t;for(auto c: s) {t += string("#") + c;}auto res = manacher_odd(t + "#");return vector<ll>(begin(res) + 1, end(res) - 1);}
ll dist = 0;
void dfs(ll node, vector<vll>&adj, vector<bool> &vis, vector<pair<ll, pair<ll, ll>>> &v) {
    vis[node] = true;
    v[node].second.first = dist++;
    for(auto i : adj[node]) {
        if(!vis[i]) dfs(i, adj, vis, v);
    }
}
void dfs2(ll node, vector<vll>&adj, vector<bool>&vis) {
    vis[node] = true;
    for(auto i: adj[node])
        if(!vis[i]) dfs2(i, adj, vis);
}

void solve() {
    ll n;cin>>n;
    vector<vll> adj(n);
    for(int i = 0; i < n - 1; i++) {
        ll u, v; cin>>u>>v;
        u--;v--;
        adj[u].pb(v);
        adj[v].pb(u);
    }
    ll ans = 0;
    vector<pair<ll, pair<ll, ll>>> v(n), v2; // indegree, distance from leaf node, index
    ll leaf = -1;
    for(int i = 0; i < n; i++) {
        v[i].first = adj[i].size(), v[i].second.second = i;
        if(adj[i].size() == 1) {
            // leaf node
            leaf = i;
        }
    }
    // calculate distance from a leaf node
    vector<bool> vis(n, false);
    dfs(leaf, adj, vis, v);
    vis = vector<bool>(n, false);
    v2 = v;
    sort(rall(v));
    // removing the first node
    ll in = v2[0].second.second;
    for(auto i: adj[in]) v2[i].first--;
    v2[in].first = -1e9;
    vis[in] = true;
    sort(rall(v2));
    in = v2[0].second.second;
    vis[in] = true;
    for(int i = 0; i < n; i++) {
        if(!vis[i]) {
            ans++;
            dfs2(i, adj, vis);
        }
    }
    cout<<ans<<nl;
}

int main() {
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    ll t = 1;
    cin >> t;
    while (t--) solve();
    return 0;
}
// SegmentTree<ll> sumSegmentTree(arr);
// SegmentTree<ll, SumOperation<ll> > sumSegmentTree(arr);
// SegmentTree<ll, MinOperation<ll> > minSegmentTree(arr);
// SegmentTree<ll, MaxOperation<ll> > maxSegmentTree(arr);
// segmentTree.query(l,r); will return a query result int the form of {value, index}
// segmentTree.update(index, value);
// __builtin_clz(x): the number of zeros at the beginning of the number
// __builtin_ctz(x): the number of zeros at the end of the number
// __builtin_popcount(x): the number of ones in the number
// __builtin_parity(x): the parity (even or odd) of the number of ones
// __builtin_ffs(int) finds the index of the first (most right) set bit

Submission (verdict: Accepted):
#include<bits/stdc++.h>
using namespace std; typedef long long int ll; typedef long double ld; typedef unsigned long long int ull; typedef vector<vector<int> > vvi; typedef vector<ll> vll; typedef pair<long long int,long long int> pll; typedef vector<pll> vpll;
#define repi(i,s,e) for(ll i=s;i<e;i++)
#define repd(i,e,s) for(ll i=e;i>=s;i--)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define pb push_back
#define sp " "
#define nl "\n"
#define INF numeric_limits<float>::infinity()
const ll MOD = 1e9 + 7;
template <typename T> struct SumOperation {pair<T, int> operator()(pair<T, int> a, pair<T, int> b) const { return {a.first + b.first, a.second}; }pair<T, int> getNeutralElement() const { return {0, -1}; }};template <typename T>struct MinOperation {pair<T, int> operator()(pair<T, int> a, pair<T, int> b) const { return a.first < b.first ? pair<T, int> {a.first, a.second} : pair<T, int> {b.first, b.second}; }pair<T, int> getNeutralElement() const { return {numeric_limits<T>::max(), -1}; }};template <typename T>struct MaxOperation {pair<T, int> operator()(pair<T, int> a, pair<T, int> b) const { return a.first > b.first ? pair<T, int> {a.first, a.second} : pair<T, int> {b.first, b.second}; }pair<T, int> getNeutralElement() const { return {numeric_limits<T>::min(), -1}; }};template <typename T, typename MergeOperation = SumOperation<T>>
class SegmentTree {private:vector<pair<T, int>> tree;MergeOperation mergeOp;int n;void build(const vector<T>& v) {for(int i = 0; i < n; i++) {tree[n + i] = {v[i], i};}for(int i = n - 1; i > 0; i--) {tree[i] = mergeOp(tree[i << 1], tree[i << 1 | 1]);}}public:SegmentTree(const vector<T>& v, const MergeOperation& op = MergeOperation()) : mergeOp(op), n(v.size()), tree(vector<pair<T, int>>(2 * v.size(), op.getNeutralElement())) {build(v);}void update(int index, T value) {if(index < 0 || index >= n) return; for(tree[index += n].first = value; index > 1; index >>= 1) {tree[index >> 1] = mergeOp(tree[index], tree[index ^ 1]);}}pair<T, int> query(int l, int r) {pair<T, int> res = mergeOp.getNeutralElement();if(l < 0 || r > n) return res;for(l += n, r += n; l < r; l >>= 1, r >>= 1) {if(l & 1) res = mergeOp(res, tree[l++]);if(r & 1) res = mergeOp(res, tree[--r]);}return res;}};
class DSU{private:vll parent;vll rank;public:DSU(ll n){parent.resize(n);rank.resize(n,0);for(ll i=0;i<n;++i){parent[i]=i;}}ll find(ll x){if(parent[x]==x)return x;return parent[x]=find(parent[x]);}void union_sets(ll x, ll y){ll root_x = find(x);ll root_y = find(y);if (root_x != root_y){if (rank[root_x] < rank[root_y])parent[root_x] = root_y;else if (rank[root_x] > rank[root_y])parent[root_y] = root_x;else{parent[root_y] = root_x;rank[root_x]++;}}}};
bool isPrime(ll n){if (n <= 1)return false; if (n==2) return true; for (ll i = 2; i < sqrt(n)+1; i++)if (n % i == 0)return false;return true;}
bool isPowerOfTwo(ull n){return n && !(n & (n - 1));}
ll gcdExtended(ll a, ll b, ll &x, ll &y){if (a == 0) {x = 0;y = 1;return b;}ll x1, y1;ll gcd = gcdExtended(b % a, a, x1, y1);x = y1 - (b / a) * x1;y = x1;return gcd;}
ll modInverse(ll a, ll M){ll x, y;ll gcd = gcdExtended(a, M, x, y);if (gcd != 1) {return -1;} else {return (x % M + M) % M;}}
ll modPow(ll base, ll exponent, ll modulus){if (exponent == -1){return modInverse(base, modulus);}if (modulus == 1)return 0;ll result = 1;base %= modulus;while (exponent > 0){if (exponent & 1)result = (result * base) % modulus;base = (base * base) % modulus;exponent /= 2;}return result;}
ll round_pow2(ll x){return pow(2,ceil(log(x)/log(2)));}
ll binaryToDecimal(string num){ll dec_value = 0, base = 1, len = num.length();for (ll i = len - 1; i >= 0; i--){if (num[i] == '1')dec_value += base;base = base * 2;}return dec_value;}
string DecimalToBinary(ll num){string str;if (num == 0)return "0";while (num){if (num & 1)str += '1';else num >>= 1;}reverse(all(str));return str;}
vll manacher_odd(string s) {ll n = s.size();s = "$" + s + "^";vector<ll> p(n + 2);ll l = 1, r = 1;for(ll i = 1; i <= n; i++) {p[i] = max(ll(0), min(r - i, p[l + (r - i)]));while(s[i - p[i]] == s[i + p[i]]) {p[i]++;}if(i + p[i] > r) {l = i - p[i], r = i + p[i];}}return vector<ll>(begin(p) + 1, end(p) - 1);}
vll manacher(string s) {string t;for(auto c: s) {t += string("#") + c;}auto res = manacher_odd(t + "#");return vector<ll>(begin(res) + 1, end(res) - 1);}
ll dist = 0;
void dfs(ll node, vector<vll>&adj, vector<bool> &vis, vector<pair<ll, pair<ll, ll>>> &v) {
    vis[node] = true;
    v[node].second.first = dist++;
    for(auto i : adj[node]) {
        if(!vis[i]) dfs(i, adj, vis, v);
    }
}
void dfs2(ll node, vector<vll>&adj, vector<bool>&vis) {
    vis[node] = true;
    for(auto i: adj[node])
        if(!vis[i]) dfs2(i, adj, vis);
}

void solve() {
    dist = 0;
    ll n;cin>>n;
    vector<vll> adj(n);
    for(int i = 0; i < n - 1; i++) {
        ll u, v; cin>>u>>v;
        u--;v--;
        adj[u].pb(v);
        adj[v].pb(u);
    }
    ll ans = 0;
    vector<pair<ll, pair<ll, ll>>> v(n), v2; // indegree, distance from leaf node, index
    ll leaf = -1;
    for(int i = 0; i < n; i++) {
        v[i].first = adj[i].size(), v[i].second.second = i;
        if(adj[i].size() == 1) {
            // leaf node
            leaf = i;
        }
    }
    // calculate distance from a leaf node
    vector<bool> vis(n, false);
    dfs(leaf, adj, vis, v);
    vis = vector<bool>(n, false);
    v2 = v;
    // for(auto i: v) cout<<i.second.second + 1<<sp<<i.second.first<<nl;
    // 4-2-1-3-5
    sort(rall(v));
    // for(auto i: v)cout<<i.first<<sp<<i.second.first<<sp<<i.second.second + 1<<nl;
    // removing the first node
    ll in = v[0].second.second;
    for(auto i: adj[in]) v2[i].first--;
    v2[in].first = -1e9;
    vis[in] = true;
    sort(rall(v2));
    in = v2[0].second.second;
    vis[in] = true;
    for(int i = 0; i < n; i++) {
        if(!vis[i]) {
            ans++;
            dfs2(i, adj, vis);
        }
    }
    cout<<ans<<nl;
}

int main() {
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    ll t = 1;
    cin >> t;
    while (t--) solve();
    return 0;
}
// SegmentTree<ll> sumSegmentTree(arr);
// SegmentTree<ll, SumOperation<ll> > sumSegmentTree(arr);
// SegmentTree<ll, MinOperation<ll> > minSegmentTree(arr);
// SegmentTree<ll, MaxOperation<ll> > maxSegmentTree(arr);
// segmentTree.query(l,r); will return a query result int the form of {value, index}
// segmentTree.update(index, value);
// __builtin_clz(x): the number of zeros at the beginning of the number
// __builtin_ctz(x): the number of zeros at the end of the number
// __builtin_popcount(x): the number of ones in the number
// __builtin_parity(x): the parity (even or odd) of the number of ones
// __builtin_ffs(int) finds the index of the first (most right) set bit