Problem: Consider a data structure called BUT (Binary and/or Unary Tree). A BUT is defined inductively as follows:

* Let l be a letter of the English alphabet, either lowercase or uppercase (n the sequel, we say simply "a letter"). Then, the object that consists only of l, designating l as its label, is a BUT. In this case, it is called a 0-ary BUT.
* Let l be a letter and C a BUT. Then, the object that consists of l and C, designating l as its label and C as its component, is a BUT. In this case, it is called a unary BUT.
* Let l be a letter, L and R BUTs. Then, the object that consists of l, L and R, designating l as its label, L as its left component, and R as its right component, is a BUT. In this case, it is called a binary BUT.



A BUT can be represented by a expression in the following way.

* When a BUT B is 0-ary, its representation is the letter of its label.
* When a BUT B is unary, its representation is the letter of its label followed by the parenthesized representation of its component.
* When a BUT B is binary, its representation is the letter of its label, a left parenthesis, the representation of its left component, a comma, the representation of its right component, and a right parenthesis, arranged in this order.



Here are examples:


a
A(b)
a(a,B)
a(B(c(D),E),f(g(H,i)))


Such an expression is concise, but a diagram is much more appealing to our eyes. We prefer a diagram:


D  H i
-  ---
c E g
--- -
B  f
----
a


to the expression


a(B(c(D),E),f(g(H,i)))


Your mission is to write a program that converts the expression representing a BUT into its diagram. We want to keep a diagram as compact as possible assuming that we display it on a conventional character terminal with a fixed pitch font such as Courier. Let's define the diagram D for BUT B inductively along the structure of B as follows:


* When B is 0-ary, D consists only of a letter of its label. The letter is called the root of D, and also called the leaf of D
* When B is unary, D consists of a letter l of its label, a minus symbol S, and the diagram C for its component, satisfying the following constraints:
* l is just below S
* The root of C is just above S
l is called the root of D, and the leaves of C are called the leaves of D.
* When B is binary, D consists of a letter l of its label, a sequence of minus symbols S, the diagram L for its left component, and the diagram R for its right component, satisfying the following constraints:
* S is contiguous, and is in a line.
* l is just below the central minus symbol of S, where, if the center of S locates on a minus symbol s, s is the central, and if the center of S locates between adjacent minus symbols, the left one of them is the central.
* The root of L is just above the left most minus symbols of S, and the rot of R is just above the rightmost minus symbol of S
* In any line of D, L and R do not touch or overlap each other.
* No minus symbols are just above the leaves of L and R.
l is called the root of D, and the leaves of L and R are called the leaves of D



Input

The input to the program is a sequence of expressions representing BUTs. Each expression except the last one is terminated by a semicolon. The last expression is terminated by a period. White spaces (tabs and blanks) should be ignored. An expression may extend over multiple lines. The number of letter, i.e., the number of characters except parentheses, commas, and white spaces, in an expression is at most 80.

You may assume that the input is syntactically correct and need not take care of error cases.

Output

Each expression is to be identified with a number starting with 1 in the order of occurrence in the input. Output should be produced in the order of the input.

For each expression, a line consisting of the identification number of the expression followed by a colon should be produced first, and then, the diagram for the BUT represented by the expression should be produced.

For diagram, output should consist of the minimum number of lines, which contain only letters or minus symbols together with minimum number of blanks required to obey the rules shown above.

Examples

Input

a(A,b(B,C));
x( y( y( z(z), v( s, t ) ) ), u ) ;

a( b( c,
      d(
         e(f),
         g
       )
    ),
   h( i(
         j(
            k(k,k),
            l(l)
          ),
         m(m)
       )
    )
 );

a(B(C),d(e(f(g(h(i(j,k),l),m),n),o),p))
.


Output

1:
 B C
 ---
A b
---
 a
2:
z s t
- ---
z  v
----
 y
 -
 y u
 ---
  x
3:
   k k l
   --- -
 f  k  l m
 -  ---- -
 e g j   m
 --- -----
c d    i
---    -
 b     h
 -------
    a
4:
j k
---
 i l
 ---
  h m
  ---
   g n
   ---
    f o
    ---
   C e p
   - ---
   B  d
   ----
    a


Input

a(A,b(B,C));
x( y( y( z(z), v( s, t ) ) ), u ) ;

a( b( c,
d(
e(f),
g
)
),
h( i(
j(
k(k,k),
l(l)
),
m(m)
)
)
);

a(B(C),d(e(f(g(h(i(j,k),l),m),n),o),p))
.


Output

1:
B C
---
A b
---
a
2:
z s t
- ---
z  v
----
y
-
y u
---
x
3:
k k l
--- -
f  k  l m
-  ---- -
e g j   m
--- -----
c d    i
---    -
b     h
-------
a
4:
j k
---
i l
---
h m
---
g n
---
f o
---
C e p
- ---
B  d
----
a

Solution (in CPP):

Solution:
#include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cerr<<*i<<" "; cerr<<endl; }
inline bool valid(int x, int y, int W, int H){ return (x >= 0 && y >= 0 && x < W && y < H); }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
struct Node{
  char label;
  Node *left, *right;
  Node(char label) : label(label), left(NULL), right(NULL) {}
};
struct Result{
  Node* value;
  int p;
  Result(Node* value, int p) :
    value(value), p(p) {}
};
struct Diag{
  char label;
  Diag *left, *right;
  int ld, rd;
  vector< pair<int, int> > v;
  Diag(char label) :
    label(label), left(NULL), right(NULL), ld(0), rd(0), v(0) {}
};

