#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
using namespace std;

int hhy=0;
struct nd{
	nd * c[2];
	nd * p;
	long long sm,lzy,pt,slp;
	long long lzy_pt;
	long long inc,prv;
	long long sm_inc;
	long long sm_len;
	bool rev;
	nd(nd * pa,long long pp,long long s,long long pv){
		c[0]=c[1]=NULL;
		prv=pv;
		p=pa;
		sm=1;
		lzy_pt=0;
		rev=false;
		lzy=0;
		
		pt=pp;
		slp=s;
		sm_len=pp-prv;
		inc=(pp-prv) * slp;
		sm_inc=inc;
	}
};
struct splay{
	nd * root;
	splay(){
		root=NULL;
	}
	long long num(nd * t){
		if(t==NULL)return 0;
		return t->sm;
	}
	long long leng(nd * t){
		if(t==NULL)return 0;
		return t->sm_len;
	}
	long long incc(nd * t){
		if(t==NULL)return 0;
		return t->sm_inc;
	}
	long long ty(nd * t){
		if(t->p==NULL)return -1;
		if(t->p->c[0]==t)return 0;
		return 1;
	}
	void push_down(nd * t){
		if(t->rev){
			swap(t->c[0],t->c[1]);
			if(t->c[0]!=NULL){
				t->c[0]->rev = ! t->c[0]->rev;
			}
			if(t->c[1]!=NULL){
				t->c[1]->rev = ! t->c[1]->rev;
			}
			t->rev=false;
		}
		if(t->lzy){
			t->slp+=t->lzy;
			t->inc+=t->lzy * (t->pt-t->prv);
			t->sm_inc+=t->lzy * t->sm_len;
			if(t->c[0]!=NULL){
				t->c[0]->lzy += t->lzy;
			}
			if(t->c[1]!=NULL){
				t->c[1]->lzy += t->lzy;
			}
			t->lzy=0;
		}
		if(t->lzy_pt){
			
			if(t->pt!= 1ll<<60){
				t->pt+=t->lzy_pt;
			}
			if(t->prv!= -1ll<<60){
				t->prv+=t->lzy_pt;
			}
			if(t->c[0]!=NULL){
				t->c[0]->lzy_pt += t->lzy_pt;
			}
			if(t->c[1]!=NULL){
				t->c[1]->lzy_pt += t->lzy_pt;
			}
			t->lzy_pt=0;
		}
	}
	void fix(nd * t){
		push_down(t);
		if(t->c[0]!=NULL){
			push_down(t->c[0]);
		}
		if(t->c[1]!=NULL){
			push_down(t->c[1]);
		}
		t->inc = (t->pt-t->prv) * t->slp;
		t->sm= num(t->c[0])+num(t->c[1])+1;
		t->sm_len= leng(t->c[0])+leng(t->c[1])+(t->pt-t->prv);
		t->sm_inc= incc(t->c[0])+incc(t->c[1])+t->inc;
	}
	void rotate(nd * t){
		long long c=ty(t);
		if(c==-1)return;
		nd * p = t->p;
		if(p==NULL)return;
		if(p->p!=NULL){
			p->p->c[ty(p)]=t;
		}
		t->p=p->p;
		p->p=t;
		p->c[c]=t->c[1-c];
		if(t->c[1-c]!=NULL){
			t->c[1-c]->p=p;
		}
		t->c[1-c]=p;
		fix(p);
		fix(t);
		if(t->p!=NULL){
			fix(t->p);
		}
	}
	
