import std.algorithm;
import std.array;
import std.container;
import std.conv;
import std.math;
import std.numeric;
import std.range;
import std.stdio;
import std.string;
import std.typecons;

void scan(T...)(ref T a) {
    string[] ss = readln.split;
    foreach (i, t; T) a[i] = ss[i].to!t;
}
T read(T)() { return readln.chomp.to!T; }
T[] reads(T)() { return readln.split.to!(T[]); }
alias readint = read!int;
alias readints = reads!int;

alias D = Tuple!(long, "sum", int, "i", int, "j", int, "k");

void calc_pq(int K, long[] a, long[] b, long[] c) {
    a.sort!("a > b");
    b.sort!("a > b");
    c.sort!("a > b");
    auto pq = new BinaryHeap!(Array!D);
    bool[Tuple!(int, int, int)] used;
    pq.insert(D(a[0] + b[0] + c[0], 0, 0, 0));
    while (K > 0) {
        auto d = pq.front;
        pq.popFront();
        if (tuple(d.i, d.j, d.k) in used) continue;

        writeln(d.sum);
        used[tuple(d.i, d.j, d.k)] = true;
        K--;

        int i = d.i;
        int j = d.j;
        int k = d.k;
        if (i + 1 < a.length)
            pq.insert(D(a[i + 1] + b[j] + c[k], i + 1, j, k));
        if (j + 1 < b.length)
            pq.insert(D(a[i] + b[j + 1] + c[k], i, j + 1, k));
        if (k + 1 < c.length)
            pq.insert(D(a[i] + b[j] + c[k + 1], i, j, k + 1));
    }
}

void calc(int k, long[] a, long[] b, long[] c) {
    long[] ab;
//    foreach (x, y; cartesianProduct(a, b))
//        ab ~= x + y;
    foreach (x; a) foreach (y; b) ab ~= x + y;

    ab.sort!"a > b";
    c.sort!"a > b";
    long[] abc;
//    foreach (x, y; cartesianProduct(c, ab.take(k)))
//        abc ~= x + y;
    foreach (x; c) foreach (y; ab.take(k))
        abc ~= x + y;
    abc.sort!"a > b";
    foreach (e; abc.take(k)) writeln(e);
}

void main() {
    int x, y, z, k; scan(x, y, z, k);
    auto a = reads!long;
    auto b = reads!long;
    auto c = reads!long;


    calc(k, a, b, c);
}
