#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
#define maxN 100007
#define oo 1000000000000000000
vector<int>adj[maxN];
long long val[maxN];
bool vis[maxN] = {false};
int sta[maxN] = {0};
int pre[maxN] = {0};
int hate[maxN] = {0};
bool hateThemself[maxN] = {false};
int n;
int curStart, curEnd;
int curLineStart;
long long dp[maxN][2] = {0};
void readData()
{
int v;
cin >> n;
for(int i = 1; i <= n; i++)
{
sta[i] = 0;
adj[i].clear();
pre[i] = 0;
vis[i] = false;
hateThemself[i] = false;
dp[i][0] = 0;
dp[i][1] = 0;
}
for(int i = 1; i <= n; i++)
{
cin >> val[i];
cin >> hate[i];
if(i == hate[i])
hateThemself[i] = true;
}
for(int i = 1; i <= n; i++)
{
if(hate[i] == -1)
continue;
if(hateThemself[i])
{
sta[i] = 2;
continue;
}
if(hateThemself[hate[i]])
continue;
adj[i].push_back(hate[i]);
adj[hate[i]].push_back(i);
}
for(int i = 1; i <= n; i++)
{
sort(adj[i].begin(), adj[i].end());
auto it = unique(adj[i].begin(), adj[i].end());
adj[i].erase(it, adj[i].end());
}
}
bool dfsForLoop(int u, int p)
{
if(adj[u].size() <= 1)
curLineStart = u;
sta[u] = 1;
for(int v: adj[u])
{
if(v == p) continue;
if(sta[v] == 0)
{
pre[v] = u;
if(dfsForLoop(v, u))
return true;
}
else if(sta[v] == 1)
{
curStart = v;
curEnd = u;
return true;
}
}
sta[u] = 2;
return false;
}
void dfsVal(int u, int p)
{
dp[u][1] = 0;
dp[u][0] = 0;
for(int v: adj[u])
{
if(v == p || vis[v]) continue;
dfsVal(v, u);
dp[u][1] += dp[v][0];
dp[u][0] += max(dp[v][0], dp[v][1]);
}
dp[u][1] += val[u];
}
vector<long long> newArray(vector<long long>curArr)
{
long long base = 0;
vector<long long>ans;
for(int i = 0; i < curArr.size(); i++)
vis[curArr[i]] = true;
for(int i = 0; i < curArr.size(); i++)
dfsVal(curArr[i], -1);
for(int i = 0; i < curArr.size(); i++)
{
ans.push_back(dp[curArr[i]][1] - dp[curArr[i]][0]);
base += dp[curArr[i]][0];
}
ans.push_back(base);
for(int i = 0; i < curArr.size(); i++)
vis[curArr[i]] = false;
return ans;
}
long long solveNoCycle()
{
dfsVal(curLineStart, -1);
return max(dp[curLineStart][0], dp[curLineStart][1]);
}
long long solveCycle()
{
vector<long long>cycle;
cycle.push_back(curStart);
int count = 0;
for(int v = curEnd; v != curStart; v = pre[v])
{
cycle.push_back(v);
count++;
if(count > n) break; // prevent infinite loop
}
cycle = newArray(cycle);
long long base = cycle.back();
cycle.pop_back();
long long maxAns = -oo;
long long maxVal1 = 0, maxVal2 = 0;
for(int i = 1; i < cycle.size(); i++)
{
long long cur = max(maxVal1, maxVal2+cycle[i]);
maxVal2 = maxVal1;
maxVal1 = cur;
}
maxAns = max(maxAns, maxVal1);
maxVal1 = 0;
maxVal2 = 0;
for(int i = 0; i < cycle.size()-1; i++)
{
long long cur = max(maxVal1, maxVal2+cycle[i]);
maxVal2 = maxVal1;
maxVal1 = cur;
}
maxAns = max(maxAns, maxVal1);
return maxAns+base;
}
long long solveFor(int u)
{
if(!dfsForLoop(u, -1))
{
return solveNoCycle();
}
return solveCycle();
}
long long solve()
{
long long ans = 0;
for(int i = 1; i <= n; i++)
{
if(hateThemself[i])
continue;
if(sta[i] == 0)
ans += solveFor(i);
}
return ans;
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
int t;
cin >> t;
while(t--)
{
readData();
cout << solve() << "\n";
}
return 0;
}