#include <iostream>
#include <cstdlib>

class nodo {
	private:
		char info;
		nodo *izq;
		nodo *der;
	public:
		nodo(int inf, nodo *iz=NULL, nodo *de=NULL);
		~nodo(void);
		char Info(void) const { return info; };	
		nodo* copia(void) const;
		void enorden(void);
		void preorden(void);
		void postorden(void);
		nodo* deriv(void) const;
};

nodo::nodo(int inf, nodo *iz, nodo *de)
{
	info= inf;
	izq= iz;
	der= de;
}

nodo::~nodo(void)
{
	if (der!=NULL)
		delete der;
	if (izq!=NULL)
		delete izq;
}

void nodo::enorden(void)
{
	if (izq!=NULL)
		izq->enorden();
	std::cout << char(info);
	if (der!=NULL)
		der->enorden();
}

void nodo::preorden(void)
{
	std::cout << char(info);
	if (izq!=NULL)
		izq->preorden();
	if (der!=NULL)
		der->preorden();
}

void nodo::postorden(void)
{
	if (izq!=NULL)
		izq->postorden();
	if (der!=NULL)
		der->postorden();
	std::cout << char(info);
}

nodo* nodo::copia(void) const
{
	nodo *ci, *cd;
	if (izq==NULL)
		ci= NULL;
	else
		ci= izq->copia();

	if (der==NULL)
		cd= NULL;
	else
		cd= der->copia();

	return new nodo(info, ci, cd);
}



nodo* Leer(void)
{
	int c= std::cin.get();
	if (c=='.')
		return NULL;
	else {
		nodo *iz= Leer();
		nodo *de= Leer();
		return new nodo(c, iz, de);
	}
}

nodo* nodo::deriv(void) const
{
	if (isalpha(info))
		if (info=='x')
			return new nodo('1', NULL, NULL);
		else
			return new nodo('0', NULL, NULL);
	else
	if (isdigit(info))
		return new nodo('0', NULL, NULL);
	else 
		switch(info) {
			case '+': 
				return new nodo('+',
								izq->deriv(),
								der->deriv()
							);
			case '-': 
				return new nodo('-',
								izq->deriv(),
								der->deriv()
							);
			case '*':
				return new nodo('+', 
							new nodo('*', 
									izq->copia(), 
									der->deriv()),
							new nodo('*', 
									izq->deriv(), 
									der->copia())
						);
		}
	return NULL;
}

int main(int argc, char *argv[])
{
	nodo *p= Leer();
	nodo *d= p->deriv();
	d->postorden();
	delete d;
	delete p;
	return EXIT_SUCCESS;
}







