#include <bits/stdc++.h>
 
//#define int long long
 
#define pii pair<short, int>
 
#define x1 x1228
#define y1 y1228
 
#define left left228
#define right right228
 
#define data data228
 
#define pb push_back
#define eb emplace_back
 
#define mp make_pair                                                                
                                                                                                                                        
#define ff first                                                                  
#define ss second   
 
#define all(x) x.begin(), x.end()
#define debug(x) cout << #x << ": " << x << endl; 
#define TIME (ld)clock()/CLOCKS_PER_SEC
 
using namespace std;
/** Fast input-output */

template <class T = int> inline T readInt();
inline double readDouble();
inline int readUInt();
inline int readChar(); // first non-blank character
inline void readWord( char *s );
inline bool readLine( char *s ); // do not save '\n'
inline bool isEof();
inline int getChar();
inline int peekChar();
inline bool seekEof();
inline void skipBlanks();

template <class T> inline void writeInt( T x, char end = 0, int len = -1 );
inline void writeChar( int x );
inline void writeWord( const char *s );
inline void writeDouble( double x, int len = 0 );
inline void flush();

static struct buffer_flusher_t {
    ~buffer_flusher_t() {
        flush();
    }
} buffer_flusher;

/** Read */        

static const int buf_size = 4096;

static unsigned char buf[buf_size];
static int buf_len = 0, buf_pos = 0;

inline bool isEof() {
    if (buf_pos == buf_len) {
        buf_pos = 0, buf_len = fread(buf, 1, buf_size, stdin);
        if (buf_pos == buf_len)
            return 1;
    }
    return 0;
}


inline int getChar() {
    return isEof() ? -1 : buf[buf_pos++];
}

inline int peekChar() {
    return isEof() ? -1 : buf[buf_pos];
}

inline bool seekEof() {
    int c;
    while ((c = peekChar()) != -1 && c <= 32)
        buf_pos++;
    return c == -1;
}

inline void skipBlanks() {
    while (!isEof() && buf[buf_pos] <= 32U)
        buf_pos++;
}

inline int readChar() {
    int c = getChar();
    while (c != -1 && c <= 32)
        c = getChar();
    return c;
}

inline int readUInt() {
    int c = readChar(), x = 0;
    while ('0' <= c && c <= '9')
        x = x * 10 + c - '0', c = getChar();
    return x;
}

template <class T>
inline T readInt() {
    int s = 1, c = readChar();
    T x = 0;
    if (c == '-')
        s = -1, c = getChar();
    else if (c == '+')
        c = getChar();
    while ('0' <= c && c <= '9')
        x = x * 10 + c - '0', c = getChar();
    return s == 1 ? x : -x;
}

inline double readDouble() {
    int s = 1, c = readChar();
    double x = 0;
    if (c == '-')
        s = -1, c = getChar();
    while ('0' <= c && c <= '9')
        x = x * 10 + c - '0', c = getChar();
    if (c == '.') {
        c = getChar();
        double coef = 1;
        while ('0' <= c && c <= '9')
            x += (c - '0') * (coef *= 1e-1), c = getChar();
    }
    return s == 1 ? x : -x;
}

inline void readWord( char *s ) {
    int c = readChar();
    while (c > 32)
        *s++ = c, c = getChar();
    *s = 0;
}

inline bool readLine( char *s ) {
    int c = getChar();
    while (c != '\n' && c != -1)
        *s++ = c, c = getChar();
    *s = 0;
    return c != -1;
}

/** Write */

static int write_buf_pos = 0;
static char write_buf[buf_size];

inline void writeChar( int x ) {
    if (write_buf_pos == buf_size)
        fwrite(write_buf, 1, buf_size, stdout), write_buf_pos = 0;
    write_buf[write_buf_pos++] = x;
}

inline void flush() {
    if (write_buf_pos)
        fwrite(write_buf, 1, write_buf_pos, stdout), write_buf_pos = 0;
}

template <class T>
inline void writeInt( T x, char end, int output_len ) {
    if (x < 0)
        writeChar('-'), x = -x;

    char s[24];
    int n = 0;
    while (x || !n)
        s[n++] = '0' + x % 10, x /= 10;
    while (n < output_len)
        s[n++] = '0';
    while (n--)
        writeChar(s[n]);
    if (end)
        writeChar(end);
}

