L'errore è che, alla fine del ciclo interno, se le righe/colonne sono uguali i/j non varrà m/n ma m+1/n+1!
Comunque ti consiglio di riorganizzarlo un po', ad esempio potresti scrivere la stessa cosa così e risulterebbe più breve e più facile da seguire e comprendere:
	codice:
	#include <stdio.h>
#include <stdbool.h>
#define MAX 50
int main(int argc, char **argv){
	int m, n, i, j;
	int a[MAX][MAX];
	bool colonne = false, righe = false;
	/* inizializzazione e riempimento vettore*/
	do {
		printf("m: ");
		scanf("%d", &m);
	} while((m > MAX) || (m < 0));
	
	do {
		printf("n: ");
		scanf("%d", &n);
	} while((n > MAX) || (n < 0));
	
	for(i = 0; i < m; i++){
		for(j = 0; j < n; j++){
			printf("Valore in (%d,%d): ", i, j);
			scanf("%d", &a[i][j]);
		}
	}
	for(i = 0; i < m; i++){
		for(j = 0; j < n; j++){
			printf(" %5d", a[i][j]);
		}
		printf("\n");
	}
	/* controllo righe */
	for(i = 0; i < m - 1; i++) {
		righe = true;
		for(j = 0; j < n; j++) {
			if(a[i][j] != a[i + 1][j]) {
				righe = false;
				break;
			}
		}
		if(righe) {
			break;
		}
	}
	/* controllo colonne */
	if(righe) {
		for(j = 0; j < n - 1; j++) {
			colonne = true;
			for(i = 0; i < m; i++) {
				if(a[i][j] != a[i][j + 1]) {
					colonne = false;
					break;
				}
			}
			if(colonne) {
				break;
			}
		}
	}
	printf("%s\n", (colonne && righe) ? "True" : "False");
	return 0;
}
 
Ci sono parentesi in eccesso messe solo per chiarezza ed ho aggiunto un controllo sulle dimensioni della matrice che tu non avevi considerato...
Un alternativa è allocarla dinamicamente, ciò toglie ogni vincolo sulle dimensioni:
	codice:
	#include <stdlib.h>
//...
int **a;
//...
a = (int **)malloc(sizeof(int *) * m);
for(i = 0; i < m; i++) {
  a[i] = (int *)malloc(sizeof(int) * n);
}
//...
for(i = 0; i < m; i++) {
  free(a[i]);
}
free(a);
//...
 
Infine non trascurare che l'esercizio chiedeva una funzione che restituisse true o false, mentre tu hai fatto un programma che stampa a video il risultato!