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

Previous submission (verdict: Wrong answer on test 2):
#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <stdio.h>
#include <set>
#include <math.h>
#include <map>
#include <limits.h>
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <unordered_set>
#include <unordered_map>
#include <sstream>
#include <deque>
#include <time.h>
#include <list>
#include <iomanip>
#include <queue>
#include <cctype>
#include <regex>
#include <cstdint>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
//#define eps 1e-18
#define mod 1000000007
#define mod2 998244353
#define inf 2000000001
#define infD 200000000001
#define infL 2000000000000000001

ifstream in("input.txt");
ofstream out("output.txt");

template <typename T>
class DecartTree;

template <typename T>
class TreapNode {
public:
	/*template <typename T>
	friend class Treap;

	friend pair<TreapNode<T>* TreapNode<T>*> split(TreapNode<T>* t, int k);
	friend TreapNode<T>* merge(TreapNode<T>* left, TreapNode<T>* right);*/

	TreapNode* left;
	TreapNode* right;

	T value;
	int c; //������� ����, ���������� ��������� � ���������, ������� ����
	int y; //���������


	TreapNode(T value) {
		left = nullptr;
		right = nullptr;
		this->value = value;
		this->c = 1;
		y = rand();
	}


	void update() {
		c = 1 + (left == nullptr ? 0 : left->c) + (right == nullptr ? 0 : right->c);
	}
};

template <typename T>
class Treap {
	//friend pair<TreapNode<T>*, TreapNode<T>*> split(TreapNode<T>* t, int k);
	//friend TreapNode<T>* merge(TreapNode<T>* left, TreapNode<T>* right);
	//TreapNode<T>* root;

public:
	TreapNode<T>* root;
	void insert(int id, T value) {
		pair<TreapNode<T>*, TreapNode<T>*> p = split(root, id);
		root = merge(p.first, new TreapNode<T>(value));
		root = merge(root, p.second);
	}

	void erase(int id) {
		pair<TreapNode<T>*, TreapNode<T>*> p = split(root, id + 1);
		pair<TreapNode<T>*, TreapNode<T>*> p1 = split(p.first, id);
		delete p1.second;
		root = merge(p1.first, p.second);
	}

	T get(int id) {
		return getSup(root, id);
	}

	int find(T value) {
		return findSup(root, value);
	}

	void set(int id, T value) {
		setSup(root, id, value);
	}

	int size() {
		return root->c;
	}

	Treap() {
		srand(time(0));
		root = nullptr;
	}
};

template <typename T>
void setSup(TreapNode<T>* t, int id, T value) {
	int l = (t->left == nullptr ? 0 : t->left->c);
	if (l == id) {
		t->value = value;
		return;
	}
	if (l > id) {
		setSup(t->left, id, value);
	} else {
		setSup(t->right, id - l - 1, value);
	}
	return;
}

template<typename T>
int findSup(TreapNode<T>* t, T value) {
	if (t == nullptr) return -1e9;
	if (value == t->value) {
		return t->c;
	}
	if (value > t->value) {
		return t->c + findSup(t->right, value);
	} else {
		return findSup(t->left, value);
	}
}

template <typename T>
T getSup(TreapNode<T>* t, int id) {
	int l = (t->left == nullptr ? 0 : t->left->c);
	if (l == id) {
		return t->value;
	}
	if (l > id) {
		return getSup(t->left, id);
	} else {
		return getSup(t->right, id - l - 1);
	}
}

template <typename T>
pair<TreapNode<T>*, TreapNode<T>*> split(TreapNode<T>* t, int k) {
	if (t == nullptr) {
		return { nullptr, nullptr };
	}

	int l = (t->left == nullptr ? 0 : t->left->c);
	if (l >= k) {
		pair<TreapNode<T>*, TreapNode<T>*> p = split(t->left, k);
		t->left = p.second;
		t->update();
		return { p.first, t };
	} else {
		pair<TreapNode<T>*, TreapNode<T>*> p = split(t->right, k - l - 1);
		t->right = p.first;
		t->update();
		return { t, p.second };
	}
}

template <typename T>
TreapNode<T>* merge(TreapNode<T>* t1, TreapNode<T>* t2) {
	if (t2 == nullptr) {
		return t1;
	}
	if (t1 == nullptr) {
		return t2;
	}

	if (t1->y > t2->y) {
		t1->right = merge(t1->right, t2);
		t1->update();
		return t1;
	} else {
		t2->left = merge(t1, t2->left);
		t2->update();
		return t2;
	}
}

