A general way of checking a property of all k×k squares in a two-dimensional array would be to store the property of all rectangles from the top-left corner to each cell, and then compare the properties of the cells at the four corners of the rectangle you want to check.
Consider this example array with values from 0 to 9:
1 8 5 6 8
7 2 5 4 6
3 0 2 5 8
9 5 1 4 6
An array of hashes that store the number of occurances of each 0-9 value in the rectangles from top-left to each cell would be:
0100000000 0100000010 0100010010 0100011010 0100011020
0100000100 0110000110 0110020110 0110121110 0110122120
0101000100 1111000110 1121020110 1121131110 1121132130
0101000101 1111010111 1221030111 1221241111 1221243131
If you build this from top-left to bottom-right, each hash is the sum of the hash above it and the hash to the left of it, minus the hash above-left of it, with the value of the cell added; e.g. the hash for cell (1,1) is based on the hash for cells (1,0), (0,1), (0,0) and its own value 2:
0100000010 + 0100000100 - 0100000000 + 0010000000 = 0110000110
Once you have the array of hashes, you can check any rectangle using the hashes at its corners, e.g. to check this rectangle:
. . . . .
. 2 5 4 .
. 0 2 5 .
. . . . .
you take the hashes at these positions:
A . . B .
. . . . .
C . . D .
. . . . .
and the hash for the rectangle is D - B - C + A:
1121131110 - 0100011010 - 0101000100 + 0100000000 = 1020120000
which indicates that the rectangle has one 0, two 2's, one 4 and two 5's, so there are two distinct elements: 0 and 4.
Building the array of hashes means calculating m×n hashes (where m×n is the size of the array) each based on three other hashes, and checking every k×k square means calculating (m-k)×(n-k) hashes, each based on four hashes. Whether that means the time complexity is really O(m×n) probably depends on the range of values and the corresponding size of the hashes.