import std.algorithm;
import std.conv;
import std.range;
import std.stdio;
import std.string;

void main ()
{
	int x, y, z, k;
	while (readf (" %s %s %s %s", &x, &y, &z, &k) > 0)
	{
		readln;
		auto a = readln.splitter.map !(to !(long)).array;
		auto b = readln.splitter.map !(to !(long)).array;
		auto c = readln.splitter.map !(to !(long)).array;
		sort !(q{a > b}) (a);
		sort !(q{a > b}) (b);
		sort !(q{a > b}) (c);
		int u = 1;
		int v = 1;
		int w = 1;
		while (u * v * w < k)
		{
			auto cu = (u == a.length) ? long.max : a[0] - a[u];
			auto cv = (v == b.length) ? long.max : b[0] - b[v];
			auto cw = (w == c.length) ? long.max : c[0] - c[w];
			if (cu <= cv && cu <= cw)
			{
				u += 1;
			}
			else if (cv <= cu && cv <= cw)
			{
				v += 1;
			}
			else
			{
				w += 1;
			}
		}
		debug {stderr.writeln (u, " ", v, " ", w);}

		auto getBest ()
		{
			long [] d;
			d.reserve (u * v * w);
			auto m = min (k, u * v * w);
			foreach (p; 0..u)
			{
				foreach (q; 0..v)
				{
					foreach (r; 0..w)
					{
						d ~= a[p] + b[q] + c[r];
					}
				}
			}
			partialSort !(q{a > b}) (d, m);
			return d[0..m];
		}

		if (u < a.length)
		{
			u += 1;
		}
		if (v < b.length)
		{
			v += 1;
		}
		if (w < c.length)
		{
			w += 1;
		}
		auto prev = getBest ();

		writefln ("%(%s\n%)", prev);
	}
}
