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.


DEFINE MAXSIZE="1000"
CARD ARRAY stack(MAXSIZE)
CARD stacksize=[0]
 
BYTE FUNC IsEmpty()
  IF stacksize=0 THEN
    RETURN (1)
  FI
RETURN (0)
 
PROC Push(BYTE v)
  IF stacksize=maxsize THEN
    PrintE("Error: stack is full!")
    Break()
  FI
  stack(stacksize)=v
  stacksize==+1
RETURN
 
BYTE FUNC Pop()
  IF IsEmpty() THEN
    PrintE("Error: stack is empty!")
    Break()
  FI
  stacksize==-1
RETURN (stack(stacksize))
 
CARD FUNC Ackermann(CARD m,n)
  Push(m)
  WHILE IsEmpty()=0
  DO
    m=Pop()
    IF m=0 THEN
      n==+1
    ELSEIF n=0 THEN
      n=1
      Push(m-1)
    ELSE
      n==-1
      Push(m-1)
      Push(m)
    FI
  OD
RETURN (n)
 
PROC Main()
  CARD m,n,res
 
  FOR m=0 TO 3
  DO
    FOR n=0 TO 4
    DO
      res=Ackermann(m,n)
      PrintF("Ack(%U,%U)=%U%E",m,n,res)
    OD
  OD
RETURN