#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int MAXHASHSIZE = ;
int d, _head[MAXHASHSIZE], _next[MAXHASHSIZE];
int vol[], _d, ans, idx, st[MAXHASHSIZE], pour_set[MAXHASHSIZE];
struct Node {
int v[], pour;
Node(int a = , int b = , int c = , int p = ) {
v[] = a; v[] = b; v[] = c; pour = p;
}
bool operator == (const Node &rhs) const {
for (int i = ; i < ; i++) if (rhs.v[i] != v[i]) return false;
if (rhs.pour != pour) return false;
return true;
}
};
void init() {
_d = -;
ans = ;
idx = ;
memset(_head, , sizeof(_head));
}
bool try_to_insert(Node &cur) {
int status = cur.v[] * + cur.v[] * + cur.v[];
int h = status % MAXHASHSIZE;
int u = _head[h];
while (u) {
if (st[u] == status) {
if (cur.pour < pour_set[u]) {
pour_set[u] = cur.pour;
return ;
}
return ;
}
u = _next[u];
}
st[idx] = status;
pour_set[idx] = cur.pour;
_next[idx] = _head[h];
_head[h] = idx++;
return ;
}
void bfs(Node start) {
pour_set[] = start.pour;
try_to_insert(start);
queue<Node> q;
q.push(start);
while (!q.empty()) {
Node cur = q.front(); q.pop();
for (int i = ; i < ; i++) {
if (cur.v[i] == _d)
ans = min(ans, cur.pour);
else if (cur.v[i] > _d && cur.v[i] <= d) {
ans = cur.pour;
_d = cur.v[i];
}
if (cur.v[i] != )
for (int j = ; j < ; j++) if (i != j) {
int pour = min(cur.v[i], vol[j] - cur.v[j]);
cur.v[i] -= pour;
cur.v[j] += pour;
Node nextn = Node(cur.v[], cur.v[], cur.v[], cur.pour + pour);
cur.v[i] += pour;
cur.v[j] -= pour;
if (try_to_insert(nextn)) q.push(nextn);
}
}
}
}
int main() {
int T;
scanf("%d", &T);
while (T--) {
init();
scanf("%d%d%d%d", &vol[], &vol[], &vol[], &d);
bfs(Node(, , vol[], ));
printf("%d %d\n", ans, _d);
}
return ;
}