#include <bits/stdc++.h>  // include all standard C++ libraries

using namespace std;

// Loops
#define _overload3(_1,_2,_3,name,...) name
#define _rep(i,n) repi(i,0,n)
#define repi(i,a,b) for(int i=int(a);i<int(b);++i)
#define _rrep(i,n) rrepi(i,n,0)
#define rrepi(i,a,b) for(int i=int(a)-1;i>=int(b);--i)

#define rep(...) _overload3(__VA_ARGS__,repi,_rep,)(__VA_ARGS__)
#define rrep(...) _overload3(__VA_ARGS__,rrepi,_rrep,)(__VA_ARGS__)
#define each(xi, x) for (auto&& xi : x)
// Note: we can use rep(i,N) or rep(i,from,to)


// typedef
using ll = long long;
template <class T> using vec = vector<T>;
using vi   = vector<int>;
using vvi  = vector<vi>;
using vvvi = vector<vvi>;
using pii  = pair<int, int>;


// Constants
#define INF 1e9

// Algorithms
#define all(x) (x).begin(), (x).end()
#define uniq(v) v.erase( unique(all(v)), v.end() )
#define perm(c) sort(all(c));for(bool c##p=1;c##p;c##p=next_permutation(all(c)))

template<class T> inline bool chmax(T &maxval, const T &newval) { if (maxval<newval) { maxval=newval; return 1; } return 0; }
template<class T> inline bool chmin(T &minval, const T &newval) { if (minval<newval) { minval=newval; return 1; } return 0; }

// Utilities
// Grid world utilities
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
#define inside(H,W,y,x) 0<=(x) && (x)<(W) && 0<=(y) && (y)<(H)

inline int in() {int x; cin >> x; return x;} // read int from cin
inline  ll IN() {ll x; cin >> x; return x;}  // read ll from cin


// Shorter repr for frequently used terms
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define Fi first
#define Se second

// Debug
#ifdef LOCAL
  #include "dump.hpp"
  #define debug(x) cerr << #x << ": " << x << '\n'
#else
  #define dump(...)
  #define debug(x)
#endif

// Paste snippets here!!
struct Data {
  ll i, j, k;
  ll val;
  Data(int i, int j, int k, ll val) : i(i), j(j), k(k), val(val) {}
  //bool operator>(const Data &rhs) const { return val>rhs.val; }
  bool operator<(const Data &rhs) const { return val<rhs.val; }
  //ll order() const { return i+1000*j+1000000*k; }
  //bool operator<(const Data &rhs) const { return order()<rhs.order(); }
  //bool operator==(const Data &rhs) const { return (i==rhs.i && j==rhs.j && k==rhs.k); }
};
// 
class DataComp {
public:
  bool operator()(const Data &left,
                  const Data &right) {
    return (left.i + left.j*1000 + left.k*1000000 <
            right.i + right.j*1000 + right.k*1000000);
  }
};

int main(){
  cin.tie(0); ios::sync_with_stdio(false);    // Magic for faster cin

  int X, Y, Z, K;
  cin >> X >> Y >> Z >> K;
  vec<ll> A(X); vec<ll> B(Y); vec<ll> C(Z);
  rep(i,X) cin >> A[i];
  rep(i,Y) cin >> B[i];
  rep(i,Z) cin >> C[i];

  //auto f = [](ll a, ll b){return a>b;};
  sort(all(A), greater<ll>());
  sort(all(B), greater<ll>());
  sort(all(C), greater<ll>());


  priority_queue<Data> q;
  Data x(0,0,0,A[0]+B[0]+C[0]);
  q.push(x);
  set<Data, DataComp> mem; mem.insert(x);
  int r=0;
  while(r<K){
    Data x = q.top(); q.pop();
    cout << x.val << endl;
    r++;
    
    
    if(x.i<A.size()-1){
      Data d1(x.i+1,x.j,  x.k,  A[x.i+1]+B[x.j]+C[x.k]);
      if(mem.find(d1)==mem.end()){q.push(d1); mem.insert(d1);}
    }
    if(x.j<B.size()-1){
      Data d2(x.i  ,x.j+1,x.k,  A[x.i]+B[x.j+1]+C[x.k]);
      if(mem.find(d2)==mem.end()){ q.push(d2); mem.insert(d2); }
    }
    if(x.k<C.size()-1){
      Data d3(x.i  ,x.j,  x.k+1,A[x.i]+B[x.j]+C[x.k+1]);
      if(mem.find(d3)==mem.end()){ q.push(d3); mem.insert(d3); }
    }
  }
  return 0;
}


Measured memory_bytes: 1024