class Expr
{
    // Question 1.1

    int nature ;
    final static int INT=1, OP=2, VAR=3 ;

    // Entier :
    int intVal ;
    Expr (int i) {
        nature = INT ;
        intVal = i ;
    }

    // Op'eration :
    char op ;
    Expr left, right ;
    Expr (char o, Expr l, Expr r) {
        nature = OP ;
        op = o ;
        left = l ;
        right = r ;
    }

    // Variable :
    char var ;
    Expr (char v) {
        nature = VAR ;
        var = v ;
    }

    // Question 2

    static void printPrefix (Expr e) {
        switch (e.nature) {
            case INT: System.out.print (e.intVal) ; break ;
            case VAR: System.out.print (e.var) ; break ;
            case OP: 
                System.out.print (e.op + " ") ;
                printPrefix (e.left) ;
                System.out.print (" ") ;
                printPrefix (e.right) ;
                break ;
            default: 
                throw new Error ("Nature inconnue : " + e.nature) ;
        }
    }

    static void printInfix (Expr e) {
        switch (e.nature) {
            case INT: System.out.print (e.intVal) ; break ;
            case VAR: System.out.print (e.var) ; break ;
            case OP: 
                System.out.print ("(") ;
                printInfix (e.left) ;
                System.out.print (" " + e.op + " ") ;
                printInfix (e.right) ;
                System.out.print (")") ;
                break ;
            default: 
                throw new Error ("Nature inconnue : " + e.nature) ;
        }
    }

    static int value (Expr e) {
        switch (e.nature) {
            case INT: return e.intVal ;
            case VAR: 
                throw new Error ("Variable dans value() : " + e.var) ;
            case OP: 
                int vl = value (e.left) ;
                int vr = value (e.right) ;
                switch (e.op) {
                    case '+': return vl + vr ;
                    case '-': return vl - vr ;
                    case '*': return vl * vr ;
                    default:
                        throw new Error ("Op'eration inconnue : " + e.op) ;
                }
            default: 
                throw new Error ("Nature inconnue : " + e.nature) ;
        }
    }

    static Expr zero = new Expr (0) ;
    static Expr un = new Expr (1) ;

    static Expr derive (Expr e, char v) {
        switch (e.nature) {
            case INT: return zero ;
            case VAR: 
                if (e.var == v) return un ;
                else return zero ;
            case OP: 
                Expr dl = derive (e.left, v) ;
                Expr dr = derive (e.right, v) ;
                switch (e.op) {
                    case '+': return new Expr ('+', dl, dr) ;
                    case '-': return new Expr ('-', dl, dr) ;
                    case '*': 
                        return new Expr ('+', 
                                         new Expr ('*', dl, e.right),
                                         new Expr ('*', e.left, dr)) ;
                    default:
                        throw new Error ("Op'eration inconnue : " + e.op) ;
                }
            default: 
                throw new Error ("Nature inconnue : " + e.nature) ;
        }        
    }

    static char getChar () {
        try { // On essaye de lire un caract`ere par System.in.read() :
            return (char) System.in.read () ;
        } catch (java.io.IOException e) { // En cas de probl`eme :
            throw new Error ("Probl`eme d'entr'ee sortie.") ;
        } 
    }

    static Expr readPrefix () {
        char c = getChar () ;
        if (Character.isWhitespace (c))
            return readPrefix () ;
        if (Character.isDigit (c))
            return new Expr (Character.getNumericValue (c)) ;
        if (Character.isLetter (c))
            return new Expr (c) ;
        if (c == '+' || c == '-' || c == '*') {
            Expr l = readPrefix () ;
            Expr r = readPrefix () ;
            return new Expr (c, l, r) ;
        }
        throw new Error ("Caract`ere inattendu : " + c) ;
    }

}

class Calcul
{
    public static void main (String[] args) {
        Expr e1 = new Expr( '*', new Expr('x'), new Expr(10));
        Expr e2 = new Expr( '*',
                            new Expr( '*', 
                                      new Expr( '*', 
                                                new Expr(6), 
                                                new Expr( '+', 
                                                          new Expr( '-',
                                                                    new Expr(3),
                                                                    new Expr(2)),
                                                          new Expr(1))),
                                      new Expr( '-',
                                                new Expr(9),
                                                new Expr(6))),
                            new Expr(2));
        Expr.printPrefix (e1) ; System.out.println() ; 
        Expr.printPrefix (e2) ; System.out.println() ; 
        Expr.printInfix (e1) ; System.out.println() ; 
        Expr.printInfix (e2) ; System.out.println() ; 
        System.out.println (Expr.value(e2)) ;
        Expr.printInfix (Expr.derive (e1, 'x')) ; System.out.println() ; 
        Expr.printInfix (Expr.readPrefix ()) ; System.out.println() ; 
    }
}
