#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using vint = vector<int>;
using vvint = vector<vint>;
using pint = pair<int, int>;
using vpint = vector<pint>;
using vll = vector<ll>;
using vvll = vector<vll>;
using pll = pair<ll, ll>;
using vpll = vector<pll>;
#define repi(n) for (int i = 0; i < n; i++)
#define repj(n) for (int j = 0; j < n; j++)
#define repk(n) for (int k = 0; j < n; k++)
#define rep(i, n) for (int i = 0; i < n; i++)
#define repr(i, a, b) for (int i = a; i < b; i++)
#define repv(itr) for (auto&& v : itr)
#define swap(x, y)    \
  {                   \
    auto ___temp = x; \
    x = y;            \
    y = ___temp;      \
  }

const int dx[] = {-1, 0, 0, 1, -1, -1, 1, 1};
const int dy[] = {0, -1, 1, 0, -1, 1, -1, 1};
template <typename T>
T minptr(T begin, T end) {
  T re = begin;
  for (T i = begin + 1; i != end; i++) {
    if (*i < *re) re = i;
  }
  return re;
}
template <typename T>
T maxptr(T begin, T end) {
  T re = begin;
  for (T i = begin + 1; i != end; i++) {
    if (*i > *re) re = i;
  }
  return re;
}
int __vmax(int x) {
  return INT_MAX;
}
double __vmax(double x) {
  return 1e+300;
}
ll __vmax(ll x) {
  return LLONG_MAX;
}
int __vmin(int x) {
  return INT_MIN;
}
double __vmin(double x) {
  return -1e+300;
}
ll __vmin(ll x) {
  return LLONG_MIN;
}
template <typename T>
vector<T> lis(T begin, T end, bool allowequal = false, bool lds = false) {
  using V = typename iterator_traits<T>::value_type;
  int n = end - begin;
  vector<V> a(n, lds ? __vmin(*begin) : __vmax(*begin));
  vector<int> id(n);
  if (lds && allowequal) {
    for (int i = 0; i < n; i++) {
      id[i] = n - 1 -
              (lower_bound(a.rbegin(), a.rend(), begin[i]) - 1 - a.rbegin());
      a[id[i]] = begin[i];
    }
  } else if (lds) {
    for (int i = 0; i < n; i++) {
      id[i] = n - 1 -
              (upper_bound(a.rbegin(), a.rend(), begin[i]) - 1 - a.rbegin());
      a[id[i]] = begin[i];
    }
  } else if (allowequal) {
    for (int i = 0; i < n; i++) {
      id[i] = upper_bound(a.begin(), a.end(), begin[i]) - a.begin();
      a[id[i]] = begin[i];
    }
  } else {
    for (int i = 0; i < n; i++) {
      id[i] = lower_bound(a.begin(), a.end(), begin[i]) - a.begin();
      a[id[i]] = begin[i];
    }
  }
  int m = *maxptr(id.begin(), id.end());
  vector<T> re(m + 1);
  for (int i = n - 1; i >= 0; i--) {
    if (id[i] == m) re[m--] = begin + i;
  }
  return re;
}
template <typename T>
T gcd(T a, T b) {
  return b ? gcd(b, a % b) : a;
}

using V = struct V {
  ll value;
  int ai, bi, ci;
  V(ll value_, int ai_, int bi_, int ci_) {
    value = value_;
    ai = ai_;
    bi = bi_;
    ci = ci_;
  }
};
bool operator<(V a, V b) {
  if (a.value != b.value) return a.value > b.value;
  if (a.ai != b.ai) return a.ai < b.ai;
  if (a.bi != b.bi) return a.bi < b.bi;
  return a.ci < b.ci;
}
int main() {
  int x, y, z, k;
  cin >> x >> y >> z >> k;
  vll a(x), b(y), c(z);
  repi(x) cin >> a[i];
  repi(y) cin >> b[i];
  repi(z) cin >> c[i];
  sort(a.begin(), a.end(), greater<ll>());
  sort(b.begin(), b.end(), greater<ll>());
  sort(c.begin(), c.end(), greater<ll>());
  set<V> s;
  V sf(a[0] + b[0] + c[0], 0, 0, 0);
  s.insert(sf);
  repi(k) {
    auto sf = s.begin();
    auto v = sf->value;
    auto ai = sf->ai, bi = sf->bi, ci = sf->ci;
    cout << v << endl;
    if (ai + 1 < x) {
      V sf0(a[ai + 1] + b[bi] + c[ci], ai + 1, bi, ci);
      s.insert(sf0);
    }
    if (bi + 1 < y) {
      V sf0(a[ai] + b[bi + 1] + c[ci], ai, bi + 1, ci);
      s.insert(sf0);
    }
    if (ci + 1 < z) {
      V sf0(a[ai] + b[bi] + c[ci + 1], ai, bi, ci + 1);
      s.insert(sf0);
    }
    s.erase(sf);
  }
}


Measured memory_bytes: 512