
#include <iostream>
#include <list>
#include <memory>
#include <string>
#include <sstream>
using namespace std;

class token {
public:
    virtual bool is_int() {
        return false;
    }

    virtual bool is_plus() {
        return false;
    }

    virtual bool is_star() {
        return false;
    }

    virtual int get_int_value() {
        cout << "Calling get int on non int token" << endl;
        return -1;
    }
};

class int_token : public token {
public:

    int val;
    bool is_int() {
        return true;
    }
    int get_int_value() {
        return val;
    }

    int_token(int value) {
        val = value;
    }
};

class plus_token : public token {
public:
    bool is_plus() {
        return true;
    }
};

class star_token : public token {
public:
    bool is_star() {
        return true;
    }
};

class Expr {
public:
    virtual int eval() = 0;

    virtual string format() = 0;
};

class NumExpr : public Expr {
public:
    NumExpr(int i) : val(i) {

    }

    int eval() {
        return val;
    }

    string format() {
        return to_string(val);
    }

private:
    int val;
};

class PlusExpr : public Expr {
    unique_ptr<Expr> left, right;

public:
    PlusExpr(unique_ptr<Expr> &&L, unique_ptr<Expr> &&R) :
        left(move(L)), right(move(R)) {}

    int eval() {
        return left->eval() + right->eval();
    }

    string format() {
        return left->format() + " + " + right->format();
    }
};

class MultExpr : public Expr {
    unique_ptr<Expr> left, right;

public:
    MultExpr(unique_ptr<Expr> &&L, unique_ptr<Expr> &&R) :
        left(move(L)), right(move(R)) {}

    int eval() {
        return left->eval() * right->eval();
    }

    string format() {
        return left->format() + " * " + right->format();
    }
};

using toklist = list<unique_ptr<token>>;
unique_ptr<Expr> parse_expr(toklist &t);

unique_ptr<Expr> parse_mul_expr(toklist &t) {
    unique_ptr<Expr> left = parse_expr(t);
    if (!t.empty() && t.front()->is_star()) {
        t.pop_front();
        unique_ptr<Expr> right = parse_mul_expr(t);
        return make_unique<MultExpr>(move(left), move(right));
    }
    return left;
}

unique_ptr<Expr> parse_add_expr(toklist &t) {
    unique_ptr<Expr> left = parse_mul_expr(t);
    if (!t.empty() && t.front()->is_plus()) {
        t.pop_front();
        unique_ptr<Expr> right = parse_add_expr(t);
        return make_unique<PlusExpr>(move(left), move(right));
    }
    return left;
}

unique_ptr<Expr> parse_expr(toklist &t) {
    if (!t.empty() && t.front()->is_int()) {
        int v = t.front()->get_int_value();
        t.pop_front();
        return make_unique<NumExpr>(v);
    }
    else {
        cerr << "Ran out of possibilities in parse_expr!" << endl;
        return unique_ptr<Expr>();
    }
}



list<unique_ptr<token>> tokenize()
{
    list<unique_ptr<token>> t;
    while (cin.good()) {
        string s;
        cin >> s;
        if (s == "*") t.push_back(make_unique<star_token>());
        else if (s == "+") t.push_back(make_unique<plus_token>());
        else if (s == "q") break;
        else {
            istringstream ss(s);
            int value;
            ss >> value;
            t.push_back(make_unique<int_token>(value));
        }
    }
   
    return t;
}

int main()
{
    auto l = tokenize();
    #if 1
    for (auto&i : l) {
        cout << typeid(*i).name() << endl;
    }
#endif

    unique_ptr<Expr> e = parse_add_expr(l);

    cout << e->format() << endl;
    cout << e->eval() << endl;

    return 0;
}

