// Tetris.java


import java.util.*;
import java.io.*;

    // The upper contour is maintained as a linked list of points ordered
    // left to right. Dropping a rectangle onto the contour involves splicing
    // the rectangle's top and side edges into the list.
    // An alternative (simpler) approach maintains a buffer buf[0..1000]
    // of height values from which the upper contour can be reconstructed.
    // The height buffer is initialized to all zeros, and then updated
    // for each rectangle in turn.

public class Tetris {


    public static void main(String[] args) {
        try {
            BufferedReader in = new BufferedReader( new InputStreamReader(System.in) );
            String s = in.readLine();
            int m = Integer.parseInt(s);
            String res = "";
            for (int i = 0; i < m; i++)
                res += solveProblemInstance(in) + "\n";
            System.out.print(res);
        } catch (IOException e) {
            System.out.println("i/o exception on input file");
            System.exit(1);
        }
    }
    
    
    static String solveProblemInstance(BufferedReader in) {
        Contour contour = new Contour();
        Vector rectangles = getInput(in);
        Iterator iter = rectangles.iterator();
        while (iter.hasNext()) {
            Rectangle r = (Rectangle)iter.next();
            contour.addRectangle(r.minx, r.maxx, r.height);
        }
        return contour.points();
    }
    

    
    static Vector getInput(BufferedReader in) {
        Vector res = new Vector();
        try {
            String s = in.readLine();
            int n = Integer.parseInt(s);
            for (int i = 0; i < n; i++) {
                s = in.readLine();
                StringTokenizer t = new StringTokenizer(s);
                int xmin = Integer.parseInt(t.nextToken());
                int xmax = Integer.parseInt(t.nextToken());
                int height = Integer.parseInt(t.nextToken());
                res.add( new Rectangle(xmin, xmax, height) );
            }
        } catch (IOException e) {
            System.out.println("i/o exception on input file");
            System.exit(1);
        }
        return res;
    }
}
    

class Contour {

    List list;
    
    public static final int DefaultMinx = 0, DefaultMaxx = 1000;
    
    public Contour(int minx, int maxx) {
        list = new LinkedList();
        list.add( new PointI(minx, 0) );
        list.add( new PointI(maxx, 0) );
    }
    
    public Contour() {
        this(DefaultMinx, DefaultMaxx);
    }

    
    public int maxHeight(int minx, int maxx) {
        ListIterator iter = list.listIterator( indexOfSuccessor(minx) );
        PointI p = (PointI)iter.next();
        int cur = p.getY();
        int lastIndex = indexOfSuccessor(maxx);
        while (iter.nextIndex() < lastIndex) {
            p = (PointI)iter.next();
            if (cur < p.getY())
                cur = p.getY();
        }
        return cur;
    }
    
    public void addRectangle(int minx, int maxx, int height) {
        // height of new rectangle after it is added to contour
        int combinedHeight = height + maxHeight(minx, maxx);
        // remove vertices of countour covered by the new rectangle
        int firstIndex = indexOfSuccessor(minx);
        ListIterator iter = list.listIterator( firstIndex );
        int lastIndex = indexOfSuccessor(maxx);
        int nbrVerticesToRemove = lastIndex - firstIndex;
        for (int i = 0; i < nbrVerticesToRemove; i++) {
            iter.next();
            iter.remove();
        }

        // get vertices where new rectangle is to be spliced into
        PointI p = (PointI)iter.previous();
        iter.next();
        PointI q = (PointI)iter.next();
        iter.previous();
        
        // splice in new rectangle
        if (p.getX() < minx)
            iter.add( new PointI(minx, p.getY()) );
        if (p.getY() != combinedHeight)  // avoid redundant points
            iter.add( new PointI(minx, combinedHeight) );
        if (q.getY() != combinedHeight)
            iter.add( new PointI(maxx, combinedHeight) );
        if (q.getX() > maxx)
            iter.add( new PointI(maxx, q.getY()) );
        removeIfRedundant(p);
        removeIfRedundant(q);

    }


    public void removeIfRedundant(PointI p) {
        int indx = list.indexOf(p);
        if ((indx == 0) || (indx == list.size()-1))
            return;
        PointI a = (PointI)list.get(indx-1);
        PointI b = (PointI)list.get(indx+1);
        if ((a.getY() == p.getY()) && (p.getY() == b.getY()))
            list.remove(indx);
    }
        


    
    // note: if two points of current contour lie at x, the index of the second
    // point is returned
    public int indexOfSuccessor(int x) {
        ListIterator iter = list.listIterator( 0 );
        while (true) {
            PointI p = (PointI)iter.next();
            if (x < p.getX())
                return iter.previousIndex();
            else if (x == p.getX())
                return (iter.hasNext() ? iter.nextIndex() : iter.previousIndex());
        }
    }

    
    public int indexOfPredecessor(int x) {
        return indexOfSuccessor(x) - 1;
    }

    public String points() {
        ListIterator iter = list.listIterator(0);
        String res = "";
        while (iter.hasNext()) {
            PointI q = (PointI)iter.next();
            res += q + " ";
        }
        return res;
    }   


    public String toString() {
        ListIterator iter = list.listIterator(0);
        PointI p = (PointI)iter.next(), q;
        String res = "";
        while (iter.hasNext()) {
            q = (PointI)iter.next();
            res += p.distance(q) + " ";
            p = q;
        }
        return res;
    }   
        

}



class PointI {
    int x, y;

    public PointI(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return this.x;  
    }

    public int getY() {
        return this.y;
    }

    // assumes this and p share the same x or y coordinate
    public int distance(PointI p) {
        if (getX() == p.getX())
            return Math.abs(getY() - p.getY());
        else
            return Math.abs(getX() - p.getX());
    }


    public String toString() {
        String res = "(" + x + "," + y + ")";
        return res;
    }

    public boolean equals(Object obj) {
        if (obj instanceof PointI) {
            PointI q = (PointI)obj;
            return (this.x==q.getX()) && (this.y==q.getY());
        }
        return false;
    }
}


class Rectangle {

    public int minx, maxx, height;
    
    public Rectangle(int minx, int maxx, int height) {
        this.minx = minx;
        this.maxx = maxx;
        this.height = height;
    }
}
