#![allow(unused, non_snake_case, dead_code, non_upper_case_globals)]
use {
    proconio::{marker::*, *},
    std::{cmp::*, collections::*, mem::*},
};

#[fastout]
fn main() {
    input! {t:usize}
    for _ in 0..t {
        input! {n:usize,
        klr:[(usize,i64,i64);n]}
        let mut left = Vec::new();
        let mut right = Vec::new();
        let mut same_sum = 0;
        for &(k, l, r) in klr.iter() {
            if l > r {
                left.push((k, l, r));
            } else if r > l {
                right.push((n - k, r, l));
            } else {
                same_sum += l;
            }
        }
        println!("{}", same_sum + calc(&mut left) + calc(&mut right));
    }
}
fn calc(camels: &mut Vec<(usize, i64, i64)>) -> i64 {
    camels.sort_by_key(|&x| x.1 - x.2);
    let n = camels.len();
    let mut ret = 0;
    let mut not_used = Vec::new();
    for i in 0..=n {
        not_used.push(i);
    }
    for &(k, l, r) in camels.iter() {
        // k 未満の最小のインデックスで未使用のものを探す
        let bef = not_used.upper_bound(&k) - 1;
        if bef == 0 {
            ret += r;
        } else {
            not_used.remove(bef);
            ret += l;
        }
    }

    return ret;
}
pub trait BinarySearch<T> {
    fn lower_bound_by<F: Fn(&T) -> bool>(&self, f: F) -> usize;
    fn lower_bound(&self, x: &T) -> usize;
    fn upper_bound(&self, x: &T) -> usize;
}
impl<T: Ord> BinarySearch<T> for [T] {
    fn lower_bound_by<F: Fn(&T) -> bool>(&self, f: F) -> usize {
        let mut ng = -1;
        let mut ok = self.len() as i64;
        while (ok as i32 - ng as i32).abs() > 1 {
            let mid = (ok + ng) / 2;
            if f(&self[mid as usize]) {
                ok = mid;
            } else {
                ng = mid;
            }
        }
        ok as usize
    }
    fn lower_bound(&self, x: &T) -> usize {
        self.lower_bound_by(|y| y >= x)
    }
    fn upper_bound(&self, x: &T) -> usize {
        self.lower_bound_by(|y| y > x)
    }
}
