import std.stdio, std.range, std.conv, std.string, std.array, std.functional, std.math, std.regex, std.range, std.traits, std.ascii;
import std.algorithm.comparison, std.algorithm.iteration, std.algorithm.mutation, std.algorithm.searching, std.algorithm.setops, std.algorithm.sorting;
import std.container.binaryheap;
import std.typecons; 

void scan(TList...)(ref TList list)
{
    auto elem = readln().split;
    foreach(i, T; TList)
    {
        list[i] = elem[i].to!T;
    }
}
T[] scanArray(T=long)()
{
    return readln.split.to!(T[]);
}
T scanElem(T=long)()
{
    string res;
    char[1] bIn = ' ';
    while(isWhite(bIn[0]))
    {
        stdin.rawRead(bIn);
    }
    while(!isWhite(bIn[0]))
    {
        res ~= bIn[0];
        stdin.rawRead(bIn);
    }
    return res.to!T;
}

struct N{
    long x;
    long y;
    long z;
}

void main()
{
    auto X = scanElem();
    auto Y = scanElem();
    auto Z = scanElem();
    auto K = scanElem();

    auto aList = scanArray().sort!"a>b";
    auto bList = scanArray().sort!"a>b";
    auto cList = scanArray().sort!"a>b";

    long sum(N n)
    {
        return aList[n.x] + bList[n.y] + cList[n.z];
    }

    auto heap = BinaryHeap!(N[], (a,b)=>sum(a)<sum(b))([N(0,0,0)]);
    bool[N] used;
    used[N(0,0,0)] = true;
    foreach(i; 0..K)
    {
        auto top = heap.front; heap.popFront;
        writeln(sum(top));
        
        auto xQueue = N(top.x+1, top.y, top.z);
        auto yQueue = N(top.x, top.y+1, top.z);
        auto zQueue = N(top.x, top.y, top.z+1);
        if(top.x+1 < X && (xQueue !in used))
        {
            heap.insert(xQueue);
            used[xQueue] = true;
        }
        if(top.y+1 < Y && (yQueue !in used))
        {
            heap.insert(yQueue);
            used[yQueue] = true;
        }
        if(top.z+1 < Z && (zQueue !in used))
        {
            heap.insert(zQueue);
            used[zQueue] = true;
        }
    }
}