use std::cmp::*;
use std::collections::*;
use std::io::*;
use std::str::FromStr;
use utils::*;

pub fn main() {
    let i = stdin();
    let mut o = Vec::new();
    run(i.lock(), &mut o);
    stdout().write_all(&o).unwrap();
}

fn run<R: BufRead, W: Write>(i: R, o: &mut W) {
    let mut i = CpReader::new(i);
    let (x, y, z, k) = i.read4::<usize, usize, usize, usize>();
    let a = i.read_vec::<usize>(x);
    let b = i.read_vec::<usize>(y);
    let c = i.read_vec::<usize>(z);

    for r in solve([a, b, c], k) {
        writeln!(o, "{}", r).unwrap();
    }
}
fn solve(mut ds: [Vec<usize>; 3], k: usize) -> Vec<usize> {
    for d in ds.iter_mut() {
        d.sort();
        d.reverse();
    }

    fn insert(
        q: &mut BTreeSet<(RevCmp<usize>, [usize; 3])>,
        ds: &[Vec<usize>; 3],
        idxs: [usize; 3],
    ) {
        for i in 0..3 {
            if idxs[i] >= ds[i].len() {
                return;
            }
        }
        q.insert((
            RevCmp(ds[0][idxs[0]] + ds[1][idxs[1]] + ds[2][idxs[2]]),
            idxs,
        ));
    }

    let mut q = BTreeSet::new();
    insert(&mut q, &ds, [0, 0, 0]);

    let mut rs = Vec::with_capacity(k);
    for _ in 0..k {
        let &(r, idxs) = q.iter().next().unwrap();
        q.remove(&(r, idxs));
        rs.push(r.0);

        insert(&mut q, &ds, [idxs[0] + 1, idxs[1], idxs[2]]);
        insert(&mut q, &ds, [idxs[0], idxs[1] + 1, idxs[2]]);
        insert(&mut q, &ds, [idxs[0], idxs[1], idxs[2] + 1]);
    }
    rs
}

mod utils {
    use super::*;

    pub struct CpReader<R: BufRead> {
        r: R,
        s: String,
    }

    macro_rules! fn_read {
        { $f:ident($($t:ident),*) } => {
            #[allow(dead_code)]
            pub fn $f<$($t: FromStr),*>(&mut self) -> ($($t),*) {
                let i = &mut self.read_line().split(' ');
                ($(read_next::<$t,_>(i)),*)
            }
        };
    }

    impl<R: BufRead> CpReader<R> {
        pub fn new(r: R) -> Self {
            CpReader {
                r: r,
                s: String::new(),
            }
        }
        pub fn read_line(&mut self) -> &str {
            self.s.clear();
            self.r.read_line(&mut self.s).unwrap();
            self.s.trim()
        }

        fn_read! { read2(T1, T2) }
        fn_read! { read3(T1, T2, T3) }
        fn_read! { read4(T1, T2, T3, T4) }
        fn_read! { read5(T1, T2, T3, T4, T5) }

        pub fn read_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
            self.read_line()
                .split(' ')
                .take(n)
                .map(|x| x.parse().ok().unwrap())
                .collect()
        }
    }
    fn read_next<'a, T: FromStr, I: Iterator<Item = &'a str>>(i: &mut I) -> T {
        i.next().unwrap().parse().ok().unwrap()
    }

    // std::cmp::Reverseと同じ
    #[derive(PartialEq, Eq, Copy, Clone)]
    pub struct RevCmp<T>(pub T);

    impl<T: PartialOrd> PartialOrd for RevCmp<T> {
        fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
            other.0.partial_cmp(&self.0)
        }
    }
    impl<T: Ord> Ord for RevCmp<T> {
        fn cmp(&self, other: &Self) -> Ordering {
            other.0.cmp(&self.0)
        }
    }
}


Measured memory_bytes: 4352