Kostya is extremely busy: he is renovating his house! He needs to hand wallpaper, assemble furniture throw away trash.

Kostya is buying tiles for bathroom today. He is standing in front of a large square stand with tiles in a shop. The stand is a square of n × n cells, each cell of which contains a small tile with color c_{i,\,j}. The shop sells tiles in packs: more specifically, you can only buy a subsquare of the initial square.

A subsquare is any square part of the stand, i. e. any set S(i_0, j_0, k) = \\{c_{i,\,j}\ |\ i_0 ≤ i < i_0 + k, j_0 ≤ j < j_0 + k\} with 1 ≤ i_0, j_0 ≤ n - k + 1.

Kostya still does not know how many tiles he needs, so he considers the subsquares of all possible sizes. He doesn't want his bathroom to be too colorful. Help Kostya to count for each k ≤ n the number of subsquares of size k × k that have at most q different colors of tiles. Two subsquares are considered different if their location on the stand is different.

Input

The first line contains two integers n and q (1 ≤ n ≤ 1500, 1 ≤ q ≤ 10) — the size of the stand and the limit on the number of distinct colors in a subsquare.

Each of the next n lines contains n integers c_{i,\,j} (1 ≤ c_{i,\,j} ≤ n^2): the j-th integer in the i-th line is the color of the tile in the cell (i,\,j).

Output

For each k from 1 to n print a single integer — the number of subsquares of size k × k with no more than q different colors.

Examples

Input


3 4
1 2 3
4 5 6
7 8 9


Output


9
4
0


Input


4 8
1 2 3 4
5 6 7 8
9 1 2 3
4 5 6 7


Output


16
9
4
0

Note

In the first example all colors are distinct. Kostya doesn't want the subsquare have more than 4 colors, so he can buy any subsquare of size 1 × 1 or 2 × 2, but he can't buy a subsquare of size 3 × 3.

In the second example there are colors that appear multiple times. Because q = 8, Kostya can buy any subsquare of size 1 × 1 and 2 × 2, and any subsquare 3 × 3, because of such subsquare has 7 different colors. He can't buy the whole stand 4 × 4, because there are 9 colors.
#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;
}  
