#include <bits/stdc++.h>
using namespace std;
class SemiRing {
public:
SemiRing(int el=0):
el_(el)
{ }
SemiRing& operator +=(const SemiRing& rhs) {
if (el_ < rhs.el_) {
el_ = rhs.el_;
}
return *this;
}
SemiRing& operator *=(const SemiRing& rhs) {
if (el_ == inf or rhs.el_ == inf) {
el_ = inf;
} else {
el_ += rhs.el_;
}
return *this;
}
SemiRing operator +(const SemiRing& rhs) const { return SemiRing(*this) += rhs; }
SemiRing operator *(const SemiRing& rhs) const { return SemiRing(*this) *= rhs; }
int value() const { return el_; }
static SemiRing ONE() { return SemiRing(1); }
static SemiRing INF() { return SemiRing(inf); }
private:
static constexpr int inf = -0x3f3f3f3f;
int el_;
};
class Mat22 {
public:
Mat22(SemiRing x00=0, SemiRing x01=SemiRing::INF(),
SemiRing x10=SemiRing::INF(), SemiRing x11=0):
a00(x00),
a01(x01),
a10(x10),
a11(x11)
{ }
Mat22 operator *=(const Mat22& rhs) {
return *this = *this * rhs;
}
Mat22 operator *(const Mat22& rhs) const {
return Mat22(
a00 * rhs.a00 + a01 * rhs.a10,
a00 * rhs.a01 + a01 * rhs.a11,
a10 * rhs.a00 + a11 * rhs.a10,
a10 * rhs.a01 + a11 * rhs.a11
);
}
int Get00() const { return a00.value(); }
int Get01() const { return a01.value(); }
int Get10() const { return a10.value(); }
int Get11() const { return a11.value(); }
private:
SemiRing a00, a01, a10, a11;
};
class LCTree {
public:
LCTree(int n=0):
parent(n + 1),
path_parent(n + 1),
first(n + 1),
last(n + 1),
value(n + 1),
cvalue(n + 1),
child(n + 1),
light_dp(n + 1),
num_nodes(0)
{ }
void AddPoint(const int parent) {
if (parent != 0) {
Access(parent);
Splay(parent, 0);
light_dp[parent].first *= SemiRing::ONE();
value[parent] = LightMatrix(parent);
Update(parent);
}
++num_nodes;
path_parent[num_nodes] = parent;
value[num_nodes] = HeavyMatrix(num_nodes);
Update(num_nodes); Access(num_nodes); Splay(num_nodes,0);
}
int Query() {
Access(1);
return num_nodes - HeavyMatrix(1).Get01();
}
protected:
Mat22 HeavyMatrix(const int node) const {
return Mat22(SemiRing::INF(),
light_dp[node].first + light_dp[node].second * SemiRing::ONE(),
SemiRing::INF(),
light_dp[node].first);
}
Mat22 LightMatrix(const int node) const {
return Mat22(light_dp[node].first,
light_dp[node].second * SemiRing::ONE(),
light_dp[node].first,
SemiRing::INF());
}
private:
bool IsRightSon(const int node) const {
return child[parent[node]][1] == node;
}
void Update(const int node) {
if (child[node][0]) {
first[node] = first[child[node][0]];
cvalue[node] = cvalue[child[node][0]] * value[node];
} else {
first[node] = node;
cvalue[node] = value[node];
}
if (child[node][1] != 0) {
last[node] = last[child[node][1]];
cvalue[node] = cvalue[node] * cvalue[child[node][1]];
} else {
last[node] = node;
}
}
void Rotate(const int node) {
const int par = parent[node];
const bool where = IsRightSon(node);
if (parent[par] != 0) {
child[parent[par]][IsRightSon(par)] = node;
}
if (child[node][where ^ 1] != 0) {
parent[child[node][where ^ 1]] = par;
}
child[par][where] = child[node][where ^ 1];
child[node][where ^ 1] = par;
parent[node] = parent[par];
parent[par] = node;
if (path_parent[par] != 0) {
path_parent[node] = path_parent[par];
path_parent[par] = 0;
}
Update(par);
}
void Splay(int from, const int to) {
while (parent[from] != to) {
if (parent[parent[from]] != to) {
Rotate(IsRightSon(from) != IsRightSon(parent[from]) ? from : parent[from]);
}
Rotate(from);
}
Update(from);
}
template <bool is_heavy>
int Get(const int node, int to) {
int foo;
to = first[to]; Splay(to, is_heavy ? 0 : node);
foo = last[to]; Splay(foo, is_heavy ? 0 : node);
auto r = cvalue[child[foo][0]] * HeavyMatrix(foo);
light_dp[node].first *= is_heavy ? -r.Get01() : r.Get01();
light_dp[node].second *= is_heavy ? -r.Get11() : r.Get11();
value[node] = LightMatrix(node);
Splay(to, is_heavy ? 0 : node);
Update(node);
return to;
}
int Access(int node) {
int to = 0;
while (node != 0) {
Splay(node, 0);
if (child[node][1] != 0) {
Get<false>(node, child[node][1]);
parent[child[node][1]] = 0;
path_parent[child[node][1]] = node;
}
if (to != 0) {
to = Get<true>(node, to);
parent[to] = node;
path_parent[to] = 0;
}
child[node][1] = to;
Update(node);
to = node;
node = path_parent[node];
}
return to;
}
vector<int> parent, path_parent;
vector<int> first, last;
vector<Mat22> value, cvalue;
vector<array<int, 2>> child;
vector<pair<SemiRing, SemiRing>> light_dp;
int num_nodes;
};
int BoatSize(int num_nodes, int mvc) {
if (num_nodes <= 3) {
return 2;
}
if (mvc == 1) {
return 3;
}
return 1 + mvc;
}
int main() {
cin.tie(0);
ios_base::sync_with_stdio(false);
int num_tests; cin >> num_tests;
assert(1 <= num_tests && num_tests <= 200000);
int sum_n = 0;
while (num_tests--> 0) {
int n; cin >> n;
assert(2 <= n);
sum_n += n;
LCTree tree(n); tree.AddPoint(0);
for (int i = 2; i <= n; ++i) {
int parent; cin >> parent;
assert(1 <= parent && parent <= i);
tree.AddPoint(parent);
cout << BoatSize(i, tree.Query()) << " \n"[i == n];
}
}
assert(sum_n <= 1000000);
return 0;
}