//#include "debug.h"
#include <assert.h>
#include <string.h>
#include <limits.h>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

template<class T>
void printa(const T *a, int n) {
	cout << '[';
	for (int i=0; i<n; i++) {
		if (i) cout << ',';
		cout << a[i];
	}
	cout << ']' << endl;
}

template<class T>
void printa_nz(const T *a, int n) {
	cout << '[';
	for (int i=0, k=0; i<n; i++) {
		if (!(a[i]==0)) {
			if (k++) cout << ',';
			cout << i << ':' << a[i];
		}
	}
	cout << ']' << endl;
}

template<class T>
void printa_i(const T *a, int n) {
	cout << '[';
	for (int i=0; i<n; i++) {
		if (i) cout << ',';
		cout << i << ':' << a[i];
	}
	cout << ']' << endl;
}

template<class T1,class T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &x) {
	return os<<'('<<x.first<<','<<x.second<<')';
}

template<class T>
ostream &operator<<(ostream &os, const vector<T> &a) {
	os << '[';
	int n = a.size();
	for (int i=0; i<n; i++) {
		if (i) os << ',';
		os << a[i];
	}
	os << ']';
	return os;
}

template<class K, class T>
ostream &operator<<(ostream &os, const map<K,T> &a) {
	os << '{';
	int i = 0;
	for (auto &x: a) {
		if (i) os << ',';
		i++;
		os << x.first << ':' << x.second;
	}
	return os << '}' << endl;
}


template<class T, class C>
ostream &operator<<(ostream &os, const set<T, C> &a) {
	os << '{';
	int i = 0;
	for (auto &x: a) {
		if (i) os << ',';
		i++;
		os << x;
	}
	return os << '}';
}


template<class T>
ostream &operator<<(ostream &os, const multiset<T> &a) {
	os << '{';
	int i = 0;
	for (auto &x: a) {
		if (i) os << ',';
		i++;
		os << x;
	}
	return os << '}';
}
#include <string.h>
#include <limits.h>
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;

#define MAXN 1000
typedef long long i64;

int n[3];
int k;
i64 a[3][MAXN];

int input() {
	if (scanf("%d %d %d", &n[0], &n[1], &n[2]) < 0) return 0;
	scanf("%d", &k);
	for (int i=0; i<3; i++)
		for (int j=0; j<n[i]; j++)
			scanf("%lld", &a[i][j]);
	return 1;
}

void init() {
}

struct node {
	int p[3];
	i64 s;
	node(int *q) {
		memcpy(p, q, sizeof(p));
		s = 0;
		for (int i=0; i<3; i++)
			s += a[i][p[i]];
	}
	node next(int i) {
		int q[3];
		memcpy(q, p, sizeof(p));
		q[i]++;
		return node(q);
	}
};

struct cmp {
	bool operator()(const node &x, const node &y) const {
		for (int i=0; i<3; i++)
			if (x.p[i] != y.p[i])
				return x.p[i] < y.p[i];
		return false;
	}
};

/*
ostream &operator<<(ostream &os, const node &x) {
	printa(x.p, 3);
	return os;
}
*/

bool operator<(const node &x, const node &y) {
	return x.s < y.s;
}

i64 solve() {
	for (int i=0; i<3; i++)
		sort(a[i], a[i]+n[i], greater<i64>());
	priority_queue<node> q;
	set<node, cmp> d;
	int p[3]={0};
	node x(p);
	q.push(x);
	d.insert(x);
	for (int i=0; i<k; i++) {
		x = q.top();
		q.pop();
		printf("%lld\n", x.s);
		for (int j=0; j<3; j++) {
			if (x.p[j]+1 == n[j]) continue;
			node y = x.next(j);
			if (d.count(y)==0) {
				d.insert(y);
				q.push(y);
			}
		}
	}
	//for (int i=0; i<3; i++) printa(a[i], n[i]);
	//cout << d << endl;
	return 1;
}

void output(i64 ans) {
}

void cleanup() {
}

int main() {
	//precalc();
	//int ca; scanf("%d", &ca);
	while (input()) {
		init();
		output(solve());
		cleanup();
		//break;
	}
}




Measured memory_bytes: 768