You actually have only one array of ints (i.e. int arr1[][5]) and one pointer to a pointer of an int, i.e. int **arr2. Even if an array like arr1[10][5], when passed as argument to a function, decays to a pointer to the beginning of the memory where the elements reside, there is a (big) difference in memory layout and in the way how a compiler treats access to these pointers.
BTW, in main it should be int n=5,m=4;int arr1[m][n], not int n=5,m=4;int arr1[n][m]. 
Concerning memory layout:
A 2D integer array of the form int [10][5] is represented as 10 consecutive "rows", each comprising 5 "columns" (i.e. integral values). The size of this array is 10 * 5 * sizeof(int), and the size of one "row" is 5 * sizeof(int).
A pointer to a pointer to int int **p is just a single pointer; its size is sizeof(int**), even if you have "malloced" a sequence of integral pointers lile p = malloc(10 * sizeof (int*)); Note "*" in sizeof(int *), as you create a sequence of pointers to integers, not a sequence of integers. That's the main difference in memory layout: It's not a 2D array of integers, but a 1D array of pointers to integers. And if one actually had allocated 10 "rows" for "10" integers, each row could be located in a different portion of memory. The space needed for managing such a (spreaded) amount of 10x5 integral values is "10*sizeof(int*) + 10*5*sizeof(int)".
Concerning access:
Let's assume a variable of type int arr[][5], which is a 2D-array of integers, where the size of a column is 5 and the number of rows is not determined. Informally, an access like int x = arr[3][4] is translated into an access the (3*5 + 4)th element of the array, i.e. "row times rowsize plus column"; Note that - based on this formula - the compiler does not need to know how many rows the the array actually has. 
In contrast, let's assume a variable of type int **p. You can think of an access like x = p[3][4] as being equivalent to int *r = p[3]; int x = r[4]; Note that r is of type int *, i.e. it is a pointer, and r[4] then dereferences this pointer and returns an integral value.
This is rather informally described. 
Yet the main issue is that the memory layout of an arr[][5] contains consecutive integral values only, whereas int **arrr may be a seqence of pointers (or even just one such pointer), each of them probably pointing to a sequence of integral values (or just one integral value).