#include <cstdio>
// #define DEBUG 1

using namespace std;

typedef struct {
    int x, y, w;
} Povrsina;

int m[1007][1007];
Povrsina s[1000007];

int main() {
    // Input.
    int n, k;
    scanf("%d %d", &n, &k);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            scanf("%d", &m[i][j]);
        }
    }
    // Setup.
    for (int i = 0; i <= k; ++i) {
        s[i].x = -1;
        s[i].y = -1;
        s[i].w = -1;
    }
    // Iteration.
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            int p = m[i][j];
            #ifdef DEBUG
            printf("Inspecting (%d, %d) | %d | (%d, %d, %d)\n", j, i, p, s[p].x, s[p].y, s[p].w);
            #endif
            if (s[p].x == -2) {
                // Not qualified.
                #ifdef DEBUG
                printf("Not qualified.\n");
                #endif
                continue;
            } else if (s[p].x == -1) {
                // New type.
                s[p].y = i;
                s[p].x = j;
                s[p].w = 1;
                #ifdef DEBUG
                printf("New type.\n");
                #endif
            } else if (s[p].y == i) {
                // Same row, increase width.
                if (p == m[i][j - 1]) {
                    ++s[p].w;
                    #ifdef DEBUG
                    printf("Increased width.\n");
                    #endif
                } else {
                    s[p].x = -2;
                    #ifdef DEBUG
                    printf("Disqualified as same row.\n");
                    #endif
                }
            } else if (j >= s[p].x && j < s[p].x + s[p].w) {
                // Same column.
                if (p != m[i - 1][j]) {
                    s[p].x = -2;
                    #ifdef DEBUG
                    printf("Disqualified as same column.\n");
                    #endif
                }
            } else {
                s[p].x = -2;
                #ifdef DEBUG
                printf("Disqualified.\n");
                #endif
            }
            // If the next one is in the area and doesn't match the type, disqualify.
            if (
                // If the next one exists...
                s[p].y != i &&
                j != n - 1 &&
                // ...and is in the area...
                j + 1 >= s[p].x &&
                j + 1 < s[p].x + s[p].w &&
                // and isn't of the same type, disqualify.
                m[i][j + 1] != p
            ) {
                s[p].x = -2;
                #ifdef DEBUG
                printf("Disqualified as the next one is invalid.\n");
                #endif
            }
            if (
                // If the next one exists...
                s[p].y != i &&
                j != 0 &&
                // ...and is in the area...
                j - 1 >= s[p].x &&
                j - 1 < s[p].x + s[p].w &&
                // and isn't of the same type, disqualify.
                m[i][j - 1] != p
            ) {
                s[p].x = -2;
                #ifdef DEBUG
                printf("Disqualified as the previous one is invalid.\n");
                #endif
            }
        }
    }
    // Count non-disqualified types.
    int cnt = 0;
    for (int i = 0; i <= k; ++i) {
        if (s[i].x >= 0) {
            ++cnt;
        }
    }
    printf("%d", cnt);
    return 0;
}