#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int MN = 1505;

#define sz(a) (int)(a.size())
struct node {
	int k , c;
} ;

bool operator < (node a , node b) {
	return a.k < b.k;
}

int N , Q , A[MN][MN] , seen[MN * MN] , ans[MN];
vector < node > col[MN][MN];
vector < node > ret;

inline void merge(vector < node > &a , vector < node > &b) {
	for (auto o : b)
		a.emplace_back((node) {o.k + 1 , o.c});
}
inline void getcol(int x , int y) {
	ret.clear();
	ret.emplace_back((node) {1 , A[x][y]});
	if (x < N) merge(ret , col[x + 1][y]);
	if (y < N) merge(ret , col[x][y + 1]);
	if (x < N && y < N) merge(ret , col[x + 1][y + 1]);
	sort(ret.begin() , ret.end());
	for (auto o : ret) {
		if (seen[o.c]) continue;
		seen[o.c] = 1;  col[x][y].emplace_back(o);
		if (sz(col[x][y]) == Q + 1) 
			break;
	}
	for (auto o : ret) 
		seen[o.c] = 0;
	return;
}
int main() {
	
	scanf("%d%d" , &N , &Q);
	for (int i = 1; i <= N; ++i)
	for (int j = 1; j <= N; ++j)
		scanf("%d" , &A[i][j]);
	for (int i = N; i >= 1; --i) 
	for (int j = N; j >= 1; --j) 
		getcol(i , j);
	for (int i = 1; i <= N; ++i)
	for (int j = 1; j <= N; ++j) {
		int val = min(N - i + 1 , N - j + 1);
		if (col[i][j].size() == Q + 1) 
			val = min(val , col[i][j][Q].k - 1);
		++ans[1] , --ans[val + 1];	
	}
	for (int i = 1; i <= N; ++i) {
		ans[i] += ans[i - 1];
		printf("%d\n" , ans[i]);
	}
	return 0;
}