//my ac code:
#include <cstdio>
using namespace std;
int n,m,nm[55][55];
int ca[6]={2,1,0,0,0,0};int cb[6]={6,6,6,6,5,4};
//ca数组为长方体模型 cft数组中,各行前面有多少空格 cb数组为每行有多少字符
int mxx=0,mxy=0;//记录右下角最大的坐标,方便最后遍历
//记录是因为,要填充. ,在矩阵空白的地方,不标记就不知道空白结尾到哪
char cc[2505][2505];
char cft[8][8]={//按照题目,建立出一个长方体的模型
"  +---+",
" /   /|",
"+---+ |",
"|   | +",
"|   |/",
"+---+",
};
void jfz(int x,int y){
    for(int i=5;i>=0;i--){
        for(int j=ca[i];j<=cb[i];j++){
            cc[5-i+x][j+y]=cft[i][j];
            if(5-i+x>mxx)mxx=5-i+x;
            if(j+y>mxy)mxy=j+y;
        }
    }
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        for(int j=0;j<m;j++){
            scanf("%d",&nm[i][j]);
            //printf("%d",nm[i][j]);
        }
    for(int i=1;i<=n;i++)
        for(int j=0;j<m;j++)
            for(int k=0;k<nm[i][j];k++)
                jfz((n-i)*2+1+3*k,(n-i)*2+1+4*j);
    // 理解:(n-o)*2+1 表示前面有多少层,即:这个长方体在最里层还是。。。
    //如 样例,第一层数据,o=1算得  x=5,y=5,  然后传进fg函数,从下到上填充字符串数组
    //至于计算x中的3*l 是因为,如果有第二层,则 因为第一层的原因,只需要在上面盖三层就好了,计算y 如此类推
    for(int i=mxx;i>=1;i--){
        for(int j=1;j<=mxy;j++){
            if(cc[i][j]=='\0')printf(".");
            else printf("%c",cc[i][j]);
        }
        printf("\n");
    }
//最后x从大到小,y从小到大:因为存储长方体的时候是,倒过来存放的,可以随便带入一组数据看就知道了
    
//从下往上建,所以要倒序输出 ,(忘记了就看函数jfz,然后自己笔算一次
        
    
    
    return 0;
}