use std::ops::DivAssign;
use std::ops::MulAssign;
use std::ops::SubAssign;
use std::collections::BinaryHeap;
use std::str::FromStr;
use std::collections::HashSet;
use std::collections::BTreeMap;
use std::fmt::Display;
use std::ops::Neg;
use std::ops::Div;
use std::ops::Mul;
use std::ops::Add;
use std::ops::{AddAssign, Sub};
use std::cmp::max;
use std::collections::VecDeque;
use std::cmp::min;
use std::collections::{HashMap, BTreeSet};
use std::cmp::Ordering;
use std::fmt::Debug;

fn read_line() -> String {
    let mut buffer = String::new();
    std::io::stdin().read_line(&mut buffer).expect("No Line");
    buffer.trim().to_owned()
}
fn read_lines<T: std::str::FromStr>(count: usize) -> Vec<T> {
    let mut buffer = String::new();
    let mut vec = Vec::with_capacity(count);
    for _ in 0 .. count {
        std::io::stdin().read_line(&mut buffer).expect("No Line");
        vec.push(buffer.trim().parse().ok().expect("Can't Parse"));
        buffer.clear();
    }
    vec
}
fn read_tabulate<R, T: Fn(&str)->R> (count: usize, transformer: T) -> Vec<R> {
    let mut buffer = String::new();
    let mut vec = Vec::with_capacity(count);
    for _ in 0 .. count {
        std::io::stdin().read_line(&mut buffer).expect("No Line");
        vec.push(transformer(buffer.trim()));
        buffer.clear();
    }
    vec
}
fn read_value<T: std::str::FromStr>() -> T {
    read_line().trim().parse().ok().unwrap()
}
fn read_values<T: std::str::FromStr>() -> Vec<T> {
    read_line().trim().split_whitespace().map(|x| x.parse().ok().expect("Can't Parse")).collect::<Vec<T>>()
}
macro_rules! freeze {
    ($($id:ident), *) => {
        $(let $id = $id;)*
    };
}
macro_rules! read_map {
    ($ident: ident: [$block: block; $size: expr]) => {
        let $ident = (0 .. $size).into_iter().map(|_| $block).collect::<Vec<_>>();
    };
    (mut $ident: ident: [$block: block; $size: expr]) => {
        let mut $ident = (0 .. $size).into_iter().map(|_| $block).collect::<Vec<_>>();
    };
}
macro_rules! read {
    (mut $ident: ident: String) => {
        let mut $ident = read_value::<String>();
    };
    ($ident: ident: String) => {
        let $ident = read_value::<String>();
    };
    (mut $ident: ident: [$ty:ty]) => {
        let mut $ident = read_values::<$ty>();
    };
    ($ident: ident: [$ty:ty]) => {
        let $ident = read_values::<$ty>();
    };
    (mut $ident: ident: [[$ty:ty]; $size: expr]) => {
        let mut $ident = (0 .. $size).into_iter().map(|_| read_values::<$ty>()).collect::<Vec<_>>();
    };
    ($ident: ident: [[$ty:ty]; $size: expr]) => {
        let $ident = (0 .. $size).into_iter().map(|_| read_values::<$ty>()).collect::<Vec<_>>();
    };
    (mut $ident: ident: [$ty:ty; $size:expr]) => {
        let mut $ident = read_lines::<$ty>($size);
    };
    ($ident: ident: [$ty:ty; $size:expr]) => {
        let $ident = read_lines::<$ty>($size);
    };
    ($ident: ident: [$block: block; $size: expr]) => {
        let $ident = (0 .. $size).into_iter().map(|_| $block).collect::<Vec<_>>();
    };
    (mut $ident: ident: [$block: block; $size: expr]) => {
        let mut $ident = (0 .. $size).into_iter().map(|_| $block).collect::<Vec<_>>();
    };
    ($($token: tt)*) => {
        let mut iter = read_values::<String>().into_iter();
        read_from_iter!(iter; $($token)*);
    };
}
macro_rules! read_from_iter {
    ($iter:expr; mut $ident:ident:$ty:ty, $($rest:tt)*) => {
        let mut $ident = $iter.next().unwrap().parse::<$ty>().expect("Can't Parse");
        read_from_iter!($iter; $($rest)*);
    };
    ($iter:expr; $ident:ident:$ty:ty, $($rest:tt)*) => {
        let $ident = $iter.next().unwrap().parse::<$ty>().expect("Can't Parse");
        read_from_iter!($iter; $($rest)*);
    };
    ($iter:expr; mut $ident:ident:$ty:ty) => {
        let mut $ident = $iter.next().unwrap().parse::<$ty>().expect("Can't Parse");
    };
    ($iter:expr; $ident:ident:$ty:ty) => {
        let $ident = $iter.next().unwrap().parse::<$ty>().expect("Can't Parse");
    };
    ($iter: expr; ) => {};
}
struct KeyValue<K, V> {
    key: K,
    value: V
}
impl <K: PartialOrd, V> PartialEq for KeyValue<K, V> {
    fn eq(&self, other: &Self) -> bool {
        self.key.eq(&other.key)
    }
}
impl <K: PartialOrd, V> Eq for KeyValue<K, V> {}
impl <K: PartialOrd, V> PartialOrd for KeyValue<K, V> {
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
        self.key.partial_cmp(&other.key)
    }
}
impl <K: PartialOrd, V> Ord for KeyValue<K, V> {
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
        self.key.partial_cmp(&other.key).ok_or("Can't Compare").unwrap()
    }
}
#[derive(Copy, Clone, Debug)]
struct PageConfig {
    plen: usize, cnum: usize, width: usize, cspace: usize
}
#[derive(Copy, Clone, Debug, Default)]
struct Cursor {
    current_page: usize, current_column: usize, current_row: usize, pos: usize
}
impl Cursor {
    fn succ(&mut self, config: PageConfig) {
        self.pos += 1;
        self.normalize(config);
    }
    fn succ_newline(&mut self, config: PageConfig) {
        self.current_row += 1;
        self.pos = 0;
        self.normalize(config);
    }
    fn normalize(&mut self, config: PageConfig) {
        if self.pos >= config.width {
            self.current_row += self.pos / config.width;
            self.pos %= config.width;
        }
        if self.current_row >= config.plen {
            self.current_column += self.current_row / config.plen;
            self.current_row %= config.plen;
        }
        if self.current_column >= config.cnum {
            self.current_page += self.current_column / config.cnum;
            self.current_column %= config.cnum;
        }
    }
}
#[derive(Clone, Debug)]
struct Page {
    config: PageConfig,
    lines: Vec<Vec<char>>,
    cursor: Cursor
}
impl Display for Page {
    fn fmt<'a>(&self, fmt: &mut std::fmt::Formatter<'a>) -> std::result::Result<(), std::fmt::Error> { 
        self.lines.iter().fold(Ok(()), |fr, line| {
            match fr {
                Ok(_) => {
                    match line.iter().fold(fr, |f, c| {
                        match f {
                            Ok(_) => write!(fmt, "{}", c),
                            _ => f
                        }
                    }) {
                        Ok(_) => write!(fmt, "\n"),
                        n => n
                    }
                }
                _ => fr
            }
        })
     }
}
impl Page {
    fn new(config: PageConfig) -> Page {
        Page{config: config, lines: vec![vec!['.'; config.width * config.cnum + (config.cnum - 1) * config.cspace]; config.plen], cursor: Cursor::default()}
    }
    fn write<'a>(&mut self, word: &'a str) -> Result<(), &'a str> {
        if self.cursor.current_page > 0 {return Err(&word); }
        let mut i = 0;
        for c in word.chars() {
            let row = self.cursor.current_row;
            let column = self.cursor.current_column * (self.config.width + self.config.cspace) + self.cursor.pos;
            self.lines[row][column] = c;
            self.cursor.succ(self.config);
            i += 1;
            if self.cursor.current_page > 0 && word.len() != i {
                return Err(&word[i..]);
            }
        }
        if word.len() == 0 || self.cursor.pos > 0 {
            self.cursor.succ_newline(self.config);
        }
        Ok(())
    }
}
#[derive(Clone, Debug)]
struct Note {
    config: PageConfig,
    pages: Vec<Page>,
    written_len: usize
}
impl Note {
    fn new(config: PageConfig) -> Note {
        Note{config: config, pages: vec![Page::new(config)], written_len: 0}
    }
    fn write(&mut self, word: String) {
        let mut input = &word[..];
        while let Err(rest) = self.pages.last_mut().unwrap().write(input) {
            input = rest;
            self.pages.push(Page::new(self.config));
        }
        self.written_len += word.len();
    }
}
impl Display for Note {
    fn fmt<'a>(&self, fmt: &mut std::fmt::Formatter<'a>) -> std::result::Result<(), std::fmt::Error> { 
        if self.written_len == 0 {
            write!(fmt, "")
        }else {
            write!(fmt, "{}#", self.pages.iter().map(|page| page.to_string()).collect::<Vec<_>>().join("#\n"))
        }
     }
}

fn main() {
    loop {
        read!(plen: usize);
        if plen == 0 {break; }
        read!(cnum: usize);
        read!(width: usize);
        read!(cspace: usize);
        let mut note = Note::new(PageConfig{plen: plen, cnum: cnum, width: width, cspace: cspace});
        loop {
            read!(word: String);
            if word == "?" {break; }
            note.write(word);
        }
        if note.written_len > 0 {
            println!("{}\n?", note);
        }else {
            println!("?");
        }
    }
}


Measured memory_bytes: 5044