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.


 
PROGRAM ACKERMAN
 
!
! computes Ackermann function
! (second version for rosettacode.org)
!
 
!$INTEGER
 
DIM STACK[10000]
 
!$INCLUDE="PC.LIB"
 
PROCEDURE ACK(M,N->N)
  LOOP
    CURSOR_SAVE(->CURX%,CURY%) 
    LOCATE(8,1)
    PRINT("Livello Stack:";S;"  ")
    LOCATE(CURY%,CURX%)
    IF M<>0 THEN
       IF N<>0 THEN
           STACK[S]=M
           S+=1
           N-=1
        ELSE
           M-=1
           N+=1
        END IF
        CONTINUE LOOP
     ELSE
        N+=1
        S-=1
    END IF
    IF S<>0 THEN
        M=STACK[S]
        M-=1
        CONTINUE LOOP
      ELSE
        EXIT PROCEDURE
    END IF
  END LOOP
END PROCEDURE
 
BEGIN
   PRINT(CHR$(12);)
   FOR X=0 TO 3 DO
     FOR Y=0 TO 9 DO
        S=1
        ACK(X,Y->ANS)
        PRINT(ANS;)
     END FOR
     PRINT
   END FOR
END PROGRAM
 