text:
Calculate Knuth's up arrow notation
Inspired by Expand exponentation.
Knuth's up arrow notation is used for big numbers such as Graham's number.
If we look deeper, we can see how it makes big numbers.
One arrow means exponentiation. e.g. 2↑3 equals 2^3 = 8.
Two or more arrows means repeating the instructions of n-1 arrows. e.g. 2↑↑3 equals 2↑2↑2 equals 2^(2^2)=16.
You will be given three integers, n, a, and m. n is the first number, a is the amount of arrows, and m is the second number.
Your code should output the final answer, which is the calculation of n ↑a m(↑x means there are x up-arrows, where x is an integer)
Examples
2 1 2 -> 4
2 1 3 -> 8
2 2 3 -> 16
2 3 3 -> 65536

Related.

I'd suggest to add 3 2 2 and 3 2 3 as additional test cases.

APL, 22 bytes
{×⍺⍺:(⍺⍺-1)∇∇/⍵/⍺⋄⍺×⍵}

This is an operator that takes a as its operand (⍺⍺), and n and m as its left and right arguments (⍺ and ⍵).
Explanation:

×⍺⍺: if ⍺⍺ is positive:

⍵/⍺: replicate ⍺ ⍵ times
(⍺⍺-1)∇∇/: fold the ⍺⍺-1-arrow function over the list.

⋄: otherwise (i.e. if ⍺⍺ is zero):

⍺×⍵: multiply the arguments

Java 7, 121 bytes
int c(int n,int a,int m){return(int)(a<2?Math.pow(n,m):d(n,a));}double d(int n,int a){return Math.pow(n,a<2?n:d(n,a-1));}

Explanation:
int c(int n, int a, int m){         // Main method with the three integer-parameters as specified by OP's challenge
  return (int)                      // Math.pow returns a double, so we cast it to an integer
          (a < 2 ?                  // if (a == 1):
                   Math.pow(n, m)   //  Use n^m
                 :                  // else (a > 1):
                   d(n, a));        //  Use method d(n, a)
}

double d(int n, int a){             // Method d with two integer-parameters
  return Math.pow(n, a < 2          // n ^ X where
                      ? n           //  X = n    if (a == 1)
                      : d(n, a-1)); //  X = recursive call d(n, a-1)    if (a > 1)
}

// In pseudo-code:
c(n, a, m){
  if a == 1: return n^m
  if a > 1:  return d(n, a);
}
d(n, a){
  if a == 1: return n^n
  if a > 1:  return d(n, a-1);
}

Test code:
Try it here.
class M{
  static int c(int n,int a,int m){return(int)(a<2?Math.pow(n,m):d(n,a));}
  static double d(int n,int a){return Math.pow(n,a<2?n:d(n,a-1));}

  public static void main(String[] a){
    System.out.println(c(2, 1, 2));
    System.out.println(c(2, 1, 3));
    System.out.println(c(2, 2, 3));
    System.out.println(c(2, 3, 3));
  }
}

Output:
4
8
16
65536

Unless I'm missing something in the challenge definition, I don't think that m should be ignored when a > 1.

@Arnauld The way I read the challenge it is, unless I'm missing something.. :S I do get the correct output. How do you interpret OP's question, and could you come up with a test case where that interpretation would differ in terms of output compared to my pseudo-code explanation?

I think we should have 3 2 2 -> 3^3 = 27 and 3 2 3 -> 3^(3^3) = 7625597484987. (You can find these examples -- and more of them -- on Wikipedia)

JavaScript ES7, 53 44 bytes
f=(a,b,c)=>b<2||c<1?a**c:f(a,b-1,f(a,b,c-1))

f=(a,b,c)=>b<2||c<1?a**c:f(a,b-1,f(a,b,c-1))

console.log(f(2,1,2));
console.log(f(2,1,3));
console.log(f(2,2,3));
console.log(f(2,3,3));

Mathematica, 48 40 bytes
If[#3>1<#,#0[#0[#-1,##2],#2,#3-1],#2^#]&

Order of arguments is m, n, a (using the notation from the challenge).

julia, 41 38 bytes
f(a,n,b)=b>1< n?f(a,n-1,f(a,n,b-1)):a^b

Thanks to @Martin 3 bytes saved.
Try it online!
a,b : operands
n: number of arrows
Previous answer:
f(a,n,b)=n<2||b<1?a^b:f(a,n-1,f(a,n,b-1))

Modified formula from Wikipedia
Try it online!

You can save some bytes on the || by a) noting that b<2 also works, b) applying deMorgan to rewrite that as n>1&&b>1 (swapping the two branches of the ternary operator) and c) using inequality chaining on the 1: f(a,n,b)=b>1<n?f(a,n-1,f(a,n,b-1)):a^b