
#include <algorithm>
#include <iostream>
#include <memory>
#include <string>
#include <vector>

using namespace std;

struct token
{
	enum Type
	{
		integer,
		plus,
		times,
		par_open,
		par_close,
	};

	Type type;

	int number;

	token(Type type, int number = 0)
	  : type{ type }
	  , number{ number }
	{}

	std::string format() const
	{
		switch (type) {
			case token::integer:
				return std::to_string(number);
				break;
			case token::plus:
				return "+";
			case token::times:
				return "*";
			case token::par_open:
				return "(";
			case token::par_close:
				return ")";
			default:
				return "<invalid>";
		}
	}
};

vector<token>
tokenize(istream &in)
{
	vector<token> res;
	while (in) {
		int peek = in.peek();
		if (peek < 0)
			break;
		if (isspace(peek)) {
			in.get();
			continue;
		}
		if (peek >= '0' && peek <= '9') {
			int tmp;
			in >> tmp;
			res.emplace_back(token::integer, tmp);
			continue;
		}
		switch (peek) {
			case '(':
				res.emplace_back(token::par_open);
				break;
			case ')':
				res.emplace_back(token::par_close);
				break;
			case '+':
				res.emplace_back(token::plus);
				break;
			case '*':
				res.emplace_back(token::times);
				break;
			default:
				cerr << "I do not recognize the token: " << peek
				     << endl;
		}
		in.get();
	}
	return res;
}
class Expr
{
      public:
	virtual int eval() = 0;
	virtual string print() = 0;
};

class Num : public Expr
{
	int number;

      public:
	Num(int number)
	  : number(number)
	{}
	int eval() { return number; };
	string print() { return to_string(number); }
};

class BinaryOper : public Expr
{
      public:
	BinaryOper(unique_ptr<Expr> &&a, unique_ptr<Expr> &&b)
	  : left(std::move(a))
	  , right(std::move(b))
	{}

      protected:
	unique_ptr<Expr> left, right;
};

class Add : public BinaryOper
{
      public:
	int eval() { return left->eval() + right->eval(); }

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

class Multiply : public BinaryOper
{
      public:
	int eval() override { return left->eval() * right->eval(); }

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

using Pos = std::vector<token>::iterator;
unique_ptr<Expr>
parseExpr(Pos &begin, Pos &end)
{
	return parseAddExpr(begin, end);
}
unique_ptr<Expr>
parseAddExpr(Pos &begin, Pos &end)
{
	auto l = parseMultExpr(begin, end);
	if (!l || begin == end || begin->type != token::plus)
		return l;
	begin++;
	auto r = parseAddExpr(begin, end);
	if (!r) {
		begin--;
		return l;
	}
	return make_unique<Add>(move(l), move(r));
}

unique_ptr<Expr>
parseMultExpr(Pos &begin, Pos &end)
{}
int
main()
{
	auto tokens = tokenize(std::cin);

	std::for_each(tokens.begin(), tokens.end(), [](const auto &token) {
		std::cout << token.format() << "\n";
	});

	// for (auto&& t : tokens) std::cout << t.format() << std::endl;

	return 0;
}