	nd * sp(nd * t){
		while(t->p!=NULL){
			if(t->p->p==NULL){
				rotate(t);
				continue;
			}
			if(ty(t) == ty(t->p)){
				rotate(t->p);
				rotate(t);
			} else {
				rotate(t);
				rotate(t);
			}
		}
		return t;
	}
	void _print(nd * t,long long pt,long long slp){
		if(t==NULL)return;
		pt+= t->lzy_pt;
		slp += t->lzy;

		_print(t->c[0],pt,slp);
		cout<<t->pt + pt <<" "<<t->slp + slp<<" "<<t->prv<<endl;
		_print(t->c[1],pt,slp);
	}
	void print(){
		return;
		cout<<"======"<<endl;
		_print(root,0,0);
	}
	long long lookup(long long slo){
		nd * t=root;
		nd * bst=NULL;
		while(true){
			push_down(t);
			if(t->slp <slo){
				bst=t;
			}
			if(t->slp >= slo){
				if(t->c[0]==NULL){
					break;
				} else {
					t=t->c[0];
				}
			} else {
				if(t->c[1]==NULL){
					break;
				} else {
					t=t->c[1];
				}
			}
		}
		push_down(t);
		root=sp(t);
		return bst->pt;
	}
	nd * lookuppt(nd * t,long long pt,bool is_not_root=false){
		nd * bst=NULL;
		while(true){
			push_down(t);
			if(t->pt <=pt){
				bst=t;
			}
			if(pt < t->pt){
				if(t->c[0]==NULL){
					break;
				} else {
					t=t->c[0];
				}
			} else {
				if(t->c[1]==NULL){
					break;
				} else {
					t=t->c[1];
				}
			}
		}
		push_down(t);
		if(!is_not_root){
			root=sp(t);
		} else {
			sp(t);
		}
		
		return bst;
	}

	nd * lookuppt2(nd * t,long long pt,bool is_not_root=false){
		nd * bst=NULL;
		while(true){
			push_down(t);
			if(pt <= t->pt ){
				bst=t;
			}
			if(pt <= t->pt){
				if(t->c[0]==NULL){
					break;
				} else {
					t=t->c[0];
				}
			} else {
				if(t->c[1]==NULL){
					break;
				} else {
					t=t->c[1];
				}
			}
		}
		push_down(t);
		if(!is_not_root){
			root=sp(t);
		} else {
			sp(t);
		}
		return bst;
	}
	pair<long long,long long> get_lookuppt2(long long x){
		nd * t=lookuppt2(root,x);
		return make_pair(t->pt,t->slp);
	}
	pair<long long,long long> get_lookuppt(long long x){
		nd * t=lookuppt(root,x);
		return make_pair(t->pt,t->slp);
	}
	void split1(nd * t,long long pt,bool is_after,nd * &l ,nd * &r){
		if(is_after){
			t=sp(lookuppt(t,pt));
			r=t->c[1];
			if(r!=NULL) r->p=NULL;
			t->c[1]=NULL;
			fix(t);
			l=t;
		} else {
			t=sp(lookuppt(t,pt));
			l=t->c[0];
			if(l!=NULL) l->p=NULL;
			t->c[0]=NULL;
			fix(t);
			r=t;
		}
	}

	void split2(nd * t,long long pt,bool is_after,nd * &l ,nd * &r){
		if(is_after){
			t=sp(lookuppt2(t,pt));
			r=t->c[1];
			if(r!=NULL) r->p=NULL;
			t->c[1]=NULL;
			fix(t);
			l=t;
		} else {
			t=sp(lookuppt2(t,pt));
			l=t->c[0];
			if(l!=NULL) l->p=NULL;
			t->c[0]=NULL;
			fix(t);
			r=t;
		}
	}
	void split_upd(nd * t,long long l,long long r,bool is_after,bool is_after2,nd * &left,nd * &mid,nd * &right){
		split2(t,r,is_after2,mid,right);
		split2(mid,l,is_after,left,mid);
	}
	void split_query(nd * t,long long l,long long r,bool is_after,bool is_after2,nd * &left,nd * &mid,nd * &right){
		split1(t,r,is_after2,mid,right);
		split2(mid,l,is_after,left,mid);
	}
	nd * _leftmost(nd * t){
		while(t->c[0]){
			push_down(t);
			t=t->c[0];
		}
		push_down(t);
		t=sp(t);
		return t;
	}
	long long leftmost(){
		nd * t=root;
		while(t->c[0]){
			push_down(t);
			t=t->c[0];
		}
		push_down(t);
		root=sp(t);
		return t->slp;
	}
	long long rightmost(){
		nd * t=root;
		while(t->c[1]){
			push_down(t);
			t=t->c[1];
		}
		push_down(t);
		root=sp(t);
		return t->slp;
	}
	void initiate(){
		root=new nd(NULL,0,-1ll<<60,-1ll<<60);
		root->c[1]=new nd(root,1ll<<60,1ll<<60,0);
	}
	void insert(long long pt){
		root=sp(lookuppt2(root,pt));
		if(root->pt==pt){
			
			return;
		}
		hhy++;
		nd * l=root->c[0];
		root->c[0]=new nd(root,pt,root->slp,root->prv);
		root->c[0]->c[0]=l;
		root->prv=pt;
		if(l!=NULL) l->p=root->c[0];
		fix(root->c[0]);
		fix(root);
	}

