// clang-format off
	#include <bits/stdc++.h>
	using namespace std; using ll = long long; using uint = unsigned int;
	#define SFINAE(x, ...)	template <class, class = void> struct x : false_type {}; template <class T> struct x<T, void_t<__VA_ARGS__>> : true_type {};
	SFINAE(DefaultIO, decltype(cout << declval<T &>()))
	SFINAE(IsTuple, typename tuple_size<T>::type)
	SFINAE(Iterable, decltype(begin(declval<T>())))
	template <class T> constexpr char Space(const T &) { return (Iterable<T>::value or IsTuple<T>::value) ? '\n' : ' '; }
	template <auto &os> struct Writer {
		template <class T> void Impl(T const &t) const {
			if constexpr (DefaultIO<T>::value) os << t;
			else if constexpr (Iterable<T>::value) { int i = 0; for (auto &&x : t) ((i++) ? (os << Space(x), Impl(x)) : Impl(x)); }
			else if constexpr (IsTuple<T>::value) apply([this](auto const &... args) { int i = 0; (((i++) ? (os << ' ', Impl(args)) : Impl(args)), ...);}, t);
			else static_assert(IsTuple<T>::value, "No matching type for print");
		}
		template <class F, class... Ts> auto &operator()(F const &f, Ts const &... ts) const { return Impl(f), ((os << ' ', Impl(ts)), ...), os << '\n', *this; }
	};
	template <auto &is> struct Reader {
		template <class T> auto& operator()(T &t) const {
			if constexpr (DefaultIO<T>::value) is >> t;
			else if constexpr (Iterable<T>::value) for (auto &x : t) (*this)(x);
			else if constexpr (IsTuple<T>::value) apply([this](auto &... args) { ((*this)(args), ...); }, t);
			else static_assert(IsTuple<T>::value, "No matching type for read");
			return *this;
		}
		template <class T> auto operator[](T t) const { return (*this)(t), t; }
	};
	#ifdef NARUT_LOCAL
	#define Debug(...) cerr << "\033[0;31m", Writer<cerr>{}(__VA_ARGS__), cerr << "\033[0m\n"
	#else
	#define Debug(...) 0
	#endif
	[[maybe_unused]] constexpr Reader<cin> Cin; [[maybe_unused]] constexpr Writer<cout> Cout;
	#define FOR(i, j, n) for (int i = int(j); i < int(n); ++i)
	#define ROF(i, j, n) for (int i = int(n) - 1; i >= int(j); --i)
// clang-format on

// auto uf = DSU(n);
struct DSU {
	DSU() = default;
	DSU(uint n) : n_sets(n), parent(n), sz(n, 1) { iota(parent.begin(), parent.end(), 0); }
	int Find(int i) const {
		while (i != parent[i]) i = parent[i] = parent[parent[i]];
		return i;
	}
	int operator[](int i) const { return Find(i); }
	int Union(int i, int j) {
		auto ir = Find(i), jr = Find(j);
		if (ir == jr) return ir;
		if (sz[ir] < sz[jr]) swap(ir, jr);
		parent[jr] = ir;
		sz[ir] += sz[jr];
		--n_sets;
		return ir;
	}
	void MakeSet() {
		parent.push_back(parent.size());
		sz.push_back(1);
		++n_sets;
	}
	uint Size() const { return sz.size(); }
	uint SizeOf(int i) const { return sz[Find(i)]; }
	uint NumSets() const { return n_sets; }

	auto ToVector() const {
		vector<int> res(Size());
		for (uint i = 0; i < Size(); ++i) res[i] = Find(i);
		return res;
	}

  private:
	uint n_sets = 0;
	mutable vector<int> parent;
	vector<int> sz;
};

auto Main() {
	const int n = Cin[0];
	using D = vector<array<int, 2>>;
	D good, bad;
	ll base = 0;
	FOR(ni, 0, n) {
		int k = Cin[0], l = Cin[0], r = Cin[0];
		if (l > r) {
			good.push_back({l - r, k});
			base += r;
		} else {
			bad.push_back({r - l, n - k});
			base += l;
		}
	}
	auto const Do = [](D &d) {
		sort(rbegin(d), rend(d));
		const int sz = d.size();
		DSU uf(sz+1);
		vector<int> ix(sz+1);
		iota(begin(ix), end(ix), 0);

		ll ans = 0;
		for (auto [x, k] : d) {
			k = min(k, sz);
			auto u = ix[uf.Find(k)];
			if (u == 0) continue;
			ans += x;
			auto v = uf.Find(u-1);
			ix[uf.Union(u, v)] = ix[v];
		}
		return ans;
	};
	cout << base + Do(good) + Do(bad) << '\n';
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout << fixed << setprecision(10);
#ifdef NARUT_LOCAL
	assert(freopen("io/test.in", "r", stdin));
	cin.exceptions(cin.badbit | cin.failbit);
	cerr << fixed << setprecision(10);
#endif

	int n_cases;
	for (cin >> n_cases; n_cases > 0; n_cases--) {
		Main();
	}
}


Measured memory_bytes: 6128