#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int maxn=200+5;
int cup[3]; //方便遍历
int mp[maxn][maxn],ans[maxn];//mpbfs判重,ans记录每个状态不同杯子的水量
struct node{
int v[3],dis;
bool operator < (const node&rhs) const{//从状态节点的dis最小处扩展,所以最短路问题也是从dis的最小处扩展
return dis>rhs.dis;
}
};
void rcu(node&u){
for(int i=0;i<3;i++){
if(ans[u.v[i]]<0||u.dis<ans[u.v[i]])//如果状态u的dis更小则更新
ans[u.v[i]]=u.dis;
}
}
void bfs(int a,int b,int c,int d){
cup[0]=a,cup[1]=b,cup[2]=c;
priority_queue<node> que;
node start;
start.v[0]=0,start.v[1]=0,start.v[2]=c,start.dis=0;
que.push(start);
memset(mp,0,sizeof(mp));
memset(ans,-1,sizeof(ans));
mp[0][0]=1;
while(que.size()){//所需要找到的dis因为必须执行到que为空结束才能找到,中间无法记录需要的节点,所以用ans保存dis和每个可行的状态的水量情况
node u=que.top();que.pop();
rcu(u);
if(ans[d]>=0)break;
//扩展子节点,依照dis小方向扩展
//从第i个杯子向第j个被子倒水
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
if(j!=i){
if(!u.v[i]||u.v[j]==cup[j])continue;
int amount=min(cup[j],u.v[i]+u.v[j])-u.v[j];//向j杯子倒amount的水
node u1;
memcpy(&u1,&u,sizeof(u));//扩展子节点,u为根节点
u1.dis=u.dis+amount;
u1.v[i]-=amount;
u1.v[j]+=amount;
if(!mp[u1.v[0]][u1.v[1]]){
que.push(u1);
mp[u1.v[0]][u1.v[1]]=1;
}
}
}
// for(int i=0;i<10;i++)printf("%d",ans[i]);
// cout<<endl;
while(d>=0){
if(ans[d]>=0){
printf("%d %d\n",ans[d],d);
return;
}
d--;
}
}
int main(){
int t,a,b,c,d;
cin>>t;
while(t--){
scanf("%d%d%d%d",&a,&b,&c,&d);
bfs(a,b,c,d);
}
return 0;
}
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int maxn=200+5;
int cup[3]; //方便遍历
int mp[maxn][maxn],ans[maxn];//mpbfs判重,ans记录每个状态不同杯子的水量
struct node{
int v[3],dis;
bool operator < (const node&rhs) const{//从状态节点的dis最小处扩展,所以最短路问题也是从dis的最小处扩展
return dis>rhs.dis;
}
};
void rcu(node&u){
for(int i=0;i<3;i++){
if(ans[u.v[i]]<0||u.dis<ans[u.v[i]])//如果状态u的dis更小则更新
ans[u.v[i]]=u.dis;
}
}
void bfs(int a,int b,int c,int d){
cup[0]=a,cup[1]=b,cup[2]=c;
priority_queue<node> que;
node start;
start.v[0]=0,start.v[1]=0,start.v[2]=c,start.dis=0;
que.push(start);
memset(mp,0,sizeof(mp));
memset(ans,-1,sizeof(ans));
mp[0][0]=1;
while(que.size()){//所需要找到的dis因为必须执行到que为空结束才能找到,中间无法记录需要的节点,所以用ans保存dis和每个可行的状态的水量情况
node u=que.top();que.pop();
rcu(u);
if(ans[d]>=0)break;
//扩展子节点,依照dis小方向扩展
//从第i个杯子向第j个被子倒水
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
if(j!=i){
if(!u.v[i]||u.v[j]==cup[j])continue;
int amount=min(cup[j],u.v[i]+u.v[j])-u.v[j];//向j杯子倒amount的水
node u1;
memcpy(&u1,&u,sizeof(u));//扩展子节点,u为根节点
u1.dis=u.dis+amount;
u1.v[i]-=amount;
u1.v[j]+=amount;
if(!mp[u1.v[0]][u1.v[1]]){
que.push(u1);
mp[u1.v[0]][u1.v[1]]=1;
}
}
}
// for(int i=0;i<10;i++)printf("%d",ans[i]);
// cout<<endl;
while(d>=0){
if(ans[d]>=0){
printf("%d %d\n",ans[d],d);
return;
}
d--;
}
}
int main(){
int t,a,b,c,d;
cin>>t;
while(t--){
scanf("%d%d%d%d",&a,&b,&c,&d);
bfs(a,b,c,d);
}
return 0;
}