#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define Status int
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define OK 1
#define ERROR 0
#define INFEASIBLE  -1
#define OVERFLOW  -2
typedef struct BiTNode
{
    char data;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
struct Binary_Tree
{
    void creat(BiTree &Tree)
    {
        char data;cin>>data;
        if(data=='0'){Tree=NULL;return ;}
        Tree=(BiTree)malloc(sizeof(BiTNode));
        Tree->data=data;
        creat(Tree->lchild);
        creat(Tree->rchild);
    }
    int leaf(BiTree Tree)
    {
        if(Tree==NULL)return 0;
        if(Tree->lchild==NULL && Tree->rchild==NULL)return 1;
        return leaf(Tree->lchild)+leaf(Tree->rchild);
    }
    int Treedeep(BiTree Tree,int deep)
    {
        if(Tree==NULL)return deep;
        return max(Treedeep(Tree->lchild,deep+1),Treedeep(Tree->rchild,deep+1));
    }
    void dfs_pre(BiTree Tree)
    {
        if(Tree==NULL){return ;}
        printf("%c",Tree->data);
        dfs_pre(Tree->lchild);
        dfs_pre(Tree->rchild);
    }
    void dfs_mid(BiTree Tree)
    {
        if(Tree==NULL){return ;}
        dfs_mid(Tree->lchild);
        printf("%c",Tree->data);
        dfs_mid(Tree->rchild);
    }
    void dfs_rear(BiTree Tree)
    {
        if(Tree==NULL){return ;}
        dfs_rear(Tree->lchild);
        dfs_rear(Tree->rchild);
        printf("%c",Tree->data);
    }
    void bfs_pre(BiTree Tree)
    {
        stack<BiTree>Stack;
        BiTree p=Tree;
        while(p!=NULL||!Stack.empty())
        {
            if(p)
            {
                printf("%c",p->data);
                Stack.push(p);
                p=p->lchild;
            }
            else 
            {
                p=Stack.top();
                Stack.pop();
                p=p->rchild;
            }
        }
    }
    void bfs_mid(BiTree Tree)
    {
        stack<BiTree>Stack;
        BiTree p=Tree;
        BiTree q=(BiTree)malloc(sizeof(BiTNode));
        while(p!=NULL||!Stack.empty())
        {
            if(p)
            {
                Stack.push(p);
                p=p->lchild;
            }
            else 
            {
                q=Stack.top();
                Stack.pop();
                printf("%c",q->data);
                p=q->rchild;
            }
        }
    }
    void bfs_rear(BiTree Tree)
    {
        stack<BiTree>Stack;
        Stack.push(Tree);
        BiTree pre,cur;
        cur=pre=NULL;
        while(!Stack.empty())
        {
            cur=Stack.top();
            if((cur->lchild == NULL && cur->rchild == NULL) || (pre != NULL && (pre == cur->lchild || pre == cur->rchild)))
            {
                printf("%c",cur->data);
                cur=Stack.top();
                Stack.pop();
                pre=cur;
            }
            else 
            {
                if(cur->rchild!=NULL)Stack.push(cur->rchild);
                if(cur->lchild!=NULL)Stack.push(cur->lchild);
            }
        }
    }
};
int main()
{
    Binary_Tree root;
    BiTree Tree;
    root.creat(Tree);
    printf("leaf: %d\n",root.leaf(Tree));
    printf("deep: %d\n",root.Treedeep(Tree,0));
    printf("dfs_pre: "); root.dfs_pre(Tree);puts("\n");
    printf("bfs_pre: "); root.bfs_pre(Tree);puts("\n");
    printf("dfs_mid: "); root.dfs_mid(Tree);puts("\n");
    printf("bfs_mid: "); root.bfs_mid(Tree);puts("\n");
    printf("dfs_rear: "); root.dfs_rear(Tree);puts("\n");
    printf("bfs_rear: ");root.bfs_rear(Tree);puts("\n");
}
// 1 1 1 0 0 1 1 0 1 0 0 1 0 0 0
// A B C 0 0 D E 0 G 0 0 F 0 0 0
// - + a 0 0 * b 0 0 - c 0 0 d 0 0 / e 0 0 f 0 0