ll gcd(ll a, ll b) {
	return (b == 0 ? a : gcd(b, a % b));
}

ll lmc(ll a, ll b) {
	return a * b / gcd(a, b);
}

bool isPrime(ll n) {
	if (n == 1) return false;
	for (ll i = 2; i * i <= n; i++) {
		if (n % i == 0) return false;
	}
	return true;
}

vector<ll> getDels(ll n) {
	vector<ll> ans;
	for (ll i = 1; i * i <= n; i++) {
		if (n % i == 0) {
			ans.push_back(i);
			if (i * i != n) {
				ans.push_back(n / i);
			}
		}
	}
	sort(ans.begin(), ans.end());
	return ans;
}

ll binaryPow(ll n, ll st, ll module) {
	if (st == 0) {
		return 1;
	}
	if (st % 2 == 0) {
		ll ans = binaryPow(n, st / 2, module);
		return (ans * ans) % module;
	} else {
		return (binaryPow(n, st - 1, module) * n % module);
	}
}


int getSet(vector<int>& tree, int v) {
	if (tree[v] == v) {
		return v;
	}
	tree[v] = getSet(tree, tree[v]);
	return tree[v];
}

void unionSet(vector<int>& tree, int v, int u) {
	v = getSet(tree, v);
	u = getSet(tree, u);
	if (v != u) {
		tree[min(u, v)] = max(u, v);
	}
}

vector<int> zFunction(string& str) {
	int n = str.size();
	vector<int> z(n, 0);
	int l = 0;
	int r = 0;
	for (int i = 1; i < n; i++) {
		if (i <= r) z[i] = min(z[i - l], r - i + 1);

		while (i + z[i] < n && str[i + z[i]] == str[z[i]]) z[i]++;

		if (i + z[i] - 1 > r) {
			r = i + z[i] - 1;
			l = i;
		}
	}
	return z;
}

vector<ll> getPrimesToN(int n) {
	vector<bool> p(n + 1, true);
	p[0] = false;
	p[1] = false;
	for (ll i = 2; i * i <= n; i++) {
		if (p[i]) {
			for (ll j = i * i; j <= n; j += i) {
				p[j] = false;
			}
		}
	}
	vector<ll> primes;
	for (int i = 0; i <= n; i++) {
		if (p[i]) {
			primes.push_back(i);
		}
	}
	return primes;
}

vector<ll> getFactorization(ll n) {
	vector<ll> ans;
	for (ll i = 2; i * i <= n; i++) {
		while (n % i == 0) {
			ans.push_back(i);
			n /= i;
		}
	}
	if (n != 1) {
		ans.push_back(n);
	}
	return ans;
}


template <typename T1, typename T2>
ostream& operator<<(ostream& out, pair<T1, T2> const& p) {
	out << p.first << " " << p.second;
	return out;
}



template <typename T>
ostream& operator<<(ostream& out, vector<T> const& vec) {
	for (int i = 0; i < vec.size(); i++) {
		out << vec[i] << " ";
	}
	return out;
}


pair<int, int> dfs(vector<vector<int>>& g, int v, int p, int& ans) {
	int tmp = -1;

	vector<int> res1;
	int mx1 = -100;
	int mx2 = -100;
	for (int u : g[v]) {
		if (u != p) {
			auto res = dfs(g, u, v, ans);
			res1.push_back(res.first);
			tmp = max(tmp, (int) g[u].size());
			ans = max(ans, res.first + (int) g[v].size() - 2);
			ans = max(ans, res.second + (int)g[v].size() - 1);

			if (mx1 < max(res.first, res.second)) {
				mx2 = mx1;
				mx1 = max(res.first, res.second);
			} else if (max(res.first, res.second) > mx2) {
				mx2 = max(res.first, res.second);
			}
		}
	}
	ans = max(ans, mx1 + mx2 - 1);
	
	return { (int)g[v].size(), tmp };
}



int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	setlocale(LC_ALL, "RU");

	int t;
	t = 1;

	cin >> t;

	for (; t > 0; t--) {
		int n;
		cin >> n;
		vector<vector<int>> g(n);
		for (int i = 0; i < n - 1; i++) {
			int  v, u;
			cin >> v >> u;
			v--;
			u--;
			g[v].push_back(u);
			g[u].push_back(v);
		}
		int ans = 0;
		dfs(g, 0, -1, ans);

		cout << ans << endl;
	}
	return 0;
}

