#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <algorithm>
#include <ctime>

using namespace std;

const int maxN = 601000;
//const int maxN = 200;

int t[4 * maxN];
int d[4 * maxN];

void build(vector<int>& a, int v, int tl, int tr) {
	if (tl == tr) {
		t[v] = a[tl];
		d[v] = 0;
	}
	else {
		int tm = (tl + tr) / 2;
		build(a, v * 2, tl, tm);
		build(a, v * 2 + 1, tm + 1, tr);
		t[v] = max(t[2 * v], t[2 * v + 1]);
		d[v] = 0;
	}
}

void push(int v, int l, int r) {
	if (d[v] != 0) {
		d[v * 2] += d[v];
		d[v * 2 + 1] += d[v];
		t[v * 2] += d[v];
		t[v * 2 + 1] += d[v];
		d[v] = 0;
	}
}

void update(int v, int tl, int tr, int l, int r, int add) {
	if (l > r)
		return;
	if (l == tl && tr == r) {
		d[v] += add;
		t[v] += add;
	}
	else {
		push(v, tl, tr);
		int tm = (tl + tr) / 2;
		update(v * 2, tl, tm, l, min(r, tm), add);
		update(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r, add);
		t[v] = max(t[v * 2], t[v * 2 + 1]);
	}
}

int get(int v, int tl, int tr, int l, int r) {
	if (l > r) {
		return -1;
	}
	if (l == tl && r == tr) {
		return t[v];
	}
	push(v, tl, tr);
	int mid = (tl + tr) / 2;
	if (l > mid) {
		return get(2 * v + 1, mid + 1, tr, l, r);
	}
	else if (r <= mid) {
		return get(2 * v, tl, mid, l, r);
	}
	else {
		return max(get(2 * v, tl, mid, l, mid), get(2 * v + 1, mid + 1, tr, mid + 1, r));
	}
}

vector<int> g[maxN];
vector<int> g2[maxN];

int tin[maxN];
int tout[maxN];
int used[maxN];
int curv[maxN];

pair<int, int> cseg[maxN];
int cnt;
int res = 1;

void dfs(int v) {
	tin[v] = cnt;
	used[v] = 1;
	++cnt;
	for (auto& to : g2[v]) {
		if (!used[to]) {
			dfs(to);
		}
	}
	tout[v] = cnt;
	++cnt;
	cseg[tout[v]] = make_pair(tin[v], tout[v]);
}

set<pair<int, int> > curseg;

void dfs2(int v, int n) {
	pair<int, int> cur = make_pair(tin[v], tout[v]);

	int segin = get(1, 0, 2 * n - 1, 0, tin[v] - 1);

	pair<int, int> erased = make_pair(-1, -1);

	if (segin > tout[v]) {
		erased = cseg[segin];
		curseg.erase(erased);
		
		int newv = -1;
		int diff = curv[erased.first] - newv;
		update(1, 0, 2 * n - 1, erased.first, erased.first, -diff);
		curv[erased.first] = -1;
	}

	int segin2 = get(1, 0, 2 * n - 1, tin[v] + 1, tout[v] - 1);
	if (segin2 == -1) {
		curseg.insert(cur);

		int newv = cur.second;
		int diff = cur.second - curv[cur.first];
		update(1, 0, 2 * n - 1, cur.first, cur.first, diff);
		curv[cur.first] = cur.second;
	}

	res = max(res, (int)curseg.size());

	for (auto& to : g[v]) {
		dfs2(to, n);
	}

	if (segin > tout[v]) {
		curseg.insert(erased);

		int newv = erased.second;
		int diff = erased.second - curv[erased.first];
		update(1, 0, 2 * n - 1, erased.first, erased.first, diff);
		curv[erased.first] = erased.second;
	}
	if (segin2 == -1) {
		curseg.erase(cur);

		int newv = -1;
		int diff = curv[cur.first] - newv;
		update(1, 0, 2 * n - 1, cur.first, cur.first, -diff);
		curv[cur.first] = -1;
	}
}

void solve(int tcase) {
	int n;
	cin >> n;

	for (int i = 0; i < n; ++i) {
		g[i].clear();
		g2[i].clear();
	}

	for (int i = 1; i < n; ++i) {
		int x;
		cin >> x;
		--x;
		g[x].push_back(i);
	}

	for (int i = 1; i < n; ++i) {
		int x;
		cin >> x;
		--x;
		g2[x].push_back(i);
	}

	cnt = 0;
	for (int i = 0; i < n; ++i) {
		used[i] = 0;
	}
	dfs(0);

	vector<int> a(2 * n, -1);
	for (int i = 0; i < 2 * n; ++i) {
		curv[i] = -1;
	}
	build(a, 1, 0, 2 * n - 1);

	curseg.clear();
	res = 1;
	dfs2(0, n);
	cout << res << "\n";
}

int main() {
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	ios_base::sync_with_stdio(false);
	cin.tie(0);

	int t;
	cin >> t;
	//t = 1;


	for (int tt = 0; tt < t; ++tt) {
		solve(tt + 1);
	}




	return 0;

}