#include <iostream>
#include <vector>
#include <algorithm>
#include <array>
#include <cmath>
#include <string>
#include <set>
#include <queue>
typedef long long ll;
using namespace std;

const int maxn = 1579;
int n, q;
vector<int> c(maxn * maxn), ans(maxn, 0);
vector<bool> seen(maxn* maxn, false);
vector<vector<int> > vr(maxn);
vector<vector<vector<int> > > vc(2, vector<vector<int>>(maxn)), vrc(2, vector<vector<int>>(maxn));
int d(int x, int y, int i)
{
	return max(i / n - x, i % n - y);
}
void mymerge(int x, int y, const vector<int>& a, const vector<int>& b, vector<int>& m)
{
	int ia = 0, ib = 0;
	while ((ia != a.size() || ib != b.size()) && m.size() < q + 1)
	{
		if (ia != a.size() && (ib == b.size() || d(x, y, a[ia]) < d(x, y, b[ib])))
		{
			if (!seen[c[a[ia]]]) m.push_back(a[ia]), seen[c[a[ia]]] = true;
			ia++;
		}
		else
		{
			if (!seen[c[b[ib]]]) m.push_back(b[ib]), seen[c[b[ib]]] = true;
			ib++;
		}
	}
	for (int i : m) seen[c[i]] = false;
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> n >> q;
	for (int i = 0; i < n * n; i++) cin >> c[i];
	for (int i = n - 1; i >= 0; i--)
	{
		int b = i & 1;
		for (int j = 0; j <= n; j++) vr[j].clear(), vrc[b][j].clear(), vc[b][j].clear();
		for (int j = n - 1; j >= 0; j--)
		{
			mymerge(i, j, vrc[!b][j + 1], { i * n + j }, vrc[b][j]);
			mymerge(i, j, vr[j + 1], vrc[b][j], vr[j]);
			mymerge(i, j, vc[!b][j], vrc[b][j], vc[b][j]);
			int len = min(n - i, n - j);
			vector<int> my;
			mymerge(i, j, vc[b][j], vr[j], my);
			if (my.size() == q + 1) len = min(len, d(i, j, my.back()));
			ans[len]++;
			/*cout << i << " " << j << ": " << len << " -> closest q + 1 colors are ";
			for (int k : my) cout << " " << c[k];
			cout << "\n";*/
		}
	}
	for (int i = n; i >= 1; i--) ans[i] += ans[i + 1];
	for (int i = 1; i <= n; i++) cout << ans[i] << "\n";
	return 0;
}