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

const int size=1<<16;
int a[size];

struct node{
	int sum;
	
	node split(node& l, node& r){};
	
	node merge(node& l, node& r){
		sum = l.sum + r.sum;
	}
	
	node setVal(int val){
		sum = val;
	}
};

node T[size<<1],lazy[size<<1];

void init(int Node, int i, int j){
	if(i==j){
		T[Node].setVal(a[i]);//for leaf nodes
		return;
	}
	
	int mid = (i+j)>>1;
	
	init(Node*2,i,mid);
	init(Node*2+1,mid+1,j);
	
	T[Node].merge(T[Node*2],T[Node*2+1]);
}

void update(int Node, int i, int j, int x,int y, int val){
	
	if(lazy[Node].sum!=0){
		// This node needs to be updated
		
		T[Node].setVal(T[Node].sum + lazy[Node].sum);				// update it
		
		if(i!=j){
			lazy[2*Node].setVal(lazy[2*Node].sum + lazy[Node].sum); 	// Mark child as lazy
			lazy[2*Node+1].setVal(lazy[2*Node+1].sum + lazy[Node].sum); // Mark child as lazy
		}
		
		lazy[Node].sum=0;									// reset
	}
	
	if(i>y||j<x || i>j)	return;					/// doesnot lie within the range
	
	if(i>=x&&j<=y){								// lie within the range x,y
		
		T[Node].setVal(T[Node].sum + val);
		
		if(i!=j){
			lazy[2*Node].setVal(lazy[2*Node].sum + val);
			lazy[2*Node+1].setVal(lazy[2*Node+1].sum + val);
		}
		
		return;
	}
	
	
	
	int mid=(i+j)>>1;
	
	update(2*Node,i,mid,x,y,val);
	update(2*Node+1,mid+1,j,x,y,val);

	T[Node].merge(T[2*Node],T[2*Node+1]);
}

void range_query(node& resultNode, int Node, int i, int j, int x, int y){
	
	if(i>j || i>y || j<x) {resultNode.sum=0;return;}
	
	if(lazy[Node].sum!=0){
		// This node needs to be updated
		
		T[Node].setVal(T[Node].sum + lazy[Node].sum);				// update it
		
		if(i!=j){
			lazy[2*Node].setVal(lazy[2*Node].sum + lazy[Node].sum); 	// Mark child as lazy
			lazy[2*Node+1].setVal(lazy[2*Node+1].sum + lazy[Node].sum); // Mark child as lazy
		}
		
		lazy[Node].sum=0;									// reset
	}
	
	
	if(i>=x&&j<=y){
		resultNode=T[Node];
		return;
	}
	
	int mid=(i+j)>>1;
	
	if(y<=mid){//if range completely lies in the left part
		range_query(resultNode,Node*2,i,mid,x,y);
	}
	else if(x>mid){//if range completely lies in the right part
		range_query(resultNode,Node*2+1,mid+1,j,x,y);
	}
	else{//lies partly in the range
		node left, right;
		range_query(left,Node*2,i,mid,x,y);
		//keep the rightmost boundary fixed and find the left index
		// as it lies partly in both range so mid will be same 
		// only we have to find the left part
		range_query(right,Node*2+1,mid+1,j,x,y);
		// same condition for right node mid+1 will be fixed
		
		resultNode.merge(left,right);
	}
}



int main() {
	int i,n,m,x,y,t;
	node res;
	scanf("%d",&t);
	
	while(t--){
		scanf("%d %d",&n,&m);
		
		for(i=0;i<n;i++){
			a[i]=0;
		}
	
		init(1,0,n-1);
		
		while(m--){
			
			int op,x,y,val;
			scanf("%d",&op);
			
			if(op==1){
				scanf("%d %d",&x,&y);
				range_query(res,1,0,n-1,x-1,y-1);
				printf("%d\n",res.sum);
			}else{
				scanf("%d %d %d",&x,&y,&val);
				update(1, 0, n-1, x-1, y-1, val);
			}
		}
	}	
	
	return 0;
}