#include <bits/stdc++.h>
#define ll long long
#define ls rt<<1
#define rs rt<<1|1
using namespace std;
const int maxn = 1e5;
struct N{
ll lm,rm,mm,sum;
}t[maxn<<2];
void push(int rt){
t[rt].sum = t[ls].sum + t[rs].sum;
t[rt].lm = max(t[ls].lm,t[ls].sum+t[rs].lm);
t[rt].rm = max(t[rs].rm,t[rs].sum+t[ls].rm);
t[rt].mm = max(max(t[ls].mm,t[rs].mm),t[ls].rm+t[rs].lm);
}
void build(int rt,int l,int r){
t[rt].lm = t[rt].rm = t[rt].mm = t[rt].sum = 0;
if(l==r)return ;
int mid = l+r>>1;
build(ls,l,mid);
build(rs,mid+1,r);
push(rt);
}
void update(int rt,int l,int r,int pos,ll val){
if(l==r){
t[rt].sum+=val;
t[rt].lm = t[rt].rm = t[rt].mm = t[rt].sum;
return;
}
int mid = l+r>>1;
if(pos<=mid) update(ls,l,mid,pos,val);
else update(rs,mid+1,r,pos,val);
push(rt);
}
//以上求最大子段和
struct P{
int x,y;
ll val;
}p[maxn];
bool cmp(P a,P b){
return a.y == b.y?a.x<b.x:a.y>b.y;
}
vector<int> vx,vy;
int getidx(int x){
return lower_bound(vx.begin(),vx.end(),x) - vx.begin()+1;
}
int getidy(int y){
return lower_bound(vy.begin(),vy.end(),y) - vy.begin()+1;
}
int main()
{
int _,n,len;
for(scanf("%d",&_);_;_--){
vx.clear(); vy.clear();
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d %d %lld",&p[i].x,&p[i].y,&p[i].val);
vx.push_back(p[i].x);
vy.push_back(p[i].y);
}
sort(vx.begin(),vx.end()); vx.erase(unique(vx.begin(),vx.end()),vx.end()); len = vx.size();
sort(vy.begin(),vy.end()); vy.erase(unique(vy.begin(),vy.end()),vy.end());
for(int i=1;i<=n;i++){
p[i].x = getidx(p[i].x);
p[i].y = getidy(p[i].y);
}
sort(p+1,p+n+1,cmp);
ll ans = -1e18,last = -1;
for(int i=1;i<=n;i++){//上边界
if(p[i].y == last)continue;
build(1,1,len);
int k;
for(int j=i;j<=n;j=k){
for(k=j;k<=n&&p[k].y==p[j].y;k++){
update(1,1,len,p[k].x,p[k].val);
}
ans = max(ans,t[1].mm);
}
last = p[i].y;
}
printf("%lld\n",ans);
}
return 0;
}