	void insert_right(long long slp){
		rightmost();
		root->c[1]=new nd(root,1ll<<60,slp,root->pt);
		fix(root);
	}
	
	void insert_left(long long slp,long long pt){
		leftmost();
		root->c[0]=new nd(root,pt,slp,-1ll<<60);
		fix(root);
	}
	
	void erase_right(){
		nd *left=root->c[0],*mid=root;
		//split_r(root,idx,idx, left,mid,right);
		delete mid;
		root=left;
		if(root!=NULL)
			root->p=NULL;
	}
	void erase_left(){
		nd *right=root->c[1],*mid=root;
		//split_r(root,idx,idx, left,mid,right);
		delete mid;
		root=right;
		if(root!=NULL)
			root->p=NULL;
	}

	nd * join(nd * l,nd * r){
		if(r==NULL)return l;
		r=_leftmost(r);
		r->c[0]=l;
		if(l!=NULL) l->p=r;
		fix(r);
		return r;
	}
	
	long long query(long long l,long long r,bool is_after){
		nd *left,*mid,*right;
		split_query(root,l,r,is_after,is_after,left,mid,right);
		long long ret;
		if(mid==NULL){
			ret=0;
		} else {
			ret=mid->sm_inc;
		}
		mid=join(left,mid);
		root=join(mid,right);
		return ret;
	}
	void upd(long long l,long long r,bool is_leftmost,long long add){
		nd *left,*mid,*right;
		split_upd(root,l,r,!is_leftmost,true,left,mid,right);
		mid->lzy+=add;
		push_down(mid);
		mid=join(left,mid);
		root=join(mid,right);
	}
};

struct func{
	splay tree;
	long long yval;
	long long xval;
};
struct ed{
	long long ch;
	long long co;
	long long dx;
	long long ind;
};
long long n;
vector<ed> adj[200011];

func * dp[200011];
long long ll[200011];
long long rr[200011];


long long evaluate(func * &a,long long x){
	if(x==a->xval){
		return a->yval;
	} else if( x<a->xval){
		a->tree.print();
		long long ans=-a->tree.query(x,a->xval,true) + a->yval;
		pair<long long,long long> yy=a->tree.get_lookuppt2(x);
		ans+= (x-yy.first) * yy.second;
		return ans;
	} else {
		long long ans=a->tree.query(a->xval,x,true) + a->yval;
		pair<long long,long long> yy=a->tree.get_lookuppt(x);
		pair<long long,long long> yy2=a->tree.get_lookuppt2(x);
		ans+= (x-yy.first) * yy2.second;
		return ans;
	}
}

void cover(func * &a,long long co,long long dx,long long &l,long long &r){
	l=-1ll<<60;
	r=1ll<<60;
	a->tree.print();
	bool del=false;
	a->tree.root->lzy_pt+=co;
	a->xval+=co;
	a->tree.print();
	while(true){
		long long y=a->tree.rightmost();
		if(y>=dx){
			del=true;
			
			a->tree.erase_right();
		} else {
			break;
		}
	}
	a->tree.print();
	if(del){
		a->tree.rightmost();
		r=a->tree.root->pt;
		a->tree.insert_right(dx);
	}
	del=false;
	long long pot=-1ll<<60;
	while(true){
		long long y=a->tree.leftmost();
		if(y<=-dx){
			del=true;
			
			pot=a->tree.root->pt;
			a->tree.erase_left();
		} else {
			break;
		}
	}
	if(del){
		l=pot;
		a->tree.insert_left(-dx,pot);
	}
	a->tree.print();
}