inline void writeWord( const char *s ) {
    while (*s)
        writeChar(*s++);
}

inline void writeDouble( double x, int output_len ) {
    if (x < 0)
        writeChar('-'), x = -x;
    int t = (int)x;
    writeInt(t), x -= t;
    writeChar('.');
    for (int i = output_len - 1; i > 0; i--) {
        x *= 10;
        t = std::min(9, (int)x);
        writeChar('0' + t), x -= t;
    }
    x *= 10;
    t = std::min(9, (int)(x + 0.5));
    writeChar('0' + t);
}
typedef long long ll; 
typedef long double ld; 
                                                                                                   
const int maxn = 1500 + 7, mod = 1e9 + 7, MAXN = 2e6 + 7;
const double eps = 1e-9;                                        
const ll INF = 1e18, inf = 1e15;
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());                       
int n, q; 
int cl[maxn][maxn]; 
vector<pii> ladder1[2][maxn], ladder2[2][maxn]; 
 
vector<pii> merge(vector<pii> p1, vector<pii> p2) {
    vector<pii> res;
    res.reserve((int)p1.size() + (int)p2.size()); 
    int pt1 = 0; 
    int pt2 = 0; 
    while (pt1 < (int)p1.size() && pt2 < (int)p2.size()) {
        if (p1[pt1].ff <= p2[pt2].ff) {
            res.pb(p1[pt1++]); 
        } else {
            res.pb(p2[pt2++]); 
        }
    }
    while (pt1 < (int)p1.size()) {
        res.pb(p1[pt1++]); 
    } 
    while (pt2 < (int)p2.size()) {
        res.pb(p2[pt2++]); 
    }
    return res; 
}
 
int used[maxn * maxn]; 
 
void compress(vector<pii> &res) {
    for (auto x : res) {
        used[x.ss] = 0; 
    }
    vector<pii> nw; 
    for (auto x : res) {
        if (!used[x.ss]) {
            nw.pb(x); 
            used[x.ss] = 1; 
        }
    }
    while ((int)nw.size() > q + 1) {
        nw.pop_back(); 
    }
    res = nw; 
}
 
void add(int i, int j, vector<pii> &cur, vector<int> &point) {
    short sz = min(i + 1, n - j); 
    if ((int)cur.size() <= q) {
        point[0]++; 
        point[sz]--; 
    } else {
        point[0]++; 
        point[min(sz, cur.back().ff)]--; 
    }
}
 
void solve() {
    n = readInt();
    q = readInt(); 
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            cl[i][j] = readInt(); 
        }
    }
    vector<int> point(n + 1); 
    int pt = 0; 
    for (int i = 0; i < n; ++i) {
        pt ^= 1; 
        for (int j = n - 1; j >= 0; --j) {                        
            vector<pii> res = ladder1[pt][j + 1]; 
            if (i) {
                res = merge(res, ladder1[pt ^ 1][j + 1]);                         
            }
            for (auto &x : res) {
                x.ff++;             
            }
            res = merge(res, {{0, cl[i][j]}}); 
            compress(res); 
            ladder1[pt][j] = res; 
 
 
            res.clear(); 
            if (i) {
                res = merge(ladder2[pt ^ 1][j], ladder2[pt ^ 1][j + 1]); 
                for (auto &x : res) {
                    x.ff++;             
                }
            }
            res = merge(res, {{0, cl[i][j]}}); 
            compress(res); 
            ladder2[pt][j] = res; 
 
            res = merge(res, ladder1[pt][j]); 
            compress(res);
            add(i, j, res, point);  
        }
        for (int j = 0; j < n; ++j) {
            ladder1[pt ^ 1][j].clear(); 
            ladder2[pt ^ 1][j].clear(); 
        }                 
    }
//    cout << TIME; 
//    return; 
    int res = 0;
    for (int i = 0; i < n; ++i) {
        res += point[i]; 
        cout << res << '\n'; 
    }     
}                                
                 
signed main() {          
#ifdef LOCAL
    freopen("TASK.in", "r", stdin);
    freopen("TASK.out", "w", stdout);
#endif // LOCAL                                                                             
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.precision(20); 
    cout << fixed; 
    int t = 1; 
    for (int i = 0; i < t; ++i) {              
        solve();
    }
    return 0;
}  
