#include "bits/stdc++.h"
using namespace std;

// Inserted snippets: io, monoid, monoidapply, root, segtreelazy
#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
template<typename H> bool chmin(H& v1, const H v2) { if (v1 > v2) { v1 = v2; return true; } return false; }
template<typename H> bool chmax(H& v1, const H v2) { if (v1 < v2) { v1 = v2; return true; } return false; }
template<typename H> void read(H& head) { cin >> head; }
template<typename H, typename ...T> void read(H& head, T& ...tail) { cin >> head; read(tail...); }
template<typename H> void write(H head) { cout << head << '\n'; }
template<typename H, typename ...T> void write(H head, T ...tail) { cout << head << " "; write(tail...); }
template<typename ...T> void die(T ...tok) { write(tok...); exit(0); }
template<class T>
struct Monoid {
	T id;
	virtual T op(T a, T b) = 0;
};
template<typename T, typename U>
struct MonoidApply {
	virtual T op(U fn, T val) = 0;
};
template<typename T, typename MT, typename U, typename MU, typename F,
	typename = enable_if<is_base_of<Monoid<T>, MT>::value>,
	typename = enable_if<is_base_of<Monoid<U>, MU>::value>,
	typename = enable_if<is_base_of<MonoidApply<T, U>, F>::value>>
struct SegTreeLazy {
	MU monoid_u;
	MT monoid_t;
	F apply;
	int size;
	vector<T> tree;
	vector<U> lazy;

	SegTreeLazy(int size, MT monoid_t, MU monoid_u, F apply) : size(size), monoid_t(monoid_t), monoid_u(monoid_u), apply(apply) {
		tree = vector<T>(size * 4, monoid_t.id);
		lazy = vector<U>(size * 4, monoid_u.id);
	}

	SegTreeLazy(vector<T> vals, MT monoid_t, MU monoid_u, F apply) : size(vals.size()), monoid_t(monoid_t), monoid_u(monoid_u), apply(apply) {
		tree = vector<T>(size * 4, monoid_t.id);
		lazy = vector<U>(size * 4, monoid_u.id);
		_build(1, 0, vals.size() - 1, vals);
	}

	void _build(int id, int l, int r, const vector<T>& vals) {
		if (l == r) {
			tree[id] = vals[l];
			return;
		}
	
		int m = l + r >> 1;
		_build(id << 1, l, m, vals);
		_build(id << 1 | 1, m + 1, r, vals);
		tree[id] = monoid_t.op(tree[id << 1], tree[id << 1 | 1]);
	}
	
	void _pushdown(int id) {
		lazy[id << 1] = monoid_u.op(lazy[id], lazy[id << 1]);
		lazy[id << 1 | 1] = monoid_u.op(lazy[id], lazy[id << 1 | 1]);
		lazy[id] = monoid_u.id;
		_recalc(id);
	}

	T _query(int id, int l, int r, int tl, int tr) {
		if (l == tl && r == tr) {
			return apply.op(lazy[id], tree[id]);
		}

		int tm = tl + tr >> 1;
		_pushdown(id);
		if (r <= tm)
			return _query(id << 1, l, r, tl, tm);
		else if (l > tm)
			return _query(id << 1 | 1, l, r, tm + 1, tr);
		else
			return monoid_t.op(
					_query(id << 1, l, tm, tl, tm),
					_query(id << 1 | 1, tm + 1, r, tm + 1, tr));
	}

	T query(int l, int r) {
		return _query(1, l, r, 0, size - 1);
	}

	void _recalc(int id) {
		tree[id] = monoid_t.op(
				apply.op(lazy[id << 1], tree[id << 1]), 
				apply.op(lazy[id << 1 | 1], tree[id << 1 | 1]));
	}	

	void _update(int id, int l, int r, int tl, int tr, U val) {
		if (l == tl && r == tr) {
			lazy[id] = monoid_u.op(val, lazy[id]);
			return;
		}
		
		_pushdown(id);
		int tm = tl + tr >> 1;
		if (r <= tm)
			_update(id << 1, l, r, tl, tm, val);
		else if (l > tm)
			_update(id << 1 | 1, l, r, tm + 1, tr, val);
		else
			_update(id << 1, l, tm, tl, tm, val),
			_update(id << 1 | 1, tm + 1, r, tm + 1, tr, val);

		_recalc(id);
	}

	void update(int l, int r, U val) {
		_update(1, l, r, 0, size - 1, val);
	}
};
// End snippets

struct MT : public Monoid<int> {
	int id = 0;
	int op(int a, int b) {
		return max(a, b);
	}
};

struct MU : public Monoid<int> {
	int id = 0;
	int op(int a, int b) {
		return a + b;
	}
};

struct F : public MonoidApply<int, int> {
	int op(int f, int x) {
		return f + x;
	}
};

struct pairsort {
bool operator()(pair<int, int> a, pair<int, int> b) {
	return
		a.second != b.second ?
			a.second < b.second :
			a.first > b.first;
}
};

void solve() {
	int n; read(n);
	ll ans = 0;
	vector<pii> pl, pr;
	rep(i, 0, n) {
		int k, l, r; read(k, l, r);
		if (k == n) {
			ans += l;
		} else if (l > r) {
			pl.push_back({k, l - r});
			ans += r;
		} else if (l < r) {
			pr.push_back({n - k, r - l});
			ans += l;
		} else {
			ans += l; // no need decide
		}
	}

	//for (auto p : pl) write("L", p.first, p.second);
	//for (auto p : pr) write("R", p.first, p.second);

	priority_queue<pii, vector<pii>, pairsort> pq1, pq2;
	for (auto p : pl) pq1.push(p);
	for (auto p : pr) pq2.push(p);

	vector<int> initv(n + 1);
	rep(i, 0, n + 1) initv[i] = -i;

	SegTreeLazy<
		int, MT, int, MU, F> 
		seg1(initv, MT(), MU(), F()), 
		seg2(initv, MT(), MU(), F());
	vector<ll> gain1(n + 1), gain2(n + 1);

	rep(i, 1, n + 1) {
		gain1[i] = gain1[i - 1];
		while (!pq1.empty()) {
			pii x = pq1.top(); pq1.pop();
			seg1.update(x.first, n, 1);
			if (seg1.query(0, n) <= 0) {
				//for (int i = 0; i <= n; i++) cout << seg1.query(i, i) << " "; cout << endl;
				//write("New is", seg1.query(0, n), "absorb", x.first, x.second);
				gain1[i] += x.second;
				goto oklabel;
			}
			//write("Reject", x.first, x.second);
			seg1.update(x.first, n, -1);
		}
		rep(j, i + 1, n + 1)
			gain1[j] = gain1[i];
		break;
		oklabel: void(0);
	}

	rep(i, 1, n + 1) {
		gain2[i] = gain2[i - 1];
		while (!pq2.empty()) {
			pii x = pq2.top(); pq2.pop();
			seg2.update(x.first, n, 1);
			if (seg2.query(0, n) <= 0) {
				gain2[i] += x.second;
				goto next;
			}
			seg2.update(x.first, n, -1);
		}
		rep(j, i + 1, n + 1)
			gain2[j] = gain2[i];
		break;
next: void(0);
	}

	ll fans = 0;
	rep(i, 0, n + 1) {
		chmax(fans, ans + gain1[i] + gain2[n - i]);
	}
	write(fans);
}

int main() {
	//cin.tie(0)->sync_with_stdio(0);
	//cin.exceptions(cin.failbit);

	int t; read(t);
	rep(i, 0, t) solve();
}


Measured memory_bytes: 23700