#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cassert>
using namespace std;

#define MAXL 2100
#define MAXS 200

char buf[MAXL];
char out[MAXS][MAXS];

struct Bnode{
	Bnode *l, *r;
	Bnode(){ l = r = NULL; }
	~Bnode(){ delete l; delete r; }
};

char *ptr;

void parse(Bnode *x){
	assert(*ptr == '(');

	++ptr;
	if(*ptr == ')'){
		++ptr;
		return;
	}

	assert(*ptr == '(');
	x->l = new Bnode;
	parse(x->l);

	if(*ptr == ')'){
		++ptr;
		return;
	}

	assert(*ptr == '(');
	x->r = new Bnode;
	parse(x->r);

	assert(*ptr == ')');
	++ptr;
}

inline void put(int r, int c, char ch, bool flip){
	if(flip)
		out[c][r] = ch;
	else
		out[r][c] = ch;
}

void line(int c, int r1, int r2, bool flip){
	assert(r1 <= r2);
	for (int i=r1; i<=r2; ++i)
		put(i, c, i % 2 ? (flip ? '-' : '|') : '+', flip);
}

void draw(Bnode *x, int left, int top, bool flip, char mark, int &right, int &bottom, int &meR, int &meC){
	right = left;
	bottom = top;
	meR = top;
	meC = left;

	if(x->l != NULL){
		int lRight, lBottom, lRootR, lRootC;
		draw(x->l, top, left, !flip, 'L', lBottom, lRight, lRootC, lRootR);

		right = lRight + 2;
		bottom = lBottom;
		meR = lRootR;
		meC = lRight + 2;

		if(x->r != NULL){
			int rRight, rBottom, rRootR, rRootC;
			draw(x->r, top, meC + 2, !flip, 'R', rBottom, rRight, rRootC, rRootR);

			right = rRight;
			bottom = max(bottom, rBottom);
			if(mark != 'R')
				meR = max(meR, rRootR);
			else
				meR = min(meR, rRootR);

			line(meC, min(lRootR, rRootR), max(lRootR, rRootR), flip);
		}
	}

	put(meR, meC, mark, flip);

	if(mark == 'L')
		line(meC, meR + 1, bottom + 1, flip);
	else if(mark == 'R')
		line(meC, top - 1, meR - 1, flip);
}

int main(){
	fgets(buf, MAXL, stdin);
	Bnode *root = new Bnode;
	ptr = buf;
	parse(root);

        memset(out,'.',sizeof(out));

	int W, H, dumR, dumC;
	draw(root, 0, 0, false, 'H', W, H, dumR, dumC);

	printf("%d %d\n", H / 2 + 1, W / 2 + 1);
	for (int i=0; i<=H; ++i){
		for (int j=0; j<=W; ++j)
			putchar(out[i][j]);
		putchar('\n');
	}

	delete root;
}
