interface Expr {
}

final class ValExpr implements Expr {
  long value;
  ValExpr(long i) {
    value = i;
  }
}

final class VarExpr implements Expr {
  String name;
  VarExpr(String s) {
    name = s;
  }
}

final class LnExpr implements Expr {
  Expr expr;
  LnExpr(Expr e) {
    expr = e;
  }
}

final class AddExpr implements Expr {
  Expr left;
  Expr right;
  AddExpr(Expr l, Expr r) {
    left = l;
    right = r;
  }
}

final class MulExpr implements Expr {
  Expr left;
  Expr right;
  MulExpr(Expr l, Expr r) {
    left = l;
    right = r;
  }
}

final class PowExpr implements Expr {
  Expr left;
  Expr right;
  PowExpr(Expr l, Expr r) {
    left = l;
    right = r;
  }
}



public class deriv {
  static long pown(long x, long n) {
    if (n==0) return 1;
    else if (n == 1) return x;
    else {
      long y = pown(x, n/2);
      return (y * y * (n%2 == 0 ? 1 : x));
    }
  }

  static Expr add( Expr x, Expr y ) {
    if (x instanceof ValExpr a && y instanceof ValExpr b) {
      return new ValExpr( a.value + b.value );
    }
    else if (x instanceof ValExpr a && a.value == 0) {
      return y;
    }
    else if (y instanceof ValExpr b && b.value == 0) {
      return x;
    }
    else if (y instanceof ValExpr b) {
      return add(y,x);
    }
    else if (x instanceof ValExpr a && y instanceof AddExpr b && b.left instanceof ValExpr bl) {
      return add(new ValExpr(a.value + bl.value), b.right);
    }
    else if (y instanceof AddExpr b && b.left instanceof ValExpr) {
      return add(b.left, add(x,b.right));
    }
    else if (x instanceof AddExpr a) {
      return add(a.left, add(a.right,y));
    }
    else {
      return new AddExpr(x,y);
    }
  }

  static Expr mul( Expr x, Expr y ) {
    if (x instanceof ValExpr a && y instanceof ValExpr b) {
      return new ValExpr( a.value * b.value );
    }
    else if (x instanceof ValExpr a && a.value == 0) {
      return x;
    }
    else if (y instanceof ValExpr b && b.value == 0) {
      return y;
    }
    else if (x instanceof ValExpr a && a.value == 1) {
      return y;
    }
    else if (y instanceof ValExpr b && b.value == 1) {
      return x;
    }
    else if (y instanceof ValExpr b) {
      return mul(y,x);
    }
    else if (x instanceof ValExpr a && y instanceof MulExpr b && b.left instanceof ValExpr bl) {
      return mul(new ValExpr(a.value * bl.value), b.right);
    }
    else if (y instanceof MulExpr b && b.left instanceof MulExpr) {
      return mul(b.left, mul(x,b.right));
    }
    else if (x instanceof MulExpr a) {
      return mul(a.left, mul(a.right,y));
    }
    else {
      return new MulExpr(x,y);
    }
  }

  static Expr powr( Expr x, Expr y ) {
    if (x instanceof ValExpr a && y instanceof ValExpr b) {
      return new ValExpr(pown(a.value,b.value));
    }
    else if (y instanceof ValExpr b && b.value == 0) {
      return new ValExpr(1);
    }
    else if (y instanceof ValExpr b && b.value == 1) {
      return x;
    }
    else if (x instanceof ValExpr a && a.value == 0) {
      return new ValExpr(0);
    }
    else {
      return new PowExpr(x,y);
    }
  }

  static Expr ln( Expr x ) {
    if (x instanceof ValExpr a && a.value == 1) {
      return new ValExpr(0);
    }
    else {
      return new LnExpr(x);
    }
  }

  static Expr d( String x, Expr e  ) {
    if (e instanceof ValExpr) {
      return new ValExpr(0);
    }
    else if (e instanceof VarExpr a) {
      return new ValExpr(a.name == x ? 1 : 0);
    }
    else if (e instanceof AddExpr a) {
      Expr f = a.left;
      Expr g = a.right;
      return add(d(x,f),d(x,g));
    }
    else if (e instanceof MulExpr a) {
      Expr f = a.left;
      Expr g = a.right;
      return add(mul(f,d(x,g)),mul(g,d(x,f)));
    }
    else if (e instanceof PowExpr a) {
      Expr f = a.left;
      Expr g = a.right;
      return mul(powr(f,g),add(mul(mul(g,d(x,f)),powr(f,new ValExpr(-1))),mul(ln(f),d(x,g))));
    }
    else if (e instanceof LnExpr a) {
      Expr f = a.expr;
      return mul(d(x,f),powr(f,new ValExpr(-1)));
    }
    else {
      return e;
    }
  }

  static long count( Expr e  ) {
    if (e instanceof ValExpr) {
      return 1;
    }
    else if (e instanceof VarExpr) {
      return 1;
    }
    else if (e instanceof AddExpr a) {
      Expr f = a.left;
      Expr g = a.right;
      return count(f) + count(g);
    }
    else if (e instanceof MulExpr a) {
      Expr f = a.left;
      Expr g = a.right;
      return count(f) + count(g);
    }
    else if (e instanceof PowExpr a) {
      Expr f = a.left;
      Expr g = a.right;
      return count(f) + count(g);
    }
    else if (e instanceof LnExpr a) {
      Expr f = a.expr;
      return count(f);
    }
    else {
      return 0;
    }
  }

  static Expr deriv( long i, Expr e) {
    Expr f = d("x",e);
    System.out.println( (i+1) + " count: " + count(f) );
    return f;
  }

  static Expr nest( long s, Expr e) {
    long n = s;
    while(n > 0) {
      e = deriv(s - n, e);
      n--;
    }
    return e;
  }

  public static void main(String args[])
  {
    Expr x = new VarExpr("x");
    Expr e = powr(x,x);
    nest(Integer.parseInt(args[0]),e);
    System.out.println( "done" );
  }
}