void merge(func * &a, func * &b){
	bool first=true;
	a->tree.print();
	b->tree.print();
	a->yval += evaluate(b,a->xval);
	long long last=-1;
	while(true){
		if(b->tree.root==NULL)break;
		b->tree.leftmost();
		a->tree.insert(b->tree.root->pt);
		a->tree.print();
		if(first){
			first=false;
			a->tree.upd(-1ll<<60,b->tree.root->pt,true,b->tree.root->slp);
			
		} else {
			a->tree.upd(last,b->tree.root->pt,false,b->tree.root->slp);
		}
		last=b->tree.root->pt;
		b->tree.erase_left();
	}
	a->tree.print();
	long long ot=a->tree.lookup(0);
	long long val=evaluate(a,ot);
	a->xval=ot;
	a->yval=val;
}

void dfs(long long nd,long long p){
	bool has_val=false;

	long long id=-1,mx=-1;
	for(long long i=0;i<adj[nd].size();i++){
		long long ch=adj[nd][i].ch;
		long long co=adj[nd][i].co;
		long long dx=adj[nd][i].dx;
		if(ch==p)continue;
		has_val=true;
		dfs(ch,nd);
		cover(dp[ch],co,dx,ll[ch],rr[ch]);
		if(mx<dp[ch]->tree.root->sm){
			mx=dp[ch]->tree.root->sm;
			id=ch;
		}
	}
	if(!has_val){
		dp[nd]=new func();

		dp[nd]->xval=0;
		dp[nd]->yval=0;
		dp[nd]->tree.initiate();
		dp[nd]->tree.print();
		return ;
	}
	dp[nd]=dp[id];
	for(long long i=0;i<adj[nd].size();i++){
		long long ch=adj[nd][i].ch;
		long long co=adj[nd][i].co;
		long long dx=adj[nd][i].dx;
		if(ch==p)continue;
		if(ch==id)continue;
		merge(dp[nd],dp[ch]);
		
	}
	
}
long long sol[200200];
void dfs_get_edges(int nd,int p,long long curr_x){
	for(int i=0;i<adj[nd].size();i++){
		int ch=adj[nd][i].ch;
		int co=adj[nd][i].co;
		int ind=adj[nd][i].ind;
		if(ch==p)continue;

		if(curr_x>rr[ch]){
			sol[ind]=curr_x-rr[ch]+co;
			dfs_get_edges(ch,nd,rr[ch]-co);
		} else if (curr_x < ll[ch]){
			sol[ind]=curr_x-ll[ch]+co;
			dfs_get_edges(ch,nd,ll[ch]-co);
		} else {
			sol[ind]=co;
			dfs_get_edges(ch,nd,curr_x-co);
		}
	}
}
long long t;
int main(){
	//freopen("input14.txt","r",stdin);
	//freopen("2oput14.txt","w",stdout);
	cin.sync_with_stdio(false);
	cin>>t;
	while(t--){
		
		cin>>n;
		for(long long i=1;i<=n;i++){
			adj[i].clear();
		}
		for(long long i=0;i<n-1;i++){
			long long a,b,c,d;
			cin>>a>>b>>c>>d;
			ed h;
			h.ch=b;
			h.co=c;
			h.dx=d;
			h.ind=i;
			adj[a].push_back(h);
			h.ch=a;
			adj[b].push_back(h);
		}
		dfs(1,1);
		cout<<dp[1]->yval<<"\n";
		dfs_get_edges(1,1,dp[1]->xval);
		for(int i=0;i<n-1;i++){
			cout<<sol[i]<<endl;
		}
		while(dp[1]->tree.root!=NULL){
			dp[1]->tree.erase_left();
		}
	}
}