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

fn main() {
    input! {t:usize}
    for _ in 0..t {
        solve();
    }
}
fn solve() {
    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 seg = SEG::<MAX>::new(n * 2);
    for i in 0..=n {
        seg.update(i, i as i64);
    }
    for &(k, l, r) in camels.iter() {
        // // k 未満の最小のインデックスで未使用のものを探す
        let ind = seg.query_range(0..k);
        if ind == -1 {
            ret += r;
        } else {
            ret += l;
            seg.update(ind as usize, -1);
        }
    }
    return ret;
}
pub trait Monoid {
    type T: Clone;
    fn id() -> Self::T;
    fn op(a: &Self::T, b: &Self::T) -> Self::T;
}
pub struct MAX;
impl Monoid for MAX {
    type T = i64;
    fn id() -> Self::T {
        -1
    }
    fn op(a: &Self::T, b: &Self::T) -> Self::T {
        max(*a, *b)
    }
}
/// Segment Tree
pub struct SEG<M: Monoid> {
    n: usize,
    buf: Vec<M::T>,
}
impl<M: Monoid> SEG<M> {
    pub fn new(n: usize) -> SEG<M> {
        SEG {
            n,
            buf: vec![M::id(); 2 * n],
        }
    }
    pub fn update(&mut self, k: usize, a: M::T) {
        let mut k = k + self.n;
        self.buf[k] = a;
        while k > 0 {
            k >>= 1;
            self.buf[k] = M::op(&self.buf[k << 1], &self.buf[(k << 1) | 1]);
        }
    }
    pub fn add(&mut self, k: usize, a: &M::T) {
        let mut k = k + self.n;
        self.buf[k] = M::op(&self.buf[k], a);
        while k > 0 {
            k >>= 1;
            self.buf[k] = M::op(&self.buf[k << 1], &self.buf[(k << 1) | 1]);
        }
    }
    pub fn get(&self, i: usize) -> M::T {
        self.query(i, i + 1)
    }
    pub fn query_range<R: std::ops::RangeBounds<usize>>(&self, range: R) -> M::T {
        let l = match range.start_bound() {
            std::ops::Bound::Excluded(&x) => {
                assert!(x > 0);
                x - 1
            }
            std::ops::Bound::Included(&x) => x,
            std::ops::Bound::Unbounded => 0,
        };
        let r = match range.end_bound() {
            std::ops::Bound::Excluded(&x) => x,
            std::ops::Bound::Included(&x) => (x + 1),
            std::ops::Bound::Unbounded => self.n,
        };
        self.query(l, r)
    }
    pub fn query(&self, l: usize, r: usize) -> M::T {
        let mut vl = M::id();
        let mut vr = M::id();
        let mut l = l + self.n;
        let mut r = r + self.n;
        while l < r {
            if l & 1 == 1 {
                vl = M::op(&vl, &self.buf[l]);
                l += 1;
            }
            if r & 1 == 1 {
                r -= 1;
                vr = M::op(&self.buf[r], &vr);
            }
            l >>= 1;
            r >>= 1;
        }
        M::op(&vl, &vr)
    }
}
