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.


main: 
        {((0 0) (0 1) (0 2)
        (0 3) (0 4) (1 0)
        (1 1) (1 2) (1 3)
        (1 4) (2 0) (2 1)
        (2 2) (2 3) (3 0)
        (3 1) (3 2) (4 0)) 
 
        { dup
        "A(" << { %d " " . << } ... ") = " <<
    reverse give 
    ack 
    %d cr << } ... }
 
ack!: 
    { dup zero?
        { <-> dup zero?
            { <-> 
                cp
                1 -
                <- <- 1 - ->
                ack -> 
                ack }
            { <->
                1 - 
                <- 1 -> 
                ack }
        if }
        { zap 1 + }
    if }
 
zero?!: { 0 = }
 