Result parse(const string& s, int p){
  Node* node = new Node(s[p]);
  if(s[p + 1] == '('){
    Result l_res = parse(s, p + 2);
    node->left = l_res.value;
    if(s[l_res.p] == ','){ //A(B, C)
      Result r_res = parse(s, l_res.p + 1);
      node->right = r_res.value;
      assert(s[r_res.p] == ')');
      return Result(node, r_res.p + 1);
    }else if(s[l_res.p] == ')'){ //A(B)
      return Result(node, l_res.p + 1);
    }else{ // exception
      assert(false);
    }
  }else{
    return Result(node, p + 1);
  }
}
void print(Node* p){
  printf("label: %c ", p->label);
  if(p->left){
    printf("left: %c ", p->left->label);
  }
  if(p->right){
    printf("right: %c ", p->right->label);
  }
  cout<<endl;
  if(p->left){
    print(p->left);
  }
  if(p->right){
    print(p->right);
  }
}
bool is_0ary(Node* p){ return (!p->left && !p->right); }
bool is_1ary(Node* p){ return ( p->left && !p->right); }
bool is_2ary(Node* p){ return ( p->left &&  p->right); }
bool is_0ary(Diag* p){ return (!p->left && !p->right); }
bool is_1ary(Diag* p){ return ( p->left && !p->right); }
bool is_2ary(Diag* p){ return ( p->left &&  p->right); }
Diag* make_diag(Node* p){
  if(is_0ary(p)){
    Diag* d = new Diag(p->label);
    return d;
  }else if(is_1ary(p)){
    Diag* d = new Diag(p->label);
    d->left = make_diag(p->left);
    d->v.push_back(make_pair(0, 0));
    d->v.insert(d->v.end(), d->left->v.begin(), d->left->v.end());
    return d;
  }else if(is_2ary(p)){
    Diag* d = new Diag(p->label);
    d->left = make_diag(p->left);
    d->right = make_diag(p->right);
    int len = 3;
    for(int i = 0; i < min(d->left->v.size(), d->right->v.size()); i++){
        len = max(len, 3 + d->left->v[i].second - d->right->v[i].first);
      if(i + 1 < d->right->v.size()) 
        len = max(len, 2 + d->left->v[i].second - d->right->v[i + 1].first);
      if(i + 1 < d->left->v.size()) 
        len = max(len, 2 + d->left->v[i + 1].second - d->right->v[i].first);
    }
    if(d->left->v.empty() && d->right->v.size()) len = max(len, 2 - d->right->v[0].first);
    if(d->right->v.empty() && d->left->v.size()) len = max(len, 2 + d->left->v[0].second);
    int mid = (len - 1) / 2;
    d->ld = -mid;
    d->rd = len + d->ld - 1;
    d->v.push_back(make_pair(d->ld, d->rd));
    for(int i = 0; i < max(d->left->v.size(), d->right->v.size()); i++){
      int ld = INF, rd = -INF;
      if(i < d->left->v.size()) ld = min(ld, d->left->v[i].first + d->ld);
      if(i < d->left->v.size()) rd = max(rd, d->left->v[i].second + d->ld);
      if(i < d->right->v.size()) ld = min(ld, d->right->v[i].first + d->rd);
      if(i < d->right->v.size()) rd = max(rd, d->right->v[i].second + d->rd);
      d->v.push_back(make_pair(ld, rd));
    }
    return d;
  }else { // exception
    assert(false);
  }
}
void print(Diag* p){
  printf("label: %c ", p->label);
  if(is_0ary(p)) printf("ary:0 ");
  if(is_1ary(p)) printf("ary:1 ld: %d ", p->ld);
  if(is_2ary(p)) printf("ary:2 ld: %d rd: %d ", p->ld, p->rd);
  REP(i, p->v.size()) printf("(%d, %d) ", p->v[i].first, p->v[i].second);
  cout<<endl;
  if(p->left){
    print(p->left);
  }
  if(p->right){
    print(p->right);
  }
}
const int SW = 500;
const int SH = 200;
char str[SH][SW];
void make_str(int y, int x, Diag* p){
  assert(y >= 0);
  assert(y < SH);
  str[y * 2][x] = p->label;
  if(is_0ary(p)){
  }else if(is_1ary(p)){
    str[y * 2 + 1][x] = '-';
    make_str(y + 1, x, p->left);
  }else if(is_2ary(p)){
    for(int dx = p->ld; dx <= p->rd; dx++){
      assert(x + dx >= 0);
      assert(x + dx < SW);
      str[y * 2 + 1][x + dx] = '-';
    }
    make_str(y + 1, x + p->ld, p->left);
    make_str(y + 1, x + p->rd, p->right);
  }else {
    assert(false);
  }
}
void output(){
  for(int y = SH - 1; y >= 0; y--){
    int ex = SW;
    while(ex - 1 >= 0 && str[y][ex - 1] == ' ') ex--;
    if(ex == 0) continue;
    REP(x, ex) putchar(str[y][x]);
    putchar('\n');
  }
}

int main(){
  vector<string> BUTS;
  string s, tmp;
  while(cin >> tmp){
    s += tmp;
  }
  REP(i, s.size()) if(s[i] == ';') s[i] = ' ';
  REP(i, s.size()) if(s[i] == '.') s[i] = ' ';
  stringstream ss(s);
  while(ss >> tmp){
    BUTS.push_back(tmp);
  }
  REP(i, BUTS.size()){
    Result res = parse(BUTS[i], 0);
    Node* root = res.value;
    assert(res.p == BUTS[i].size());
    printf("%d:\n", i + 1);
    //cout<<BUTS[i]<<endl;
    //print(root);
    Diag* d = make_diag(root);
    //print(d);
    REP(y, SH) REP(x, SW) str[y][x] = ' ';
    int minld = 0;
    REP(i, d->v.size()) minld = min(minld, d->v[i].first);
    make_str(0, -minld, d);
    output();
  }
  return 0;
}