Submission (verdict: Accepted):
#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <stdio.h>
#include <set>
#include <math.h>
#include <map>
#include <limits.h>
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <unordered_set>
#include <unordered_map>
#include <sstream>
#include <deque>
#include <time.h>
#include <list>
#include <iomanip>
#include <queue>
#include <cctype>
#include <regex>
#include <cstdint>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
//#define eps 1e-18
#define mod 1000000007
#define mod2 998244353
#define inf 2000000001
#define infD 200000000001
#define infL 2000000000000000001

ifstream in("input.txt");
ofstream out("output.txt");

template <typename T>
class DecartTree;

template <typename T>
class TreapNode {
public:
	/*template <typename T>
	friend class Treap;

	friend pair<TreapNode<T>* TreapNode<T>*> split(TreapNode<T>* t, int k);
	friend TreapNode<T>* merge(TreapNode<T>* left, TreapNode<T>* right);*/

	TreapNode* left;
	TreapNode* right;

	T value;
	int c; //������� ����, ���������� ��������� � ���������, ������� ����
	int y; //���������


	TreapNode(T value) {
		left = nullptr;
		right = nullptr;
		this->value = value;
		this->c = 1;
		y = rand();
	}


	void update() {
		c = 1 + (left == nullptr ? 0 : left->c) + (right == nullptr ? 0 : right->c);
	}
};

template <typename T>
class Treap {
	//friend pair<TreapNode<T>*, TreapNode<T>*> split(TreapNode<T>* t, int k);
	//friend TreapNode<T>* merge(TreapNode<T>* left, TreapNode<T>* right);
	//TreapNode<T>* root;

public:
	TreapNode<T>* root;
	void insert(int id, T value) {
		pair<TreapNode<T>*, TreapNode<T>*> p = split(root, id);
		root = merge(p.first, new TreapNode<T>(value));
		root = merge(root, p.second);
	}

	void erase(int id) {
		pair<TreapNode<T>*, TreapNode<T>*> p = split(root, id + 1);
		pair<TreapNode<T>*, TreapNode<T>*> p1 = split(p.first, id);
		delete p1.second;
		root = merge(p1.first, p.second);
	}

	T get(int id) {
		return getSup(root, id);
	}

	int find(T value) {
		return findSup(root, value);
	}

	void set(int id, T value) {
		setSup(root, id, value);
	}

	int size() {
		return root->c;
	}

	Treap() {
		srand(time(0));
		root = nullptr;
	}
};

template <typename T>
void setSup(TreapNode<T>* t, int id, T value) {
	int l = (t->left == nullptr ? 0 : t->left->c);
	if (l == id) {
		t->value = value;
		return;
	}
	if (l > id) {
		setSup(t->left, id, value);
	} else {
		setSup(t->right, id - l - 1, value);
	}
	return;
}

template<typename T>
int findSup(TreapNode<T>* t, T value) {
	if (t == nullptr) return -1e9;
	if (value == t->value) {
		return t->c;
	}
	if (value > t->value) {
		return t->c + findSup(t->right, value);
	} else {
		return findSup(t->left, value);
	}
}

template <typename T>
T getSup(TreapNode<T>* t, int id) {
	int l = (t->left == nullptr ? 0 : t->left->c);
	if (l == id) {
		return t->value;
	}
	if (l > id) {
		return getSup(t->left, id);
	} else {
		return getSup(t->right, id - l - 1);
	}
}

template <typename T>
pair<TreapNode<T>*, TreapNode<T>*> split(TreapNode<T>* t, int k) {
	if (t == nullptr) {
		return { nullptr, nullptr };
	}

	int l = (t->left == nullptr ? 0 : t->left->c);
	if (l >= k) {
		pair<TreapNode<T>*, TreapNode<T>*> p = split(t->left, k);
		t->left = p.second;
		t->update();
		return { p.first, t };
	} else {
		pair<TreapNode<T>*, TreapNode<T>*> p = split(t->right, k - l - 1);
		t->right = p.first;
		t->update();
		return { t, p.second };
	}
}

template <typename T>
TreapNode<T>* merge(TreapNode<T>* t1, TreapNode<T>* t2) {
	if (t2 == nullptr) {
		return t1;
	}
	if (t1 == nullptr) {
		return t2;
	}

	if (t1->y > t2->y) {
		t1->right = merge(t1->right, t2);
		t1->update();
		return t1;
	} else {
		t2->left = merge(t1, t2->left);
		t2->update();
		return t2;
	}
}

