// Mivik 2021.4.7
#include <cstdio>
#include <cstring>
#include <iostream>

#define d isdigit(c)
#define g c=t.get();
#define L return
#define K break
#define A(c,a,b)if(c)a else b;
#define I(c,a)if(c)a;
#define Y goto E
struct MI{private:char bb[1 << 14];FILE*f;char*bs,*be;char e;bool o,l;public:MI():f(stdin),bs(0),be(0){}
#ifdef __linux__
#endif
inline char get(){if(o){o=0;L e;}
#ifdef MIVIK
char c=fgetc(f);I(c==-1,l=1)L c;
#else
I(bs==be,be=(bs=bb)+fread(bb,1,sizeof(bb),f))I(bs==be,{l=1;L-1;})L*bs++;
#endif
}inline void unget(char c){o=1;e=c;}template<class T>inline MI&operator>(T&);};template<class T>struct Q{const static bool U=T(-1)>=T(0);inline void operator()(MI&t,T&r)const{r=0;char c;bool y=0;A(U,for(;;){g I(c==-1,Y)I(d,K)},for(;;){g I(c==-1,Y)A(c=='-',{g I(d,{y=1;K;})},I(d,K))})for(;;){I(c==-1,Y)A(d,r=r*10+(c^48);,K)g}t.unget(c);E:;I(y,r=-r)}};template<>struct Q<char>{};template<class T>inline MI&MI::operator>(T&t){Q<T>()(*this,t);L*this;}
#undef d
#undef g
#undef L
#undef K
#undef A
#undef I
#undef Y
template<class T>std::ostream& operator<(std::ostream&out,const T&t){return out<<t;}
#define endl ('\n')
#define P(x) cout<#x" = "<(x)<endl
#define R (cin.read<int>())

using std::cout;

#include <vector>
#include <climits>

MI cin;

typedef long long qe;

const int $n = 1505;

int n, q;
int v[$n][$n];
struct node {
	static node C;
	int x, y;
	inline int col() const { return v[x][y]; }
	inline int dist(const node &t) const { return std::max(x - t.x + 1, y - t.y + 1); }
	inline bool operator==(const node &t) const { return x == t.x && y == t.y; }
	inline bool operator<(const node &t) const { return C.dist(*this) < C.dist(t); }
};
node node::C;
const node E = { -1, -1 };
typedef std::vector<node> arr;
int cur;
arr vt[$n];
struct {
	bool vis[$n * $n];
	std::vector<int> all;
	inline bool insert(int i) {
		if (vis[i]) return 0;
		vis[i] = 1;
		all.push_back(i);
		return 1;
	}
	inline void reset() {
		for (int v : all) vis[v] = 0;
		all.clear();
	}
} H;
inline arr merge(const arr &A, const arr &B) {
	node a, b, w;
	int at = 0, bt = 0;
	arr T;
	T.push_back(node::C);
	H.reset();
	H.insert(node::C.col());
	for (int i = 0;; ++i) {
		a = b = E;
		if (at != A.size()) a = A[at];
		if (bt != B.size()) b = B[bt];
		if (a < b) {
			w = a;
			++at;
		} else {
			w = b;
			++bt;
		}
		if (w == E) break;
		if (!H.insert(w.col())) continue;
		T.push_back(w);
		if (T.size() == q + 1) {
			cur = node::C.dist(w) - 1;
			return T;
		}
	}
	cur = INT_MAX;
	return T;
}
qe ans[$n];
int main() {
	cin > n > q;
	for (int i = 1; i <= n; ++i) {
		arr ho;
		for (int j = 1; j <= n; ++j) {
			cin > v[i][j];
			node::C = { i, j };
			vt[j] = merge(vt[j - 1], vt[j]);
			cur = std::min(cur, std::min(i, j));
			++ans[cur];
		}
	}
	for (int i = n - 1; i; --i) ans[i] += ans[i + 1];
	for (int i = 1; i <= n; ++i) cout < ans[i] < endl;
}