Problem: 2063C - Remove Exactly Two
Language: c++17 

Solution 1 (runtime: 624 ms):
// Problem: C. Remove Exactly Two
// Contest: Codeforces - Codeforces Round 1000 (Div. 2)
// URL: https://codeforces.com/contest/2063/problem/C
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// Author: alchemist_17


#include<bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#define sped ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL); 
 
#define ln '\n'
#define ld long double
#define int long long
#define f first
#define s second
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define mii map<int, int>
#define pii pair<int, int>
#define vi vector<int>
#define vpii vector<pii>
#define vvi vector<vi>
#define pb push_back
#define sara(x) cout << #x << " = " << x << "\n"
#define setbitsll(n)  __builtin_popcountll(n) //counts all set bits in (int)num, setbitsll(num)==1 i.e no. is power of 2
#define setbits(n)  __builtin_popcount(n) 
#define msb(x) __builtin_clzll(x) // to count leading 0 , to find index = 64-msb(n)-1
#define lsb(x) __builtin_ctzll(x) // to count trailing 0 , to find index = lsb(n)
#define yesno(f) f?cout<<"YES\n":cout<<"NO\n"
#define mx(v) *max_element(v.begin(),v.end())
#define mn(v) *min_element(v.begin(),v.end())
#define loop(n) for(int i=0; i<n; ++i)
#define alone(v) v.erase(unique(v.begin(),v.end()),v.end())
#define inf LLONG_MAX
#define PI 3.14159265359
#define ordered_set tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>
 
/*
  If mod operations performed , divide won't work instead of / , * by its mod inverse 
*/
/* ordered_set st
   st.order_of_key(k) : no. of elements < k
   *st.find_by_order(i) : value at index i (0-based)
*/
/* In Interactive problem use :
   endl (flushes buffer automatically)(provide o/p for each query) 
   or use '\n' (provide o/p for all query at once) along with cout.flush();
*/
 
/* n=10010010
         0010(want till ith)
   extracted no.=(n%(1<<(i+1))) i.e.0010 
   remaining no.=n^((n%(1<<(i+1)))) i.e. 10010000
   ct of ith → (i+1)*(n-i) // no. of subarrays containing the ith element, total subarrays = n*(n+1)/2
   n % 2ʲ -> last j bits of n
*/
 
// upper bound of factors:cbrt(n)
 
const long long M = 1000000007;
const int N = 1000000;
vector<bool> isprime(N + 1, true);
vector<int> spf(N + 1, 0);
 
int lcm(int a, int b){int g=__gcd(a, b); return a/g*b;}
 
int factorial(int n){n%=M; if(n<=1) return 1; return n*factorial(n-1)%M;}
 
int binexp(int a, int b , int m) {
  if (b == 0) return 1;
  if (b == 1) return (a) % m;
  int res = binexp(a, b / 2 , m);
  if (b % 2 == 0) return (res * res) % m;
  return ((res * res) % m * (a) % m) % m;
}
 
int modinv(int a, int p)
{return binexp(a, p - 2, p);}
 
long double ncr(int n,int r){if(n<r)return 0.0;if(n-r<r)r=n-r;long double ans=1.0;for(int i=1;i<=r;++i){ans*=n-i+1;ans/=i;}return ans;}
 
void SPF(){
  for (int i = 1; i <= N; i++){ spf[i] = i;}spf[1] = -1;
  for (int i = 2; i * i <= N; i++) {if (spf[i] == i) {for (int j = i * i; j <= N; j += i) {if (spf[j] == j) {spf[j] = i;}}}}
}
 
void sieve() {
    isprime[0]=isprime[1] = false;
for (int i = 2; i * i <= N; i++) {if (isprime[i]) {for (int j = i * i; j <= N; j += i) {if (isprime[j] == true) isprime[j] = false;}}}
}
 
 
//<---------------------------code begins--------------------------->
 
int32_t main() {
    sped
    int t;
    cin >> t;
    while (t--) {
         int n;
    cin>>n;
    vvi adj(n);
    for(int i=0;i<n-1;i++){
        int u,v;
        cin>>u>>v;
        --u;
        --v;
        adj[u].pb(v);
        adj[v].pb(u);
    }
    set<pii> s;
    vpii b;
    for(int i=0;i<n;i++){
        s.insert({adj[i].size(),i});
        b.pb({adj[i].size(),i});
    }
    sort(rall(b));
    int ans=0;
    for(int j=0;j<min(n,3ll);j++){
        int i=b[j].s;
        set<pii> temp=s;
        pii p1={adj[i].size(),i};
        int a1=max(0ll,p1.f);
        s.erase(s.find(p1));
        for(auto it:adj[i]){
            pii p1={adj[it].size(),it};
            s.erase(s.find(p1));
            pii p2={adj[it].size()-1,it};
            s.insert(p2);
        }
        auto it=(--s.end());
        int a2=max(0ll,it->f);
        ans=max(ans,a1+a2-1);
        s=temp;
    }
    cout << ans << ln;
    }
}



Solution 2 (runtime: 530 ms):
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <set>
using namespace std;

const int N = 2e5+3;

int n,m,deg[N],ans;
vector<int> t[N];
multiset<int> q;

void s1(int u,int fa){
	for (int v:t[u]){
		if (v==fa) continue;
		ans = max(ans,deg[u]+deg[v]-2);
		s1(v,u);
	}
}
void del(int v){
	auto it = q.find(v);
	q.erase(it);
}
void s2(int u,int fa){
	del(deg[u]); 
	for (int v:t[u]){
		if (v) del(deg[v]);
	}
	if (!q.empty()) ans = max(ans,deg[u]+*(q.rbegin())-1);
	for (int v:t[u]){
		if (v) q.insert(deg[v]);
	}
	q.insert(deg[u]);
	for (int v:t[u]){
		if (v==fa) continue;
		s2(v,u);
	}
}
void work(){
	s1(1,0);
	s2(1,0);
	printf("%d\n",ans);
}

void init(){
	scanf("%d",&n);
	memset(deg,0,sizeof deg);
	for (int i=1;i<=n;++i) t[i].clear();
	for (int i=1,u,v;i<n;++i){
		scanf("%d%d",&u,&v);
		deg[u]++;deg[v]++;
		t[u].emplace_back(v);
		t[v].emplace_back(u);
	} 
	q.clear();
	for (int i=1;i<=n;++i) q.insert(deg[i]);
	ans = 0;
}

int main(){
	int T = 1;
	scanf("%d",&T);
	while(T--){
		init();
		work();
	}
	return 0;
}