ll gcd(ll a, ll b) {
	return (b == 0 ? a : gcd(b, a % b));
}

ll lmc(ll a, ll b) {
	return a * b / gcd(a, b);
}

bool isPrime(ll n) {
	if (n == 1) return false;
	for (ll i = 2; i * i <= n; i++) {
		if (n % i == 0) return false;
	}
	return true;
}

vector<ll> getDels(ll n) {
	vector<ll> ans;
	for (ll i = 1; i * i <= n; i++) {
		if (n % i == 0) {
			ans.push_back(i);
			if (i * i != n) {
				ans.push_back(n / i);
			}
		}
	}
	sort(ans.begin(), ans.end());
	return ans;
}

ll binaryPow(ll n, ll st, ll module) {
	if (st == 0) {
		return 1;
	}
	if (st % 2 == 0) {
		ll ans = binaryPow(n, st / 2, module);
		return (ans * ans) % module;
	} else {
		return (binaryPow(n, st - 1, module) * n % module);
	}
}


int getSet(vector<int>& tree, int v) {
	if (tree[v] == v) {
		return v;
	}
	tree[v] = getSet(tree, tree[v]);
	return tree[v];
}

void unionSet(vector<int>& tree, int v, int u) {
	v = getSet(tree, v);
	u = getSet(tree, u);
	if (v != u) {
		tree[min(u, v)] = max(u, v);
	}
}

vector<int> zFunction(string& str) {
	int n = str.size();
	vector<int> z(n, 0);
	int l = 0;
	int r = 0;
	for (int i = 1; i < n; i++) {
		if (i <= r) z[i] = min(z[i - l], r - i + 1);

		while (i + z[i] < n && str[i + z[i]] == str[z[i]]) z[i]++;

		if (i + z[i] - 1 > r) {
			r = i + z[i] - 1;
			l = i;
		}
	}
	return z;
}

vector<ll> getPrimesToN(int n) {
	vector<bool> p(n + 1, true);
	p[0] = false;
	p[1] = false;
	for (ll i = 2; i * i <= n; i++) {
		if (p[i]) {
			for (ll j = i * i; j <= n; j += i) {
				p[j] = false;
			}
		}
	}
	vector<ll> primes;
	for (int i = 0; i <= n; i++) {
		if (p[i]) {
			primes.push_back(i);
		}
	}
	return primes;
}

vector<ll> getFactorization(ll n) {
	vector<ll> ans;
	for (ll i = 2; i * i <= n; i++) {
		while (n % i == 0) {
			ans.push_back(i);
			n /= i;
		}
	}
	if (n != 1) {
		ans.push_back(n);
	}
	return ans;
}


template <typename T1, typename T2>
ostream& operator<<(ostream& out, pair<T1, T2> const& p) {
	out << p.first << " " << p.second;
	return out;
}



template <typename T>
ostream& operator<<(ostream& out, vector<T> const& vec) {
	for (int i = 0; i < vec.size(); i++) {
		out << vec[i] << " ";
	}
	return out;
}


pair<int, int> dfs(vector<vector<int>>& g, int v, int p, int& ans) {
	int tmp = -1;

	int mx1 = -100;
	int mx2 = -100;
	for (int u : g[v]) {
		if (u != p) {
			auto res = dfs(g, u, v, ans);
			int z = max(res.first, res.second);
			tmp = max(tmp, z);
			ans = max(ans, res.first + (int) g[v].size() - 2);
			ans = max(ans, res.second + (int) g[v].size() - 1);

			if (mx1 < z) {
				mx2 = mx1;
				mx1 = z;
			} else if (z > mx2) {
				mx2 = z;
			}
		}
	}
	ans = max(ans, mx1 + mx2 - 1);
	
	return { (int)g[v].size(), tmp };
}



int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	setlocale(LC_ALL, "RU");

	int t;
	t = 1;

	cin >> t;

	for (; t > 0; t--) {
		int n;
		cin >> n;
		vector<vector<int>> g(n);
		for (int i = 0; i < n - 1; i++) {
			int  v, u;
			cin >> v >> u;
			v--;
			u--;
			g[v].push_back(u);
			g[u].push_back(v);
		}
		int ans = 0;
		dfs(g, 0, -1, ans);

		cout << ans << endl;
	}
	return 0;
}