// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;



using i32 = std::int_fast32_t;

using i64 = std::int_fast64_t;



#define REP(i, stop) FOR(i, 0, stop)

#define FOR(i, start, stop) for (int i = start, i##_len = stop; i < i##_len; ++i)

#define RREP(i, n) for (int i = n; i-- > 0;)

#define ALL(v) (v).begin(), (v).end()



template<typename T> istream& operator>>(istream& is, vector<T>& a) { for (T& x : a) is >> x; return is; }



struct InitCpp { InitCpp() { cin.tie(nullptr); ios::sync_with_stdio(false); } } initCpp;



signed main() {

  i32 x, y, z, k;

  cin >> x >> y >> z >> k;

  vector<i64> A(x), B(y), C(z);

  cin >> A >> B >> C;

  sort(ALL(A), greater<i64>());

  sort(ALL(B), greater<i64>());

  sort(ALL(C), greater<i64>());

  auto solve = [&](i32 P) {

    i32 cnt = 0;

    REP(u, x) {

      REP(v, y) {

        REP(w, z) {

          if (A[u] + B[v] + C[w] < P) break;

          cnt++;

          if (cnt >= k) return true;

        }

      }

    }

    return false;

  };

  i64 l = 0;

  i64 r = A[0] + B[0] + C[0];

  while (l < r) {

    i64 m = (l + r + 1) / 2;

    if (solve(m)) {

      l = m;

    } else {

      r = m - 1;

    }

  }

  vector<i64> ans;

  REP(u, x) {

    REP(v, y) {

      REP(w, z) {

        i64 p = A[u] + B[v] + C[w];

        if (p < l) break;

        if (p >= l) ans.push_back(p);

      }

    }

  }

  sort(ALL(ans), greater<i64>());

  REP(i, k) {

    cout << ans[i] << endl;

  }

}

// Faster C++ solution for the same problem (measured speedup: 1.1009573368295376x):
#include <cstdio>

#include <algorithm>

#include <set>

using namespace std;



using i32 = int;

using i64 = long long;



#define REP(i, stop) for (int i = 0; i < stop; ++i)



template<typename T>

T read() {

  T a = 0;

  register int c;

  for(;;) {

    c = getchar_unlocked();

    if (c & 16) {

      a = a * 10 + c - 48;

    } else {

      return a;

    }

  }

}



void writeln(i64 a) {

  char buf[20];

  register int i = 0;

  // if (a <= 0)

  while (a > 0) {

    buf[i] = a % 10;

    a = a / 10;

    ++i;

  }

  while (i > 0) {

    --i;

    putchar_unlocked(buf[i] + 48);

  }

  putchar_unlocked('\n');

}



i64 A[1000], B[1000], C[1000];

i64 AB[3000];

signed main() {

  i32 X = read<i32>(),

      Y = read<i32>(),

      Z = read<i32>(),

      K = read<i32>();

  REP(i, X) A[i] = -read<i64>();

  REP(i, Y) B[i] = -read<i64>();

  REP(i, Z) C[i] = -read<i64>();

  sort(A, A + X);

  sort(B, B + Y);

  sort(C, C + Z);

  using P = pair<i64, i32>;

  set<P> Q, R;

  Q.insert({A[0] + B[0], 0});

  i32 L = min(K, X * Y);

  REP(i, L) {

    i64 p = (*Q.begin()).first;

    i64 q = (*Q.begin()).second;

    AB[i] = p;

    Q.erase(Q.begin());

    i32 u = q >> 10;

    i32 v = q & 1023;

    if (u + 1 < X && (u + 1) * v < L) Q.insert({A[u + 1] + B[v], q + 1024});

    if (v + 1 < Y && u * (v + 1) < L) Q.insert({A[u] + B[v + 1], q + 1});

  }

  R.insert({AB[0] + C[0], 0});

  REP(_, K) {

    i64 p = (*R.begin()).first;

    i64 q = (*R.begin()).second;

    // printf("%lld\n", -p);

    writeln(-p);

    R.erase(R.begin());

    i32 u = q >> 10;

    i32 v = q & 1023;

    if (u + 1 < L && (u + 1) * v < K) R.insert({AB[u + 1] + C[v], q + 1024});

    if (v + 1 < Z && u * (v + 1) < K) R.insert({AB[u] + C[v + 1], q + 1});

  }

}