#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <functional>

using namespace std;

struct ABCijk {
    long long int ABC;
    int i, j, k;
};

// bool cmp(ABCijk a, ABCijk b) {
//     if(a.ABC!=b.ABC) {
//         return a.ABC>b.ABC;
//     } else {
//         return a.i+a.j+a.k < b.i+b.j+b.k;
//     }
// }


int main() {
    int X, Y, Z, K;
    cin >> X >> Y >> Z >> K;
    
    vector<long long int> A(X);
    vector<long long int> B(Y);
    vector<long long int> C(Z);
    vector<long long int> a(X, 0);
    vector<long long int> b(Y, 0);
    vector<long long int> c(Z, 0);
    for(int x=0; x<X; x++) {
        cin >> A[x];
    }
    for(int y=0; y<Y; y++) {
        cin >> B[y];
    }
    for(int z=0; z<Z; z++) {
        cin >> C[z];
    }
    
    sort(A.begin(), A.end(), greater<long long int>());
    sort(B.begin(), B.end(), greater<long long int>());
    sort(C.begin(), C.end(), greater<long long int>());
    
    int i=0;
    while(i<max(X, max(Y, Z))) {
        if(i<X) {
            a[i] = A[0]-A[i];
            // cout << a[i] << " ";
        }
        if(i<Y) {
            b[i] = B[0]-B[i];
            // cout << b[i] << " ";
        }
        if(i<Z) {
            c[i] = C[0]-C[i];
            // cout << c[i] << " ";
        }
        // cout << endl;
        i++;
    }
    
    auto cmp = [](ABCijk a, ABCijk b) {
        if(a.ABC!=b.ABC) {
            return a.ABC<b.ABC;
        } else {
            return a.i+a.j+a.k < b.i+b.j+b.k;
        }
    };
    priority_queue<ABCijk, vector<ABCijk>, decltype(cmp)> que(cmp);
    vector<ABCijk> candidate;
    ABCijk abcijk={A[0]+B[0]+C[0], 0, 0, 0};
    que.push(abcijk);
    candidate.push_back(abcijk);
    
    int count=0;
    while(count<K) {
        ABCijk curabcijk = que.top();
        long long int curABC = curabcijk.ABC;
        int cur_i = curabcijk.i;
        int cur_j = curabcijk.j;
        int cur_k = curabcijk.k;

        que.pop();
        
        cout << curABC << endl;
        
        bool flag=true;
        if(cur_i+1<X) {
            for(int vi=0; vi<candidate.size(); vi++) {
                if(candidate[vi].i==cur_i+1 && \
                    candidate[vi].j==cur_j && \
                    candidate[vi].k==cur_k) {
                    flag=false;
                    break;
                }
            }
            if(flag) {
                que.push({A[cur_i+1]+B[cur_j]+C[cur_k], cur_i+1, cur_j, cur_k});
                candidate.push_back({A[cur_i+1]+B[cur_j]+C[cur_k], cur_i+1, cur_j, cur_k});
            }
        }
        flag=true;
        if(cur_j+1<Y) {
            for(int vi=0; vi<candidate.size(); vi++) {
                if(candidate[vi].i==cur_i && \
                    candidate[vi].j==cur_j+1 && \
                    candidate[vi].k==cur_k) {
                    flag=false;
                    break;
                }
            }
            if(flag) {
                que.push({A[cur_i]+B[cur_j+1]+C[cur_k], cur_i, cur_j+1, cur_k});
                candidate.push_back({A[cur_i]+B[cur_j+1]+C[cur_k], cur_i, cur_j+1, cur_k});
            }
        }
        flag=true;
        if(cur_k+1<Z) {
            for(int vi=0; vi<candidate.size(); vi++) {
                if(candidate[vi].i==cur_i && \
                    candidate[vi].j==cur_j && \
                    candidate[vi].k==cur_k+1) {
                    flag=false;
                    break;
                }
            }
            if(flag) {
                que.push({A[cur_i]+B[cur_j]+C[cur_k+1], cur_i, cur_j, cur_k+1});
                candidate.push_back({A[cur_i]+B[cur_j]+C[cur_k+1], cur_i, cur_j, cur_k+1});
            }
        }
        
        count++;
    }

    return 0;
    
}

Measured memory_bytes: 768