local DBG = false
local function dbgpr(...)
    if DBG then
        io.write("[dbg]")
        print(...)
    end
end

local function dbgpr_t(tbl, use_pairs)
    if DBG then
        local enum = ipairs
        if use_pairs then
            enum = pairs
        end
        dbgpr(tbl)
        io.write("[dbg]")
        for i,v in enum(tbl) do
            io.write(i)
            io.write(":")
            io.write(tostring(v))
            io.write(" ")
        end
        print("")
    end
end

local function dbgpr_tp(tbl)
    dbgpr_t(tbl, true)
end

-- heap
local Heap = {}
function Heap.new(upper_func)
    local self = setmetatable({}, {__index = Heap})
    self.a = {}
    self.upper_func = upper_func
    self.upper = function(k1, k2)
        assert(k1 < k2)
        if k1 == 0 then
            return false
        else
            return upper_func(self.a[k1], self.a[k2])
        end
    end
    self.lower = function(k1, k2)
        return not self.upper(k1, k2)
    end
    return self
end

function Heap:count()
    return #self.a
end

function Heap:_swap(k1, k2)
    local old_k1 = self.a[k1]
    self.a[k1] = self.a[k2]
    self.a[k2] = old_k1
end

function Heap:upheap(newk)
    local ku = newk // 2
    local k = newk
    while ku > 0 and self.lower(ku, k) do
        self:_swap(ku, k)
        k = k//2
        ku = ku//2
    end
end

function Heap:insertq(e)
    table.insert(self.a, e)
    self:upheap(#self.a)
end

function Heap:downheap(newk)
    local k = newk
    while k <= #self.a//2 do
        local kdl = k*2
        local kdr = kdl + 1
        local kd
        if kdr <= #self.a and self.lower(kdl, kdr) then
            kd = kdr
        else
            kd = kdl
        end
        if self.upper(k, kd) then
            break
        end
        self:_swap(k, kd)
        k = kd
    end
end

function Heap:top()
    assert(#self.a >= 1)
    return self.a[1]
end

function Heap:remove_top()
    assert(#self.a >= 1)
    local v = self.a[1]
    self:_swap(1, #self.a)
    table.remove(self.a)
    self:downheap(1)
    return v
end

--[[
function Heap:replace_top(e)
    assert(#self.a >= 1)
    local old_v = self.a[1]
    local swapped = false
    if self.upper_func(old_v, e) then
        self.a[1] = e
        self:downheap(1)
        swapped = true
    end
    return swapped, old_v
end

function Heap:change()
end

function Heap:delete()
end
]]
-- D
local X, Y, Z, K = io.read("n", "n", "n", "n")
local A, B, C = {}, {}, {}

for i, tbl in ipairs {A, B, C} do
    local nums = {X, Y, Z}
    local count = nums[i]
    for j=1, count do
        tbl[j] = io.read("n")
    end
    table.sort(tbl, function (x,y)
        return x > y
    end)
end

local function goodness(a, b, c)
    if a > #A or b > #B or c > #C then
        return -10000000000000
    end
    return A[a] + B[b] + C[c]
end

local visited = {}
local function visit(a,b,c)
    visited[tostring(a) .. "*" .. tostring(b) .. "*" .. tostring(c)] = true
end
local function isvisited(a,b,c)
    return visited[tostring(a) .. "*" .. tostring(b) .. "*" .. tostring(c)]
end

-- most good comb top
local items = Heap.new(function(x,y)
    return x[4] > y[4]
end)
local function items_add(a, b, c)
    items:insertq({a,b,c,goodness(a,b,c)})
end
local function check_add(a,b,c)
    if a > #A or b > #B or c > #C then
        return -1
    end
    if isvisited(a, b, c) then
        return -2
    end
    visit(a,b,c)
    items_add(a, b, c)
end
local ans = {}
local a, b, c = 1, 1, 1
check_add(a, b, c)
while #ans < K do
    local e = items:remove_top()
    table.insert(ans, e[4])
    local a,b,c = e[1], e[2], e[3]
    check_add(a+1,b,c)
    check_add(a,b+1,c)
    check_add(a,b,c+1)
end

table.sort(ans, function(x,y) return x>y end)
for i=1,K do
    print(ans[i])
end


Measured memory_bytes: 2420