The Ackermann function is a classic example of a recursive function, notable especially because it is not a primitive recursive function. It grows very quickly in value, as does the size of its call tree.



The Ackermann function is usually defined as follows:







A
(
m
,
n
)
=


{



n
+
1



if 

m
=
0




A
(
m
−
1
,
1
)



if 

m
>
0

 and 

n
=
0




A
(
m
−
1
,
A
(
m
,
n
−
1
)
)



if 

m
>
0

 and 

n
>
0.








{\displaystyle A(m,n)={\begin{cases}n+1&{\mbox{if }}m=0\\A(m-1,1)&{\mbox{if }}m>0{\mbox{ and }}n=0\\A(m-1,A(m,n-1))&{\mbox{if }}m>0{\mbox{ and }}n>0.\end{cases}}}






Its arguments are never negative and it always terminates.



Task

Write a function which returns the value of 



A
(
m
,
n
)


{\displaystyle A(m,n)}

. Arbitrary precision is preferred (since the function grows so quickly), but not required.



See also

 Conway chained arrow notation for the Ackermann function.


/**
 Ackermann recursion, in Neko
 Tectonics:
    nekoc ackermann.neko
    neko ackermann 4 0
*/
ack = function(x,y) {
   if (x == 0) return y+1;
   if (y == 0) return ack(x-1,1);
   return ack(x-1, ack(x,y-1));
};
 
var arg1 = $int($loader.args[0]);
var arg2 = $int($loader.args[1]);
 
/* If not given, or negative, default to Ackermann(3,4) */
if (arg1 == null || arg1 < 0) arg1 = 3;
if (arg2 == null || arg2 < 0) arg2 = 4;
 
try
   $print("Ackermann(", arg1, ",", arg2, "): ", ack(arg1,arg2), "\n")
catch problem
   $print("Ackermann(", arg1, ",", arg2, "): ", problem, "\n")