#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef double db;

namespace {
    template <typename T> inline void read(T &x) {
        x = 0; T f = 1; char c = getchar();
        for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
        for(; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
        x = x * f;
    }
}

const int N = 2E3 + 50;

# define P pair<int, int>

int n, k, mlen, up, f[N][N], id[N][N], mx[4 * N], c[N][N];
char s[N][N];
std::vector<P> g;
string ans;

bool cmp(P a, P b) {
    int i1 = a.first, j1 = up - i1, i2 = b.first, j2 = up - i2;
    if(s[i1][j1] != s[i2][j2]) return s[i1][j1] < s[i2][j2];
    return a.second < b.second;
}
inline P calc(P now) {
    return P(now.first, up - now.first);
}
void solve(int x = 1, int y = 1) {
    bool flag = false;
    for(int i = 1; i <= n; i++) c[0][i] = 1e9, c[i][0] = 1e9;
    c[0][1] = 0;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++) {
            c[i][j] = min(c[i - 1][j], c[i][j - 1]) + (s[i][j] != 'a');
            if(c[i][j] == k) mlen = max(mlen, i + j);
        }
    // cout << c[7][8] << ' ' << c[6][9] << '\n';
    // cout << mlen << '\n';
    // (1 : i + 1, j) (-1 : i, j + 1)
    id[n][n] = 1;
    for(int t = n * 2 - 1; t > 1; --t) {
        g.clear(); up = t;
        for(int i = 1, j, p; i <= n; i++) {
            j = t - i;
            if(j < 1 || j > n) continue;
            if(j == n) f[i][j] = 1, p = id[i + 1][j];
            else if(i == n) f[i][j] = -1, p = id[i][j + 1];
            else if(s[i + 1][j] < s[i][j + 1]) f[i][j] = 1, p = id[i + 1][j];
            else if(s[i + 1][j] > s[i][j + 1]) f[i][j] = -1, p = id[i][j + 1];
            else {
                if(id[i + 1][j] < id[i][j + 1])
                    f[i][j] = 1, p = id[i + 1][j];
                else f[i][j] = -1, p = id[i][j + 1];
            }
            g.push_back(P(i, p));
        }
        sort(g.begin(), g.end(), cmp);
        int sz = g.size(); P getn;
        for(int i = 0; i < sz; i++) {
            getn = calc(g[i]);
            // if(t == mlen + 1)
            //     cout << s[getn.first][getn.second] << ' ' << c[getn.first][getn.second] << '\n';
            if(t == mlen + 1 && c[getn.first][getn.second] == k + 1 && !flag)
                x = getn.first, y = getn.second, flag = 1;
            id[getn.first][getn.second] = i + 1;
        }
    }
    // cout << x << ' ' << y << ' ' << c[x][y] << '\n';
    for(int i = 1; x != n || y != n; i++) {
        ans += s[x][y];
        if(f[x][y] == 1) x ++;
        else y++;
    }
    ans += s[n][n];
    for(int i = 1; i <= 2 * n - 1 - ans.length(); ++i)
        putchar('a');
    cout << ans << '\n';
}
int main() {
    read(n), read(k);
    for(int i = 1; i <= n; i++)
        scanf("%s", s[i] + 1);
    if(k >= 2 * n - 1) {
        for(int i = 1; i <= 2 * n - 1; ++i) printf("a");
        printf("\n");
        return 0;
    }
    solve();
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef double db;

namespace {
    template <typename T> inline void read(T &x) {
        x = 0; T f = 1; char c = getchar();
        for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
        for(; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
        x = x * f;
    }
}

const int N = 2E3 + 50;

# define P pair<int, int>

int n, k, mlen, up, f[N][N], id[N][N], mx[4 * N], c[N][N];
char s[N][N];
std::vector<P> g;
string ans;

bool cmp(P a, P b) {
    int i1 = a.first, j1 = up - i1, i2 = b.first, j2 = up - i2;
    if(s[i1][j1] != s[i2][j2]) return s[i1][j1] < s[i2][j2];
    return a.second < b.second;
}
inline P calc(P now) {
    return P(now.first, up - now.first);
}
void solve(int x = 0, int y = 0) {
    bool flag = false;
    c[1][1] = s[1][1] != 'a';
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++) {
            if(i > 1) c[i][j] = c[i - 1][j] + (s[i][j] != 'a');
            if(j > 1) c[i][j] = min(c[i][j] ? c[i][j] : 1000000, c[i][j - 1] + (s[i][j] != 'a'));
            if(c[i][j] == k) mlen = max(mlen, i + j);
        }
    // cout << mlen << '\n';
    // (1 : i + 1, j) (-1 : i, j + 1)
    id[n][n] = 1;
    for(int t = n * 2 - 1; t > 1; --t) {
        g.clear(); up = t;
        for(int i = 1, j, p; i <= n; i++) {
            j = t - i;
            if(j < 1 || j > n) continue;
            if(j == n) f[i][j] = 1, p = id[i + 1][j];
            else if(i == n) f[i][j] = -1, p = id[i][j + 1];
            else if(s[i + 1][j] < s[i][j + 1]) f[i][j] = 1, p = id[i + 1][j];
            else if(s[i + 1][j] > s[i][j + 1]) f[i][j] = -1, p = id[i][j + 1];
            else {
                if(id[i + 1][j] < id[i][j + 1])
                    f[i][j] = 1, p = id[i + 1][j];
                else f[i][j] = -1, p = id[i][j + 1];
            }
            g.push_back(P(i, p));
        }
        sort(g.begin(), g.end(), cmp);
        int sz = g.size(); P getn;
        for(int i = 0; i < sz; i++) {
            getn = calc(g[i]);
            // if(t == mlen + 1)
            //     cout << s[getn.first][getn.second] << ' ' << c[getn.first][getn.second] << '\n';
            if(t == mlen + 1 && c[getn.first][getn.second] == k + 1 && !flag)
                x = getn.first, y = getn.second, flag = 1;
            id[getn.first][getn.second] = i + 1;
        }
    }
    // cout << x << ' ' << y << ' ' << c[x][y] << '\n';
    for(int i = 1; x != n || y != n; i++) {
        ans += s[x][y];
        if(f[x][y] == 1) x ++;
        else y++;
    }
    ans += s[n][n];
    for(int i = 1; i <= 2 * n - 1 - ans.length(); ++i)
        putchar('a');
    cout << ans << '\n';
}
int main() {
    read(n), read(k);
    for(int i = 1; i <= n; i++)
        scanf("%s", s[i] + 1);
    if(k >= 2 * n - 1) {
        for(int i = 1; i <= 2 * n - 1; ++i) printf("a");
        printf("\n");
        return 0;
    }
    solve();
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef double db;

namespace {
    template <typename T> inline void read(T &x) {
        x = 0; T f = 1; char c = getchar();
        for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
        for(; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
        x = x * f;
    }
}

const int N = 2E3 + 50;

# define P pair<int, int>

int n, k, mlen, up, f[N][N], id[N][N], mx[4 * N], c[N][N];
char s[N][N];
std::vector<P> g;
string ans;

bool cmp(P a, P b) {
    int i1 = a.first, j1 = up - i1, i2 = b.first, j2 = up - i2;
    if(s[i1][j1] != s[i2][j2]) return s[i1][j1] < s[i2][j2];
    return a.second < b.second;
}
inline P calc(P now) {
    return P(now.first, up - now.first);
}
void solve(int x = 1, int y = 1) {
    bool flag = false;
    for(int i = 1; i <= n; i++) c[0][i] = 1e9, c[i][0] = 1e9;
    c[0][1] = 0;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++) {
            c[i][j] = min(c[i - 1][j], c[i][j - 1]) + (s[i][j] != 'a');
            if(c[i][j] == k) mlen = max(mlen, i + j);
        }
    // cout << 2 * n - 1 - c[n][n] << '\n';
    if(c[n][n] <= k) {
        for(int i = 1; i <= 2 * n - 1; ++i) printf("a");
        printf("\n");
        exit(0);
    }
    // (1 : i + 1, j) (-1 : i, j + 1)
    id[n][n] = 1;
    for(int t = n * 2 - 1; t > 1; --t) {
        g.clear(); up = t;
        for(int i = 1, j, p; i <= n; i++) {
            j = t - i;
            if(j < 1 || j > n) continue;
            if(j == n) f[i][j] = 1, p = id[i + 1][j];
            else if(i == n) f[i][j] = -1, p = id[i][j + 1];
            else if(s[i + 1][j] < s[i][j + 1]) f[i][j] = 1, p = id[i + 1][j];
            else if(s[i + 1][j] > s[i][j + 1]) f[i][j] = -1, p = id[i][j + 1];
            else {
                if(id[i + 1][j] < id[i][j + 1])
                    f[i][j] = 1, p = id[i + 1][j];
                else f[i][j] = -1, p = id[i][j + 1];
            }
            g.push_back(P(i, p));
        }
        sort(g.begin(), g.end(), cmp);
        int sz = g.size(); P getn;
        for(int i = 0; i < sz; i++) {
            getn = calc(g[i]);
            if(t == mlen + 1 && c[getn.first][getn.second] == k + 1 && !flag && s[getn.first][getn.second] != 'a')
                x = getn.first, y = getn.second, flag = 1;
            id[getn.first][getn.second] = i + 1;
        }
    }
    // cout << x << ' ' << y << ' ' << c[x][y] << '\n';
    for(int i = 1; x != n || y != n; i++) {
        ans += s[x][y];
        if(f[x][y] == 1) x ++;
        else y++;
    }
    ans += s[n][n];
    for(int i = 1; i <= 2 * n - 1 - ans.length(); ++i)
        putchar('a');
    cout << ans << '\n';
}
int main() {
    read(n), read(k);
    for(int i = 1; i <= n; i++)
        scanf("%s", s[i] + 1);
    solve();
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef double db;

namespace {
    template <typename T> inline void read(T &x) {
        x = 0; T f = 1; char c = getchar();
        for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
        for(; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
        x = x * f;
    }
}

const int N = 2E3 + 50;

# define P pair<int, int>

int n, k, mlen, up, f[N][N], id[N][N], mx[4 * N], c[N][N];
char s[N][N];
std::vector<P> g;
string ans;

bool cmp(P a, P b) {
    int i1 = a.first, j1 = up - i1, i2 = b.first, j2 = up - i2;
    if(s[i1][j1] != s[i2][j2]) return s[i1][j1] < s[i2][j2];
    return a.second < b.second;
}
inline P calc(P now) {
    return P(now.first, up - now.first);
}
void solve(int x = 0, int y = 0) {
    bool flag = false;
    c[1][1] = s[1][1] != 'a';
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++) {
            if(i > 1) c[i][j] = c[i - 1][j] + (s[i][j] != 'a');
            if(j > 1) c[i][j] = min(c[i][j] ? c[i][j] : 1000000, c[i][j - 1] + (s[i][j] != 'a'));
            if(c[i][j] == k) mlen = max(mlen, i + j);
        }
    // cout << mlen << '\n';
    // (1 : i + 1, j) (-1 : i, j + 1)
    id[n][n] = 1;
    for(int t = n * 2 - 1; t > 1; --t) {
        g.clear(); up = t;
        for(int i = 1, j, p; i <= n; i++) {
            j = t - i;
            if(j < 1 || j > n) continue;
            if(j == n) f[i][j] = 1, p = id[i + 1][j];
            else if(i == n) f[i][j] = -1, p = id[i][j + 1];
            else if(s[i + 1][j] < s[i][j + 1]) f[i][j] = 1, p = id[i + 1][j];
            else if(s[i + 1][j] > s[i][j + 1]) f[i][j] = -1, p = id[i][j + 1];
            else {
                if(id[i + 1][j] < id[i][j + 1])
                    f[i][j] = 1, p = id[i + 1][j];
                else f[i][j] = -1, p = id[i][j + 1];
            }
            g.push_back(P(i, p));
        }
        sort(g.begin(), g.end(), cmp);
        int sz = g.size(); P getn;
        for(int i = 0; i < sz; i++) {
            getn = calc(g[i]);
            if(t == mlen + 1)
                cout << s[getn.first][getn.second] << ' ' << c[getn.first][getn.second] << '\n';
            if(t == mlen + 1 && c[getn.first][getn.second] == k + 1 && !flag)
                x = getn.first, y = getn.second, flag = 1;
            id[getn.first][getn.second] = i + 1;
        }
    }
    // cout << x << ' ' << y << ' ' << c[x][y] << '\n';
    for(int i = 1; x != n || y != n; i++) {
        ans += s[x][y];
        if(f[x][y] == 1) x ++;
        else y++;
    }
    ans += s[n][n];
    for(int i = 1; i <= 2 * n - 1 - ans.length(); ++i)
        putchar('a');
    cout << ans << '\n';
}
int main() {
    read(n), read(k);
    for(int i = 1; i <= n; i++)
        scanf("%s", s[i] + 1);
    if(k >= 2 * n - 1) {
        for(int i = 1; i <= 2 * n - 1; ++i) printf("a");
        printf("\n");
        return 0;
    }
    solve();
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef double db;

namespace {
	template <typename T> inline void read(T &x) {
	 	x = 0; T f = 1; char c = getchar();
	 	for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
	 	for(; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
	 	x = x * f;
	}
}

const int N = 2E3 + 50;

# define P pair<int, int>

int n, k, up, f[N][N], id[N][N];
char s[N][N];
std::vector<P> g;
string ans;

bool cmp(P a, P b) {
	int i1 = a.first, j1 = up - i1, i2 = b.first, j2 = up - i2;
	if(f[i1][j1] == 1) i1++; else j1++;
	if(f[i2][j2] == 1) i2++; else j2++;
	if(s[i1][j1] != s[i2][j2]) return s[i1][j1] < s[i2][j2];
	return a.second < b.second;
}
inline P calc(P now) {
	return P(now.first, up - now.first);
}
void solve() {
	// (1 : i + 1, j) (-1 : i, j + 1)
	id[n][n] = 1;
	for(int t = n * 2 - 1; t > 1; --t) {
		g.clear(); up = t;
		for(int i = 1, j, p; i <= n; i++) {
			j = t - i;
			if(j < 1 || j > n) continue;
			if(j == n) f[i][j] = 1, p = id[i + 1][j];
			else if(i == n) f[i][j] = -1, p = id[i][j + 1];
			else if(s[i + 1][j] < s[i][j + 1])
				f[i][j] = 1, p = id[i + 1][j];
			else if(s[i + 1][j] > s[i][j + 1])
				f[i][j] = -1, p = id[i][j + 1];
			else {
				if(id[i + 1][j] < id[i][j + 1])
					f[i][j] = 1, p = id[i + 1][j];
				else f[i][j] = -1, p = id[i][j + 1];
			}
			g.push_back(P(i, p));
		}
		sort(g.begin(), g.end(), cmp);
		int sz = g.size(); P getn;
		for(int i = 0; i < sz; i++) {
			getn = calc(g[i]);
			id[getn.first][getn.second] = i + 1;
		}
	}
	for(int i = 1, x = 1, y = 1; i <= 2 * n - 1; i++) {
		ans += s[x][y];
		if(f[x][y] == 1) x ++;
		else y++;
	}
	for(int i = 0; i < 2 * n - 1; i++)
		if(ans[i] != 'a' && k) ans[i] = 'a', k--;
	cout << ans << '\n';
}
int main() {
	read(n), read(k);
	for(int i = 1; i <= n; i++)
		scanf("%s", s[i] + 1);
	if(k >= 2 * n - 1) {
		for(int i = 1; i <= 2 * n - 1; ++i) printf("a");
		return 0;
	}
	solve();
	return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef double db;

namespace {
	template <typename T> inline void read(T &x) {
	 	x = 0; T f = 1; char c = getchar();
	 	for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
	 	for(; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
	 	x = x * f;
	}
}

const int N = 2E3 + 50;

# define P pair<int, int>

int n, k, up, f[N][N], id[N][N];
char s[N][N];
std::vector<P> g;
string ans;

bool cmp(P a, P b) {
	int i1 = a.first, j1 = up - i1, i2 = b.first, j2 = up - i2;
	if(f[i1][j1] == 1) i1++; else j1++;
	if(f[i2][j2] == 1) i2++; else j2++;
	if(s[i1][j1] != s[i2][j2]) return s[i1][j1] < s[i2][j2];
	return a.second < b.second;
}
inline P calc(P now) {
	return P(now.first, up - now.first);
}
void solve() {
	// (1 : i + 1, j) (-1 : i, j + 1)
	id[n][n] = 1;
	for(int t = n * 2 - 1; t > 1; --t) {
		g.clear(); up = t;
		for(int i = 1, j, p; i <= n; i++) {
			j = t - i;
			if(j < 1 || j > n) continue;
			if(j == n) f[i][j] = 1, p = id[i + 1][j];
			else if(i == n) f[i][j] = -1, p = id[i][j + 1];
			else if(s[i + 1][j] < s[i][j + 1])
				f[i][j] = 1, p = id[i + 1][j];
			else if(s[i + 1][j] > s[i][j + 1])
				f[i][j] = -1, p = id[i][j + 1];
			else {
				if(id[i + 1][j] < id[i][j + 1])
					f[i][j] = 1, p = id[i + 1][j];
				else f[i][j] = -1, p = id[i][j + 1];
			}
			g.push_back(P(i, p));
		}
		sort(g.begin(), g.end(), cmp);
		int sz = g.size(), cnt = 1;
		P getn = calc(g[0]);
		id[getn.first][getn.second] = 1;
		for(int i = 1; i < sz; i++) {
			if(cmp(g[i - 1], g[i])) cnt ++;
			getn = calc(g[i]);
			id[getn.first][getn.second] = cnt;
		}
	}
	for(int i = 1, x = 1, y = 1; i <= 2 * n - 1; i++) {
		ans += s[x][y];
		if(f[x][y] == 1) x ++;
		else y++;
	}
	for(int i = 0; i < 2 * n - 1; i++)
		if(ans[i] != 'a' && k) ans[i] = 'a', k--;
	cout << ans << '\n';
}
int main() {
	read(n), read(k);
	for(int i = 1; i <= n; i++)
		scanf("%s", s[i] + 1);
	if(k >= 2 * n - 1) {
		for(int i = 1; i <= 2 * n - 1; ++i) printf("a");
		return 0;
	}
	solve();
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<(b);++i)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
#define pb push_back
#define mp make_pair
#define de(x) cout<<#x<<" = "<<x<<endl
#define dd(x) cout<<#x<<" = "<<x<<"  , "
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long ll;
typedef unsigned long long  ull;
typedef pair<int,int> pii;
const int N=2e3+7,maxn=1e5+7;
const ll mod=998244353;
char ap[N][N];
struct qwe{
    int x,y,sy;
    qwe(){}
    qwe(int x,int y,int sy):x(x),y(y),sy(sy){}
};
struct cmp{
    bool operator () (qwe a,qwe b){
        return a.sy<b.sy;
    }
};
bool in[N][N];
priority_queue<qwe,vector<qwe>,cmp >q;
vector<qwe>p1,p2;
int pre[N][N];
int main(){
    int n,m;
    cin>>n>>m;
    rep(i,0,n)scanf("%s",ap[i]);
    if(ap[0][0]=='a'){
        q.push( qwe(0,0,m) );
    }else if(m>=1) q.push( qwe(0,0,m-1) );
    qwe u;
    int mx=-1;
    while(!q.empty()){
        u=q.top();q.pop();
        int x=u.x,y=u.y;
        if(in[x][y])continue;
        in[x][y]=1;
        mx=max(mx,x+y);
        if(x+1<n&& ap[x+1][y]=='a'  ){
            q.push( qwe(x+1,y,u.sy) );
        }
        if(y+1<n&& ap[x][y+1]=='a'){
            q.push( qwe(x,y+1,u.sy) );
        }
        if(u.sy==0)continue;
        if(x+1<n&& ap[x+1][y]!='a') q.push(qwe(x+1,y,u.sy-1) );
        if(y+1<n&&ap[x][y+1]!='a' ) q.push(qwe(x,y+1,u.sy-1) );
    }
    rep(i,0,n){
        rep(j,0,n){
            if(in[i][j]==1&& (i+j)==mx ){
                p2.pb(qwe(i,j,0) );
            }
        }
    }
    memset(pre,-1,sizeof(pre));
    int x,y;
    if(mx==-1)p2.pb( qwe(0,0,0) );
    while(1){
        bool f=0;
        char mi='z';
        swap(p1,p2);
        rep(i,0,p1.size()){
            x=p1[i].x,y=p1[i].y;
            if(x+1<n) mi=min(mi, ap[x+1][y]);
            if(y+1<n) mi=min(mi,ap[x][y+1]);
        }
        rep(i,0,p1.size()){
            x=p1[i].x,y=p1[i].y;
            if( x+1<n &&ap[x+1][y]==mi&&in[x+1][y]==0 ){
                p2.pb( qwe(x+1,y,0) );
                pre[x+1][y]=x*1e5+y;
                in[x+1][y]=1;
                f=1;
            }
            if( y+1<n&& ap[x][y+1]==mi&&in[x][y+1]==0 ){
                p2.pb( qwe(x,y+1,0) );
                pre[x][y+1]=x*1e5+y;
                f=1;
                in[x][y+1]=1;
            }
        }
        p1.clear();
        if(f==0)break;
    }
    rep(i,0,mx+1){
        printf("a");
    }
    int sy=2*n-2-mx;
    if(mx==-1)sy=2*n-1;
    int nx=n-1,ny=n-1,t1,t2;
    vector<char>ans;
    while(sy--){
        ans.pb(ap[nx][ny]);
        t1=pre[nx][ny]/ (int) (1e5);
        t2=pre[nx][ny]%(int)(1e5);
        nx=t1,ny=t2;
    }
    per(i,0,ans.size())printf("%c",ans[i]);
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<(b);++i)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
#define pb push_back
#define mp make_pair
#define de(x) cout<<#x<<" = "<<x<<endl
#define dd(x) cout<<#x<<" = "<<x<<"  , "
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long ll;
typedef unsigned long long  ull;
typedef pair<int,int> pii;
const int N=2e3+7,maxn=1e5+7;
const ll mod=998244353;
char ap[N][N];
struct qwe{
    int x,y,sy;
    qwe(){}
    qwe(int x,int y,int sy):x(x),y(y),sy(sy){}
};
bool in[N][N];
queue<qwe>q;
vector<qwe>p1,p2;
int pre[N][N];
int main(){
    int n,m;
    cin>>n>>m;
    rep(i,0,n)scanf("%s",ap[i]);
    if(ap[0][0]=='a'){
        q.push( qwe(0,0,m) );
    }else if(m>=1) q.push( qwe(0,0,m-1) );
    qwe u;
    int mx=-1;
    while(!q.empty()){
        u=q.front();q.pop();
        int x=u.x,y=u.y;
        in[x][y]=1;
        mx=max(mx,x+y);
        if(x+1<n&& ap[x+1][y]=='a' &&in[x+1][y]==0 ){
            in[x+1][y]=1;
            q.push( qwe(x+1,y,u.sy) );
        }
        if(y+1<n&& ap[x][y+1]=='a'&&in[x][y+1]==0){
            in[x][y+1]=1;
            q.push( qwe(x,y+1,u.sy) );
        }
        if(u.sy==0)continue;
        if(x+1<n&& ap[x+1][y]!='a'&&in[x+1][y]==0)in[x+1][y]=1, q.push(qwe(x+1,y,u.sy-1) );
        if(y+1<n&&ap[x][y+1]!='a' &&in[x][y+1]==0 )in[x][y+1]=1, q.push(qwe(x,y+1,u.sy-1) );
    }
    rep(i,0,n){
        rep(j,0,n){
            if(in[i][j]==1&& (i+j)==mx ){
                p2.pb(qwe(i,j,0) );
            }
        }
    }
    memset(pre,-1,sizeof(pre));
    int x,y;
    if(mx==-1)p2.pb( qwe(0,0,0) );
    while(1){
        bool f=0;
        char mi='z';
        swap(p1,p2);
        rep(i,0,p1.size()){
            x=p1[i].x,y=p1[i].y;
            if(x+1<n) mi=min(mi, ap[x+1][y]);
            if(y+1<n) mi=min(mi,ap[x][y+1]);
        }
        rep(i,0,p1.size()){
            x=p1[i].x,y=p1[i].y;
            if( x+1<n &&ap[x+1][y]==mi&&in[x+1][y]==0 ){
                p2.pb( qwe(x+1,y,0) );
                pre[x+1][y]=x*1e5+y;
                f=1;
            }
            if( y+1<n&& ap[x][y+1]==mi&&in[x][y+1]==0 ){
                p2.pb( qwe(x,y+1,0) );
                pre[x][y+1]=x*1e5+y;
                f=1;
            }
        }
        p1.clear();
        if(f==0)break;
    }
    rep(i,0,mx+1){
        printf("a");
    }
    int sy=2*n-2-mx;
    if(mx==-1)sy=2*n-1;
    int nx=n-1,ny=n-1,t1,t2;
    vector<char>ans;
    while(sy){
        sy--;
        ans.pb(ap[nx][ny]);
        t1=pre[nx][ny]/ (int) (1e5);
        t2=pre[nx][ny]%(int)(1e5);
        nx=t1,ny=t2;
    }
    per(i,0,ans.size())printf("%c",ans[i]);
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<(b);++i)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
#define pb push_back
#define mp make_pair
#define de(x) cout<<#x<<" = "<<x<<endl
#define dd(x) cout<<#x<<" = "<<x<<"  , "
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long ll;
typedef unsigned long long  ull;
typedef pair<int,int> pii;
const int N=2e3+7,maxn=1e5+7;
const ll mod=998244353;
char ap[N][N];
struct qwe{
    int x,y,sy;
    qwe(){}
    qwe(int x,int y,int sy):x(x),y(y),sy(sy){}
};
bool in[N][N];
queue<qwe>q;
vector<qwe>p1,p2;
int pre[N][N];
int main(){
    int n,m;
    cin>>n>>m;
    rep(i,0,n)scanf("%s",ap[i]);
    if(ap[0][0]=='a'){
        q.push( qwe(0,0,m) );
    }else if(m>=1) q.push( qwe(0,0,m-1) );
    qwe u;
    int mx=-1;
    while(!q.empty()){
        u=q.front();q.pop();
        int x=u.x,y=u.y;
        in[x][y]=1;
        mx=max(mx,x+y);
        if(x+1<n&& ap[x+1][y]=='a' &&in[x+1][y]==0 ){
            in[x+1][y]=1;
            q.push( qwe(x+1,y,u.sy) );
        }
        if(y+1<n&& ap[x][y+1]=='a'&&in[x][y+1]==0){
            in[x][y+1]=1;
            q.push( qwe(x,y+1,u.sy) );
        }
        if(u.sy==0)continue;
        if(x+1<n&& ap[x+1][y]!='a'&&in[x+1][y]==0)in[x+1][y]=1, q.push(qwe(x+1,y,u.sy-1) );
        if(y+1<n&&ap[x][y+1]!='a' &&in[x][y+1]==0 )in[x][y+1]=1, q.push(qwe(x,y+1,u.sy-1) );
    }
    rep(i,0,n){
        rep(j,0,n){
            if(in[i][j]==1&& (i+j)==mx ){
                p2.pb(qwe(i,j,0) );
            }
        }
    }
    memset(pre,-1,sizeof(pre));
    int x,y;
    if(mx==-1)p2.pb( qwe(0,0,0) );
    while(1){
        bool f=0;
        char mi='z';
        swap(p1,p2);
        rep(i,0,p1.size()){
            x=p1[i].x,y=p1[i].y;
            if(x+1<n) mi=min(mi, ap[x+1][y]);
            if(y+1<n) mi=min(mi,ap[x][y+1]);
        }
        rep(i,0,p1.size()){
            x=p1[i].x,y=p1[i].y;
            if( x+1<n &&ap[x+1][y]==mi&&in[x+1][y]==0 ){
                p2.pb( qwe(x+1,y,0) );
                pre[x+1][y]=x*1e5+y;
                in[x+1][y]=1;
                f=1;
            }
            if( y+1<n&& ap[x][y+1]==mi&&in[x][y+1]==0 ){
                p2.pb( qwe(x,y+1,0) );
                pre[x][y+1]=x*1e5+y;
                f=1;
                in[x][y+1]=0;
            }
        }
        p1.clear();
        if(f==0)break;
    }
    rep(i,0,mx+1){
        printf("a");
    }
    int sy=2*n-2-mx;
    if(mx==-1)sy=2*n-1;
    int nx=n-1,ny=n-1,t1,t2;
    vector<char>ans;
    while(sy){
        sy--;
        ans.pb(ap[nx][ny]);
        t1=pre[nx][ny]/ (int) (1e5);
        t2=pre[nx][ny]%(int)(1e5);
        nx=t1,ny=t2;
    }
    per(i,0,ans.size())printf("%c",ans[i]);
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<(b);++i)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
#define pb push_back
#define mp make_pair
#define de(x) cout<<#x<<" = "<<x<<endl
#define dd(x) cout<<#x<<" = "<<x<<"  , "
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long ll;
typedef unsigned long long  ull;
typedef pair<int,int> pii;
const int N=2e3+7,maxn=1e5+7;
const ll mod=998244353;
char ap[N][N];
struct qwe{
    int x,y,sy;
    qwe(){}
    qwe(int x,int y,int sy):x(x),y(y),sy(sy){}
};
bool in[N][N];
queue<qwe>q;
vector<qwe>p1,p2;
int prex[N][N],prey[N][N];
int main(){
    int n,m;
    cin>>n>>m;
    rep(i,0,n)scanf("%s",ap[i]);
    if(ap[0][0]=='a'){
        q.push( qwe(0,0,m) );
    }else if(m>=1) q.push( qwe(0,0,m-1) );
    qwe u;
    int mx=-1;
    while(!q.empty()){
        u=q.front();q.pop();
        int x=u.x,y=u.y;
        in[x][y]=1;
        mx=max(mx,x+y);
        if(x+1<n&& ap[x+1][y]=='a'){
            q.push( qwe(x+1,y,u.sy) );
        }
        if(y+1<n&& ap[x][y+1]=='a'){
            q.push( qwe(x,y+1,u.sy) );
        }
        if(u.sy==0)continue;
        if(x+1<n&& ap[x+1][y]!='a')q.push(qwe(x+1,y,u.sy-1) );
        if(y+1<n&&ap[x][y+1]!='a')q.push(qwe(x,y+1,u.sy-1) );
    }
    rep(i,0,n){
        rep(j,0,n){
            if(in[i][j]==1&& (i+j)==mx ){
                p2.pb(qwe(i,j,0) );
            }
        }
    }
    memset(prex,-1,sizeof(prex));memset(prey,-1,sizeof(prey));
    int x,y;
    if(mx==-1)p2.pb( qwe(0,0,0) );
    while(1){
        bool f=0;
        char mi='z';
        swap(p1,p2);
        rep(i,0,p1.size()){
            x=p1[i].x,y=p1[i].y;
            if(x+1<n) mi=min(mi, ap[x+1][y]);
            if(y+1<n) mi=min(mi,ap[x][y+1]);
        }
        rep(i,0,p1.size()){
            x=p1[i].x,y=p1[i].y;
            if( x+1<n &&ap[x+1][y]==mi&&in[x+1][y]==0 ){
                p2.pb( qwe(x+1,y,0) );
                prex[x+1][y]=x;
                prey[x+1][y]=y;
                f=1;
            }
            if( y+1<n&& ap[x][y+1]==mi&&in[x][y+1]==0 ){
                p2.pb( qwe(x,y+1,0) );
                prex[x][y+1]=x;
                prey[x][y+1]=y;
                f=1;
            }
        }
        p1.clear();
        if(f==0)break;
    }
    rep(i,0,mx+1){
        printf("a");
    }
    int sy=2*n-2-mx;
    if(mx==-1)sy=2*n-1;
    int nx=n-1,ny=n-1,t1,t2;
    vector<char>ans;
    while(sy){
        sy--;
        ans.pb(ap[nx][ny]);
        t1=prex[nx][ny];
        t2=prey[nx][ny];
        nx=t1,ny=t2;
    }
    per(i,0,ans.size())printf("%c",ans[i]);
}
/*
4 0
bbcd
bcde
bcad
bcde
*/


#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<(b);++i)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
#define pb push_back
#define mp make_pair
#define de(x) cout<<#x<<" = "<<x<<endl
#define dd(x) cout<<#x<<" = "<<x<<"  , "
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long ll;
typedef unsigned long long  ull;
typedef pair<int,int> pii;
const int N=2e3+7,maxn=1e5+7;
const ll mod=998244353;
char ap[N][N];
struct qwe{
    int x,y,sy;
    qwe(){}
    qwe(int x,int y,int sy):x(x),y(y),sy(sy){}
};
bool in[N][N];
queue<qwe>q;
vector<qwe>p1,p2;
int pre[N][N];
int main(){
    int n,m;
    cin>>n>>m;
    rep(i,0,n)scanf("%s",ap[i]);
    if(ap[0][0]=='a'){
        q.push( qwe(0,0,m) );
    }else if(m>=1) q.push( qwe(0,0,m-1) );
    qwe u;
    int mx=-1;
    while(!q.empty()){
        u=q.front();q.pop();
        int x=u.x,y=u.y;
        in[x][y]=1;
        mx=max(mx,x+y);
        if(x+1<n&& ap[x+1][y]=='a'){
            q.push( qwe(x+1,y,u.sy) );
        }
        if(y+1<n&& ap[x][y+1]=='a'){
            q.push( qwe(x,y+1,u.sy) );
        }
        if(u.sy==0)continue;
        if(x+1<n&& ap[x+1][y]!='a')q.push(qwe(x+1,y,u.sy-1) );
        if(y+1<n&&ap[x][y+1]!='a')q.push(qwe(x,y+1,u.sy-1) );
    }
    rep(i,0,n){
        rep(j,0,n){
            if(in[i][j]==1&& (i+j)==mx ){
                p2.pb(qwe(i,j,0) );
            }
        }
    }
    memset(pre,-1,sizeof(pre));
    int x,y;
    if(mx==-1)p2.pb( qwe(0,0,0) );
    while(1){
        bool f=0;
        char mi='z';
        swap(p1,p2);
        rep(i,0,p1.size()){
            x=p1[i].x,y=p1[i].y;
            if(x+1<n) mi=min(mi, ap[x+1][y]);
            if(y+1<n) mi=min(mi,ap[x][y+1]);
        }
        rep(i,0,p1.size()){
            x=p1[i].x,y=p1[i].y;
            if( x+1<n &&ap[x+1][y]==mi&&in[x+1][y]==0 ){
                p2.pb( qwe(x+1,y,0) );
                pre[x+1][y]=x*1e5+y;
                f=1;
            }
            if( y+1<n&& ap[x][y+1]==mi&&in[x][y+1]==0 ){
                p2.pb( qwe(x,y+1,0) );
                pre[x][y+1]=x*1e5+y;
                f=1;
            }
        }
        p1.clear();
        if(f==0)break;
    }
    rep(i,0,mx+1){
        printf("a");
    }
    int sy=2*n-2-mx;
    if(mx==-1)sy=2*n-1;
    int nx=n-1,ny=n-1,t1,t2;
    vector<char>ans;
    while(sy){
        sy--;
        ans.pb(ap[nx][ny]);
        t1=pre[nx][ny]/ (int) (1e5);
        t2=pre[nx][ny]%(int)(1e5);
        nx=t1,ny=t2;
    }
    per(i,0,ans.size())printf("%c",ans[i]);
}
/*
4 0
bbcd
bcde
bcad
bcde
*/


#include <bits/stdc++.h>
#define fore(x,a,b) for(int x=a, qwerty=b; x<qwerty; x++)
#define ALL(a) (a).begin(),(a).end()
#define SZ(a) ((int)(a).size())
#define pb push_back
#define FIN ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define fst first
#define snd second
#define mset(a,v) memset((a),(v),sizeof(a))
using namespace std;
typedef long long ll;
typedef pair<int,int> ii;
int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
int lcm(int a, int b) { return a* (b / gcd(a,b)); }

int n,k;
const int N=2048;
string s[N];
int dist[N][N];
bool vis[N][N];
int main(){FIN;
	cin>>n>>k;
	fore(i,0,n)cin>>s[i];
	if(k&&s[0][0]!='a'){
		s[0][0]='a';
		k--;
	}
	string ans="";
	queue<pair<ii,int> > q,t;
	q.push({ii(0,0),k});
	ans+=s[0][0];
	while(!q.empty()){
		ii x=q.front().fst;
		int k=q.front().snd;
		if(x.fst==n-1&&x.snd==n-1){
			break;
		}
		char c='z';
		t=q;
		while(!t.empty()){
			ii p=t.front().fst;
			k=t.front().snd;t.pop();
			if(k>0)c='a';
			if(p.fst<n-1){
				int e=0;
				c=min(c,s[p.fst+1][p.snd]);
				if(s[p.fst+1][p.snd]!='a')e=1;
				dist[p.fst+1][p.snd]=max(dist[p.fst+1][p.snd],k-e);
			}
			if(p.snd<n-1){
				int e=0;
				c=min(c,s[p.fst][p.snd+1]);
				if(s[p.fst][p.snd+1]!='a')e=1;
				dist[p.fst][p.snd+1]=max(dist[p.fst][p.snd+1],k-e);
			}
		}
		while(!q.empty()){
			ii p=q.front().fst;
			int k=q.front().snd;
			q.pop();
			if(p.fst<n-1&&(s[p.fst+1][p.snd]==c||k)){
				if(!vis[p.fst+1][p.snd]){
					t.push({ii(p.fst+1,p.snd),dist[p.fst][p.snd+1]});
					vis[p.fst+1][p.snd]=1;
				}
			}
			if(p.snd<n-1&&(s[p.fst][p.snd+1]==c||k)){
				if(!vis[p.fst][p.snd+1]){
					t.push({ii(p.fst,p.snd+1),dist[p.fst][p.snd+1]});
					vis[p.fst][p.snd+1]=1;
				}
			}
		}
		q=t;
		ans+=c;
	}
	cout<<ans<<"\n";
}


#include <bits/stdc++.h>
#define fore(x,a,b) for(int x=a, qwerty=b; x<qwerty; x++)
#define ALL(a) (a).begin(),(a).end()
#define SZ(a) ((int)(a).size())
#define pb push_back
#define FIN ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define fst first
#define snd second
#define mset(a,v) memset((a),(v),sizeof(a))
using namespace std;
typedef long long ll;
typedef pair<int,int> ii;
int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
int lcm(int a, int b) { return a* (b / gcd(a,b)); }

int n,k;
const int N=2048;
string s[N];
int dist[N][N];
bool vis[N][N];
int main(){FIN;
	cin>>n>>k;
	fore(i,0,n)cin>>s[i];
	if(k&&s[0][0]!='a'){
		s[0][0]='a';
		k--;
	}
	string ans="";
	queue<pair<ii,int> > q,t;
	q.push({ii(0,0),k});
	ans+=s[0][0];
	while(!q.empty()){
		ii x=q.front().fst;
		int k=q.front().snd;
		if(x.fst==n-1&&x.snd==n-1){
			break;
		}
		char c='z';
		t=q;
		while(!t.empty()){
			ii p=t.front().fst;
			k=t.front().snd;t.pop();
			if(k>0)c='a';
			if(p.fst<n-1){
				int e=0;
				c=min(c,s[p.fst+1][p.snd]);
				if(s[p.fst+1][p.snd]!='a')e=1;
				if(k)dist[p.fst+1][p.snd]=max(dist[p.fst+1][p.snd],k-e);
			}
			if(p.snd<n-1){
				int e=0;
				c=min(c,s[p.fst][p.snd+1]);
				if(s[p.fst][p.snd+1]!='a')e=1;
				if(k)dist[p.fst][p.snd+1]=max(dist[p.fst][p.snd+1],k-e);
			}
		}
		while(!q.empty()){
			ii p=q.front().fst;
			int k=q.front().snd;
			q.pop();
			if(p.fst<n-1&&(s[p.fst+1][p.snd]==c||k-1==dist[p.fst][p.snd+1])){
				if(!vis[p.fst+1][p.snd]){
					t.push({ii(p.fst+1,p.snd),dist[p.fst][p.snd+1]});
					vis[p.fst+1][p.snd]=1;
				}
			}
			if(p.snd<n-1&&(s[p.fst][p.snd+1]==c||k-1==dist[p.fst][p.snd+1])){
				if(!vis[p.fst][p.snd+1]){
					t.push({ii(p.fst,p.snd+1),dist[p.fst][p.snd+1]});
					vis[p.fst][p.snd+1]=1;
				}
			}
		}
		q=t;
		ans+=c;
	}
	cout<<ans<<"\n";
}


#include <bits/stdc++.h>
#define fore(x,a,b) for(int x=a, qwerty=b; x<qwerty; x++)
#define ALL(a) (a).begin(),(a).end()
#define SZ(a) ((int)(a).size())
#define pb push_back
#define FIN ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define fst first
#define snd second
#define mset(a,v) memset((a),(v),sizeof(a))
using namespace std;
typedef long long ll;
typedef pair<int,int> ii;
int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
int lcm(int a, int b) { return a* (b / gcd(a,b)); }

int n,k;
const int N=2048;
string s[N];
int dist[N][N];
bool vis[N][N];
int main(){FIN;
	cin>>n>>k;
	fore(i,0,n)cin>>s[i];
	if(k&&s[0][0]!='a'){
		s[0][0]='a';
		k--;
	}
	string ans="";
	queue<pair<ii,int> > q,t;
	q.push({ii(0,0),k});
	ans+=s[0][0];
	while(!q.empty()){
		ii x=q.front().fst;
		int k=q.front().snd;
		if(x.fst==n-1&&x.snd==n-1){
			break;
		}
		char c='z';
		t=q;
		while(!t.empty()){
			ii p=t.front().fst;
			k=t.front().snd;t.pop();
			if(k>0)c='a';
			if(p.fst<n-1){
				int e=0;
				c=min(c,s[p.fst+1][p.snd]);
				if(s[p.fst+1][p.snd]!='a')e=1;
				if(k)dist[p.fst+1][p.snd]=max(dist[p.fst+1][p.snd],k-e);
			}
			if(p.snd<n-1){
				int e=0;
				c=min(c,s[p.fst][p.snd+1]);
				if(s[p.fst][p.snd+1]!='a')e=1;
				if(k)dist[p.fst][p.snd+1]=max(dist[p.fst][p.snd+1],k-e);
			}
		}
		while(!q.empty()){
			ii p=q.front().fst;
			int k=q.front().snd;
			q.pop();
			if(p.fst<n-1&&(s[p.fst+1][p.snd]==c||k)){
				if(!vis[p.fst+1][p.snd]){
					t.push({ii(p.fst+1,p.snd),dist[p.fst+1][p.snd]});
					vis[p.fst+1][p.snd]=1;
				}
			}
			if(p.snd<n-1&&(s[p.fst][p.snd+1]==c||k)){
				if(!vis[p.fst][p.snd+1]){
					t.push({ii(p.fst,p.snd+1),dist[p.fst][p.snd+1]});
					vis[p.fst][p.snd+1]=1;
				}
			}
		}
		q=t;
		ans+=c;
	}
	cout<<ans<<"\n";
}


#include <bits/stdc++.h>
#define fore(x,a,b) for(int x=a, qwerty=b; x<qwerty; x++)
#define ALL(a) (a).begin(),(a).end()
#define SZ(a) ((int)(a).size())
#define pb push_back
#define FIN ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define fst first
#define snd second
#define mset(a,v) memset((a),(v),sizeof(a))
using namespace std;
typedef long long ll;
typedef pair<int,int> ii;
int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
int lcm(int a, int b) { return a* (b / gcd(a,b)); }

int n,k;
const int N=2048;
string s[N];
int dist[N][N];
bool vis[N][N];
int main(){FIN;
	cin>>n>>k;
	fore(i,0,n)cin>>s[i];
	if(k&&s[0][0]!='a'){
		s[0][0]='a';
		k--;
	}
	string ans="";
	queue<pair<ii,int> > q,t;
	q.push({ii(0,0),k});
	ans+=s[0][0];
	while(!q.empty()){
		ii x=q.front().fst;
		int k=q.front().snd;
		if(x.fst==n-1&&x.snd==n-1){
			break;
		}
		char c='z';
		t=q;
		while(!t.empty()){
			ii p=t.front().fst;
			k=t.front().snd;t.pop();
			if(k>0)c='a';
			if(p.fst<n-1){
				int e=0;
				c=min(c,s[p.fst+1][p.snd]);
				if(s[p.fst+1][p.snd]!='a')e=1;
				dist[p.fst+1][p.snd]=max(dist[p.fst+1][p.snd],k-e);
			}
			if(p.snd<n-1){
				int e=0;
				c=min(c,s[p.fst][p.snd+1]);
				if(s[p.fst][p.snd+1]!='a')e=1;
				dist[p.fst][p.snd+1]=max(dist[p.fst][p.snd+1],k-e);
			}
		}
		while(!q.empty()){
			ii p=q.front().fst;
			int k=q.front().snd;
			q.pop();
			if(p.fst<n-1&&(s[p.fst+1][p.snd]==c||k)){
				if(!vis[p.fst+1][p.snd]){
					t.push({ii(p.fst+1,p.snd),dist[p.fst+1][p.snd]});
					vis[p.fst+1][p.snd]=1;
				}
			}
			if(p.snd<n-1&&(s[p.fst][p.snd+1]==c||k)){
				if(!vis[p.fst][p.snd+1]){
					t.push({ii(p.fst,p.snd+1),dist[p.fst][p.snd+1]});
					vis[p.fst][p.snd+1]=1;
				}
			}
		}
		q=t;
		ans+=c;
	}
	cout<<ans<<"\n";
}


#include <bits/stdc++.h>
#define fore(x,a,b) for(int x=a, qwerty=b; x<qwerty; x++)
#define ALL(a) (a).begin(),(a).end()
#define SZ(a) ((int)(a).size())
#define pb push_back
#define FIN ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define fst first
#define snd second
#define mset(a,v) memset((a),(v),sizeof(a))
using namespace std;
typedef long long ll;
typedef pair<int,int> ii;
int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
int lcm(int a, int b) { return a* (b / gcd(a,b)); }

int n,k;
const int N=2048;
string s[N];
bool vis[N][N];
int main(){FIN;
	cin>>n>>k;
	fore(i,0,n)cin>>s[i];
	if(k&&s[0][0]!='a'){
		s[0][0]='a';
		k--;
	}
	string ans="";
	queue<ii> q,t;
	q.push({0,0});
	ans+=s[0][0];
	while(!q.empty()){
		ii x=q.front();
		if(x.fst==n-1&&x.snd==n-1){
			break;
		}
		char c='z';
		t=q;
		while(!t.empty()){
			ii p=t.front();t.pop();
			if(p.fst<n-1)c=min(c,s[p.fst+1][p.snd]);
			if(p.snd<n-1)c=min(c,s[p.fst][p.snd+1]);
		}
		bool flag=0;
		if(c!='a'&&k){
			c='a';
			k--;
			flag=1;
		}
		while(!q.empty()){
			ii p=q.front();q.pop();
			if((p.fst<n-1&&s[p.fst+1][p.snd]==c)||flag){
				if(!vis[p.fst+1][p.snd]){
					t.push({p.fst+1,p.snd});
					vis[p.fst+1][p.snd]=1;
				}
			}
			if((p.snd<n-1&&s[p.fst][p.snd+1]==c)||flag){
				if(!vis[p.fst][p.snd+1]){
					t.push({p.fst,p.snd+1});
					vis[p.fst][p.snd+1]=1;
				}
			}
		}
		q=t;
		ans+=c;
	}
	cout<<ans<<"\n";
}


#include <bits/stdc++.h>
#define fore(x,a,b) for(int x=a, qwerty=b; x<qwerty; x++)
#define ALL(a) (a).begin(),(a).end()
#define SZ(a) ((int)(a).size())
#define pb push_back
#define FIN ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define fst first
#define snd second
#define mset(a,v) memset((a),(v),sizeof(a))
using namespace std;
typedef long long ll;
typedef pair<int,int> ii;
int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
int lcm(int a, int b) { return a* (b / gcd(a,b)); }

int n,k;
const int N=2048;
string s[N];
int dist[N][N];
bool vis[N][N];
int main(){FIN;
	cin>>n>>k;
	fore(i,0,n)cin>>s[i];
	if(k&&s[0][0]!='a'){
		s[0][0]='a';
		k--;
	}
	string ans="";
	queue<pair<ii,int> > q,t;
	q.push({ii(0,0),k});
	ans+=s[0][0];
	while(!q.empty()){
		ii x=q.front().fst;
		int k=q.front().snd;
		if(x.fst==n-1&&x.snd==n-1){
			break;
		}
		char c='z';
		t=q;
		while(!t.empty()){
			ii p=t.front().fst;
			k=t.front().snd;t.pop();
			if(k>0)c='a';
			if(p.fst<n-1){
				int e=0;
				c=min(c,s[p.fst+1][p.snd]);
				if(s[p.fst+1][p.snd]!='a')e=1;
				dist[p.fst+1][p.snd]=max(dist[p.fst+1][p.snd],k-e);
			}
			if(p.snd<n-1){
				int e=0;
				c=min(c,s[p.fst][p.snd+1]);
				if(s[p.fst][p.snd+1]!='a')e=1;
				dist[p.fst][p.snd+1]=max(dist[p.fst][p.snd+1],k-e);
			}
		}
		while(!q.empty()){
			ii p=q.front().fst;
			int k=q.front().snd;
			q.pop();
			if((p.fst<n-1&&s[p.fst+1][p.snd]==c)||k){
				if(!vis[p.fst+1][p.snd]){
					t.push({ii(p.fst+1,p.snd),dist[p.fst][p.snd+1]});
					vis[p.fst+1][p.snd]=1;
				}
			}
			if((p.snd<n-1&&s[p.fst][p.snd+1]==c)||k){
				if(!vis[p.fst][p.snd+1]){
					t.push({ii(p.fst,p.snd+1),dist[p.fst][p.snd+1]});
					vis[p.fst][p.snd+1]=1;
				}
			}
		}
		q=t;
		ans+=c;
	}
	cout<<ans<<"\n";
}


#include <bits/stdc++.h>
#define fore(x,a,b) for(int x=a, qwerty=b; x<qwerty; x++)
#define ALL(a) (a).begin(),(a).end()
#define SZ(a) ((int)(a).size())
#define pb push_back
#define FIN ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define fst first
#define snd second
#define mset(a,v) memset((a),(v),sizeof(a))
using namespace std;
typedef long long ll;
typedef pair<int,int> ii;
int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
int lcm(int a, int b) { return a* (b / gcd(a,b)); }

int n,k;
const int N=2048;
string s[N];
bool vis[N][N];
int main(){FIN;
	cin>>n>>k;
	fore(i,0,n)cin>>s[i];
	if(k&&s[0][0]!='a'){
		s[0][0]='a';
		k--;
	}
	string ans="";
	queue<ii> q,t;
	q.push({0,0});
	ans+=s[0][0];
	while(!q.empty()){
		ii x=q.front();
		if(x.fst==n-1&&x.snd==n-1){
			break;
		}
		char c='z';
		t=q;
		while(!t.empty()){
			ii p=t.front();t.pop();
			if(p.fst<n-1)c=min(c,s[p.fst+1][p.snd]);
			if(p.snd<n-1)c=min(c,s[p.fst][p.snd+1]);
		}
		bool flag=0;
		if(c!='a'&&k){
			c='a';
			k--;
			flag=1;
		}
		while(!q.empty()){
			ii p=q.front();q.pop();
			if(p.fst<n-1&&(s[p.fst+1][p.snd]==c||flag)){
				if(!vis[p.fst+1][p.snd]){
					t.push({p.fst+1,p.snd});
					vis[p.fst+1][p.snd]=1;
				}
			}
			if(p.snd<n-1&&(s[p.fst][p.snd+1]==c||flag)){
				if(!vis[p.fst][p.snd+1]){
					t.push({p.fst,p.snd+1});
					vis[p.fst][p.snd+1]=1;
				}
			}
		}
		q=t;
		ans+=c;
	}
	cout<<ans<<"\n";
}


#include <bits/stdc++.h>
#define fore(x,a,b) for(int x=a, qwerty=b; x<qwerty; x++)
#define ALL(a) (a).begin(),(a).end()
#define SZ(a) ((int)(a).size())
#define pb push_back
#define FIN ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define fst first
#define snd second
#define mset(a,v) memset((a),(v),sizeof(a))
using namespace std;
typedef long long ll;
typedef pair<int,int> ii;
int n,k;
const int N=2048;
string s[N];
int dist[N][N];
bool vis[N][N];
int dx[2]={0,1};
int dy[2]={1,0};
bool can(int x, int y){return x<n&&y<n;}
int main(){FIN;
	cin>>n>>k;
	fore(i,0,n)cin>>s[i];
	if(k&&s[0][0]!='a'){
		s[0][0]='a';
		k--;
	}
	string ans="";
	queue<pair<ii,int> > q,t;
	q.push({ii(0,0),k});
	ans+=s[0][0];
	while(!q.empty()){
		ii x=q.front().fst;
		int k=q.front().snd;
		if(x.fst==n-1&&x.snd==n-1){
			break;
		}
		char c='z';
		t=q;
		while(!t.empty()){
			ii p=t.front().fst;
			k=t.front().snd;t.pop();
			if(k>0)c='a';
			fore(h,0,2){
					int x=p.fst+dx[h],y=p.snd+dy[h];
					if(!can(x,y))continue;
					int e=0;
					c=min(c,s[x][y]);
					if(s[x][y]!='a')e=1;
					dist[x][y]=max(dist[x][y],k-e);
			}
		}
		while(!q.empty()){
			ii p=q.front().fst;
			int k=q.front().snd;
			q.pop();
			fore(h,0,2){
					int x=p.fst+dx[h],y=p.snd+dy[h];
					if(!can(x,y))continue;
					if(s[x][y]==c||k){
						if(!vis[x][y]){
							t.push({ii(x,y),dist[x][y]});
							vis[x][y]=1;
						}
					}
			}
		}
		q=t;
		ans+=c;
	}
	cout<<ans<<"\n";
}


#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define pb push_back
#define x first
#define y second
#define fastread ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define PI (atan(1)*4)
#define mp make_pair
using namespace std;
const int maxn = 2003, inf = 1e7;

#define pt pair< pair<int,int>, pair<int,int> >

int id[maxn][maxn], n, k, cost[maxn][maxn];
char arr[maxn][maxn];
vector< pt > v;

bool comp(pair<int, int> a, pair<int, int> b) {
    if (cost[a.x][a.y] != cost[b.x][b.y])
        return cost[a.x][a.y] < cost[b.x][b.y];
    else
        return id[a.x][a.y] < id[b.x][b.y];
}

int main()
{
    fastread;
    cin >> n >> k;
    for (int i = 0; i < maxn; i++) {
        for (int j = 0; j < maxn; j++) {
            id[i][j] = inf;
            cost[i][j] = inf;
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            cin >> arr[i][j];
            id[i][j] = arr[i][j] - 'a';
        }
    }
    if (n == 1) {
        if (k == 0)
            cout << arr[1][1];
        else
            cout << 'a';
        return 0;
    }
    for (int i = 1; i < (2 * n - 1); i++) {
        v.clear();
        int x, y;
        if (i < n) {
            x = n;
            y = n - i;
        }
        else {
            y = 1;
            x = n - (i - (n - 1));
        }
        while (y <= n && x >= 1) {
            v.pb({{id[x][y], min(id[x + 1][y], id[x][y + 1])}, {x, y}});
            x--;
            y++;
        }
        sort(v.begin(), v.end());
        id[v.front().y.x][v.front().y.y] = 1;
        int ptr = 1;
        for (int i = 1; i < v.size(); i++) {
            if (v[i].x != v[i - 1].x)
                ptr++;
            id[v[i].y.x][v[i].y.y] = ptr;
        }
    }
    int stx = 1, sty = 1;
    if (k != 0) {
        if (arr[1][1] != 'a')
            cost[1][1] = 1;
        else
            cost[1][1] = 0;
        vector< pair<int, int> > v;
        v.pb({1, 1});
        int posx = v[0].x, posy = v[0].y;
        for (int i = 1; i < (2 * n - 1); i++) {
            v.clear();
            int x, y;
            if (i < n) {
                x = i + 1;
                y = 1;
            }
            else {
                x = n;
                y = i - (n - 1) + 1;
            }
            while (y <= n && x >= 1) {
                cost[x][y] = min(cost[x - 1][y], cost[x][y - 1]);
                if (arr[x][y] != 'a')
                    cost[x][y]++;
                if (cost[x][y] <= k) {
                    v.pb({x, y});
                }
                // cout << " " << x << " " << y << " " << cost[x][y] << endl;
                x--;
                y++;
            }
            sort(v.begin(), v.end(), comp);
            if (!v.empty()) {
                posx = v[0].x;
                posy = v[0].y;
            }
        }
        // cout << posx << " " << posy << endl;
        for (int i = 1; i < (posx + posy); i++)
            cout << 'a';
        stx = posx;
        sty = posy;
        if (id[posx + 1][posy] <= id[posx][posy + 1]) {
            stx++;
        } else {
            sty++;
        }
    }
    // cout<<endl;
    while (stx <= n && sty <= n) {
        // cout<<stx<<" "<<sty<<endl;
        cout << arr[stx][sty];
        if (id[stx + 1][sty] <= id[stx][sty + 1])
            stx++;
        else
            sty++;
    }
    return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define pb push_back
#define x first
#define y second
#define fastread ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define PI (atan(1)*4)
#define mp make_pair
using namespace std;
const int maxn = 2002, inf = 1e7;

#define pt pair< pair<int,int>, pair<int,int> >

int id[maxn][maxn], n, k, cost[maxn][maxn];
char arr[maxn][maxn];
vector< pt > v;

bool comp(pair<int, int> a, pair<int, int> b) {
    if (cost[a.x][a.y] != cost[b.x][b.y])
        return cost[a.x][a.y] < cost[b.x][b.y];
    else
        return id[a.x][a.y] < id[b.x][b.y];
}

int main()
{
    fastread;
    cin >> n >> k;
    for (int i = 0; i < maxn; i++) {
        for (int j = 0; j < maxn; j++) {
            id[i][j] = inf;
            cost[i][j] = inf;
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            cin >> arr[i][j];
            id[i][j] = arr[i][j] - 'a';
        }
    }
    if (n == 1) {
        if (k == 0)
            cout << arr[1][1];
        else
            cout << 'a';
        return 0;
    }
    for (int i = 1; i < (2 * n - 1); i++) {
        v.clear();
        int x, y;
        if (i < n) {
            x = n;
            y = n - i;
        }
        else {
            y = 1;
            x = n - (i - (n - 1));
        }
        while (y <= n && x >= 1) {
            v.pb({{id[x][y], min(id[x + 1][y], id[x][y + 1])}, {x, y}});
            x--;
            y++;
        }
        sort(v.begin(), v.end());
        id[v.front().y.x][v.front().y.y] = 1;
        int ptr = 1;
        for (int i = 1; i < v.size(); i++) {
            if (v[i].x != v[i - 1].x)
                ptr++;
            id[v[i].y.x][v[i].y.y] = ptr;
        }
    }
    int stx = 1, sty = 1;
    if (k != 0) {
        if (arr[1][1] != 'a')
            cost[1][1] = 1;
        else
            cost[1][1] = 0;
        vector< pair<int, int> > v;
        v.pb({1, 1});
        int posx = v[0].x, posy = v[0].y;
        for (int i = 1; i < (2 * n - 1); i++) {
            v.clear();
            int x, y;
            if (i < n) {
                x = i + 1;
                y = 1;
            }
            else {
                x = n;
                y = i - (n - 1);
            }
            while (y <= n && x >= 1) {
                cost[x][y] = min(cost[x - 1][y], cost[x][y - 1]);
                if (arr[x][y] != 'a')
                    cost[x][y]++;
                if (cost[x][y] <= k) {
                    v.pb({x, y});
                }
                // cout << " " << x << " " << y << " " << cost[x][y] << endl;
                x--;
                y++;
            }
            sort(v.begin(), v.end(), comp);
            if (!v.empty()) {
                posx = v[0].x;
                posy = v[0].y;
            }
        }
        // cout << posx << " " << posy << endl;
        for (int i = 1; i < (posx + posy); i++)
            cout << 'a';
        stx = posx;
        sty = posy;
        if (id[posx + 1][posy] <= id[posx][posy + 1]) {
            stx++;
        } else {
            sty++;
        }
    }
    // cout<<endl;
    while (stx <= n && sty <= n) {
        // cout<<stx<<" "<<sty<<endl;
        cout << arr[stx][sty];
        if (id[stx + 1][sty] <= id[stx][sty + 1])
            stx++;
        else
            sty++;
    }
    return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define pb push_back
#define x first
#define y second
#define fastread ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define PI (atan(1)*4)
#define mp make_pair
using namespace std;
const int maxn = 2003, inf = 1e7;

#define pt pair< pair<int,int>, pair<int,int> >

int id[maxn][maxn], n, k, cost[maxn][maxn];
char arr[maxn][maxn];
vector< pt > v;

bool comp(pair<int, int> a, pair<int, int> b) {
    if (cost[a.x][a.y] != cost[b.x][b.y])
        return cost[a.x][a.y] < cost[b.x][b.y];
    else
        return min(id[a.x + 1][a.y], id[a.x][a.y + 1]) < min(id[b.x + 1][b.y], id[b.x][b.y + 1]);
}

int main()
{
    fastread;
    cin >> n >> k;
    for (int i = 0; i < maxn; i++) {
        for (int j = 0; j < maxn; j++) {
            id[i][j] = inf;
            cost[i][j] = inf;
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            cin >> arr[i][j];
            id[i][j] = arr[i][j] - 'a';
        }
    }
    if (n == 1) {
        if (k == 0)
            cout << arr[1][1];
        else
            cout << 'a';
        return 0;
    }
    for (int i = 1; i < (2 * n - 1); i++) {
        v.clear();
        int x, y;
        if (i < n) {
            x = n;
            y = n - i;
        }
        else {
            y = 1;
            x = n - (i - (n - 1));
        }
        while (y <= n && x >= 1) {
            v.pb({{id[x][y], min(id[x + 1][y], id[x][y + 1])}, {x, y}});
            x--;
            y++;
        }
        sort(v.begin(), v.end());
        id[v.front().y.x][v.front().y.y] = 1;
        int ptr = 1;
        for (int i = 1; i < v.size(); i++) {
            if (v[i].x != v[i - 1].x)
                ptr++;
            id[v[i].y.x][v[i].y.y] = ptr;
        }
    }
    int stx = 1, sty = 1;
    if (k != 0) {
        if (arr[1][1] != 'a')
            cost[1][1] = 1;
        else
            cost[1][1] = 0;
        vector< pair<int, int> > v;
        v.pb({1, 1});
        int posx = v[0].x, posy = v[0].y;
        for (int i = 1; i < (2 * n - 1); i++) {
            v.clear();
            int x, y;
            if (i < n) {
                x = i + 1;
                y = 1;
            }
            else {
                x = n;
                y = i - (n - 1) + 1;
            }
            while (y <= n && x >= 1) {
                cost[x][y] = min(cost[x - 1][y], cost[x][y - 1]);
                if (arr[x][y] != 'a')
                    cost[x][y]++;
                if (cost[x][y] <= k) {
                    v.pb({x, y});
                }
                // cout << " " << x << " " << y << " " << cost[x][y] << endl;
                x--;
                y++;
            }
            sort(v.begin(), v.end(), comp);
            if (!v.empty()) {
                posx = v[0].x;
                posy = v[0].y;
            }
        }
        // cout << posx << " " << posy << endl;
        for (int i = 1; i < (posx + posy); i++)
            cout << 'a';
        stx = posx;
        sty = posy;
        if (id[posx + 1][posy] <= id[posx][posy + 1]) {
            stx++;
        } else {
            sty++;
        }
    }
    // cout<<endl;
    while (stx <= n && sty <= n) {
        // cout<<stx<<" "<<sty<<endl;
        cout << arr[stx][sty];
        if (id[stx + 1][sty] <= id[stx][sty + 1])
            stx++;
        else
            sty++;
    }
    return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define pb push_back
#define x first
#define y second
#define fastread ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define PI (atan(1)*4)
#define mp make_pair
using namespace std;
const int maxn = 2002, inf = 1e7;

#define pt pair< pair<int,int>, pair<int,int> >

int id[maxn][maxn], nid[maxn][maxn], n, k, cost[maxn][maxn];
char arr[maxn][maxn];
vector< pt > v;

bool comp(pair<int, int> a, pair<int, int> b) {
    if (cost[a.x][a.y] != cost[b.x][b.y])
        return cost[a.x][a.y] < cost[b.x][b.y];
    else
        return id[a.x][a.y] < id[b.x][b.y];
}

int main()
{
    fastread;
    cin >> n >> k;
    for (int i = 0; i < maxn; i++) {
        for (int j = 0; j < maxn; j++) {
            id[i][j] = inf;
            cost[i][j] = inf;
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            cin >> arr[i][j];
            id[i][j] = arr[i][j] - 'a';
        }
    }
    if (n == 1) {
        if (k == 0)
            cout << arr[1][1];
        else
            cout << 'a';
        return 0;
    }
    for (int i = 1; i < (2 * n - 1); i++) {
        v.clear();
        int x, y;
        if (i < n) {
            x = n;
            y = n - i;
        }
        else {
            y = 1;
            x = n - (i - (n - 1));
        }
        while (y <= n && x >= 1) {
            v.pb({{id[x][y], min(nid[x + 1][y], nid[x][y + 1])}, {x, y}});
            x--;
            y++;
        }
        sort(v.begin(), v.end());
        id[v.front().y.x][v.front().y.y] = 1;
        int ptr = 1;
        for (int i = 1; i < v.size(); i++) {
            if (v[i].x != v[i - 1].x)
                ptr++;
            id[v[i].y.x][v[i].y.y] = ptr;
        }
    }
    int stx = 1, sty = 1;
    if (k != 0) {
        if (arr[1][1] != 'a')
            cost[1][1] = 1;
        else
            cost[1][1] = 0;
        vector< pair<int, int> > v;
        v.pb({1, 1});
        int posx = v[0].x, posy = v[0].y;
        for (int i = 1; i < (2 * n - 1); i++) {
            v.clear();
            int x, y;
            if (i < n) {
                x = i + 1;
                y = 1;
            }
            else {
                x = n;
                y = i - (n - 1);
            }
            while (y <= n && x >= 1) {
                cost[x][y] = min(cost[x - 1][y], cost[x][y - 1]);
                if (arr[x][y] != 'a')
                    cost[x][y]++;
                if (cost[x][y] <= k) {
                    v.pb({x, y});
                }
                // cout << " " << x << " " << y << " " << cost[x][y] << endl;
                x--;
                y++;
            }
            sort(v.begin(), v.end(), comp);
            if (!v.empty()) {
                posx = v[0].x;
                posy = v[0].y;
            }
        }
        // cout << posx << " " << posy << endl;
        for (int i = 1; i < (posx + posy); i++)
            cout << 'a';
        stx = posx;
        sty = posy;
        if (id[posx + 1][posy] <= id[posx][posy + 1]) {
            stx++;
        } else {
            sty++;
        }
    }
    // cout<<endl;
    while (stx <= n && sty <= n) {
        // cout<<stx<<" "<<sty<<endl;
        cout << arr[stx][sty];
        if (id[stx + 1][sty] <= id[stx][sty + 1])
            stx++;
        else
            sty++;
    }
    return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define pb push_back
#define x first
#define y second
#define fastread ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define PI (atan(1)*4)
#define mp make_pair
using namespace std;
const int maxn = 2002, inf = 1005;

#define pt pair< pair<int,int>, pair<int,int> >

int id[maxn][maxn], nid[maxn][maxn], n, k, cost[maxn][maxn];
char arr[maxn][maxn];
vector< pt > v;

bool comp(pair<int, int> a, pair<int, int> b) {
    if (cost[a.x][a.y] != cost[b.x][b.y])
        return cost[a.x][a.y] < cost[b.x][b.y];
    else
        return id[a.x][a.y] < id[b.x][b.y];
}

int main()
{
    fastread;
    cin >> n >> k;
    for (int i = 0; i < maxn; i++) {
        for (int j = 0; j < maxn; j++) {
            id[i][j] = inf;
            cost[i][j] = inf;
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            cin >> arr[i][j];
            id[i][j] = arr[i][j] - 'a';
        }
    }
    if (n == 1) {
        if (k == 0)
            cout << arr[1][1];
        else
            cout << 'a';
        return 0;
    }
    for (int i = 1; i < (2 * n - 1); i++) {
        v.clear();
        int x, y;
        if (i < n) {
            x = n;
            y = n - i;
        }
        else {
            y = 1;
            x = n - (i - (n - 1));
        }
        while (y <= n && x >= 1) {
            v.pb({{id[x][y], min(nid[x + 1][y], nid[x][y + 1])}, {x, y}});
            x--;
            y++;
        }
        sort(v.begin(), v.end());
        id[v.front().y.x][v.front().y.y] = 1;
        int ptr = 1;
        for (int i = 1; i < v.size(); i++) {
            if (v[i].x != v[i - 1].x)
                ptr++;
            id[v[i].y.x][v[i].y.y] = ptr;
        }
    }
    int stx = 1, sty = 1;
    if (k != 0) {
        if (arr[1][1] != 'a')
            cost[1][1] = 1;
        else
            cost[1][1] = 0;
        vector< pair<int, int> > v;
        v.pb({1, 1});
        int posx = v[0].x, posy = v[0].y;
        for (int i = 1; i < (2 * n - 1); i++) {
            v.clear();
            int x, y;
            if (i < n) {
                x = i+1;
                y = 1;
            }
            else {
                x = n;
                y = i - (n - 1);
            }
            while (y <= n && x >= 1) {
                cost[x][y] = min(cost[x - 1][y], cost[x][y - 1]);
                if (arr[x][y] != 'a')
                    cost[x][y]++;
                if (cost[x][y] <= k) {
                    v.pb({x, y});
                }
                // cout << " " << x << " " << y << " " << cost[x][y] << endl;
                x--;
                y++;
            }
            sort(v.begin(), v.end(), comp);
            if (!v.empty()) {
                posx = v[0].x;
                posy = v[0].y;
            }
        }
        // cout << posx << " " << posy << endl;
        for (int i = 1; i < (posx + posy); i++)
            cout << 'a';
        stx = posx;
        sty = posy;
        if (id[posx + 1][posy] <= id[posx][posy + 1]) {
            stx++;
        } else {
            sty++;
        }
    }
    // cout<<endl;
    while (stx <= n && sty <= n) {
        // cout<<stx<<" "<<sty<<endl;
        cout << arr[stx][sty];
        if (id[stx + 1][sty] <= id[stx][sty + 1])
            stx++;
        else
            sty++;
    }
    return 0;
}


#include <bits/stdc++.h>

#define fr first
#define sc second
#define mk make_pair
#define ll long long
#define pb push_back
#define sz(s) (int)s.size()
#define all(s) s.begin(), s.end()

using namespace std;

const int N = 2e5+10;
const int inf = 1e9+7;

int n, k, an = 0;
char c[3000][3000];
int dp[3000][3000];
int u[3000][3000];
vector <pair <int, int> > v;

void go() {
    vector <pair <int, int> > cr;
    char h = char('z' + 1);
    for(auto i : v) {
        if(i.fr + 1 <= n) h = min(h, c[i.fr + 1][i.sc]);
        if(i.sc + 1 <= n) h = min(h, c[i.fr][i.sc + 1]);
    }
    if(h == char('z' + 1)) return;
    cout << h;
    for(auto i : v) {
        if(i.fr + 1 <= n && c[i.fr + 1][i.sc] == h && !u[i.fr + 1][i.sc]) {
            u[i.fr + 1][i.sc] = 1;
            cr.pb(mk(i.fr + 1, i.sc));
        }
        if(i.sc + 1 <= n && c[i.fr][i.sc + 1] == h && !u[i.fr][i.sc + 1]) {
            u[i.fr][i.sc + 1] = 1;
            cr.pb(mk(i.fr, i.sc + 1));
        }
    }
    v.swap(cr);
    go();
}

int main() {
    cin >> n >> k;

    for(int i = 1; i <= n; i++) {
        scanf("\n");
        for(int j = 1; j <= n; j++) {
            scanf("%c", &c[i][j]);
            int o = 1;
            if(c[i][j] == 'a') o = 0;
            if(i == 1 && j == 1)
                dp[i][j] = o;
            else if(i == 1)
                dp[i][j] = dp[i][j - 1] + o;
            else if(j == 1)
                dp[i][j] = dp[i - 1][j] + o;
            else
                dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + o;
            if(dp[i][j] == k) {
                an = max(an, i + j);
            }
        }
    }
    if(k == 0) {
        v.pb(mk(1, 1));
        cout << c[1][1];
        go();
    }
    else {
        for(int i = 1; i < an; i++) {
            if(dp[i][an - i] == k) {
                v.pb(mk(i, an - i));
            }
        }
        for(int i = 1; i < an ; i++)
            cout << 'a';
        go();
    }
}


#include <bits/stdc++.h>

#define fr first
#define sc second
#define mk make_pair
#define ll long long
#define pb push_back
#define sz(s) (int)s.size()
#define all(s) s.begin(), s.end()

using namespace std;

const int N = 2e5+10;
const int inf = 1e9+7;

int n, k, an = 0;
char c[3000][3000];
int dp[3000][3000];
int u[3000][3000];
vector <pair <int, int> > v;

void go() {
    vector <pair <int, int> > cr;
    char h = char('z' + 1);
    for(auto i : v) {
        if(i.fr + 1 <= n) h = min(h, c[i.fr + 1][i.sc]);
        if(i.sc + 1 <= n) h = min(h, c[i.fr][i.sc + 1]);
    }
    if(h == char('z' + 1)) return;
    cout << h;
    for(auto i : v) {
        if(i.fr + 1 <= n && c[i.fr + 1][i.sc] == h && !u[i.fr + 1][i.sc]) {
            u[i.fr + 1][i.sc] = 1;
            cr.pb(mk(i.fr + 1, i.sc));
        }
        if(i.sc + 1 <= n && c[i.fr][i.sc + 1] == h && !u[i.fr][i.sc + 1]) {
            u[i.fr][i.sc + 1] = 1;
            cr.pb(mk(i.fr, i.sc + 1));
        }
    }
    v.swap(cr);
    go();
}

int main() {
    cin >> n >> k;
    if(k >= 2 * n - 1) {
        for(int i = 1; i <= 2 * n - 1; i++)
            cout << 'a';
        return 0;
    }
    for(int i = 1; i <= n; i++) {
        scanf("\n");
        for(int j = 1; j <= n; j++) {
            scanf("%c", &c[i][j]);
            int o = 1;
            if(c[i][j] == 'a') o = 0;
            if(i == 1 && j == 1)
                dp[i][j] = o;
            else if(i == 1)
                dp[i][j] = dp[i][j - 1] + o;
            else if(j == 1)
                dp[i][j] = dp[i - 1][j] + o;
            else
                dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + o;
            if(dp[i][j] == k) {
                an = max(an, i + j);
            }
        }
    }
    if(k == 0) {
        v.pb(mk(1, 1));
        cout << c[1][1];
        go();
    }
    else {
        for(int i = 1; i < an; i++) {
            if(dp[i][an - i] == k) {
                v.pb(mk(i, an - i));
            }
        }
        for(int i = 1; i < an ; i++)
            cout << 'a';
        go();
    }
}


#include <bits/stdc++.h>

#define fr first
#define sc second
#define mk make_pair
#define ll long long
#define pb push_back
#define sz(s) (int)s.size()
#define all(s) s.begin(), s.end()

using namespace std;

const int N = 2e5+10;
const int inf = 1e9+7;

int n, k, an = 0;
char c[3000][3000];
int dp[3000][3000];
int u[3000][3000];
vector <pair <int, int> > v;

void go() {
    vector <pair <int, int> > cr;
    char h = char('z' + 1);
    for(auto i : v) {
        if(i.fr + 1 <= n) h = min(h, c[i.fr + 1][i.sc]);
        if(i.sc + 1 <= n) h = min(h, c[i.fr][i.sc + 1]);
    }
    if(h == char('z' + 1)) return;
    cout << h;
    for(auto i : v) {
        if(i.fr + 1 <= n && c[i.fr + 1][i.sc] == h && !u[i.fr + 1][i.sc]) {
            u[i.fr + 1][i.sc] = 1;
            cr.pb(mk(i.fr + 1, i.sc));
        }
        if(i.sc + 1 <= n && c[i.fr][i.sc + 1] == h && !u[i.fr][i.sc + 1]) {
            u[i.fr][i.sc + 1] = 1;
            cr.pb(mk(i.fr, i.sc + 1));
        }
    }
    v.swap(cr);
    go();
}

int main() {
    cin >> n >> k;
    if(k >= 2 * n - 1) {
        for(int i = 1; i <= 2 * n - 1; i++)
            cout << 'a';
        return 0;
    }
    for(int i = 1; i <= n; i++) {
        scanf("\n");
        for(int j = 1; j <= n; j++) {
            scanf("%c", &c[i][j]);
            int o = 1;
            if(c[i][j] == 'a') o = 0;
            if(i == 1 && j == 1)
                dp[i][j] = o;
            else if(i == 1)
                dp[i][j] = dp[i][j - 1] + o;
            else if(j == 1)
                dp[i][j] = dp[i - 1][j] + o;
            else
                dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + o;
            if(dp[i][j] <= k) {
                an = max(an, i + j);
            }
        }
    }
    if(k == 0) {
        v.pb(mk(1, 1));
        cout << c[1][1];
        go();
    }
    else {
        for(int i = 1; i < an; i++) {
            if(i <= n && an - i <= n && dp[i][an - i] == k) {
                v.pb(mk(i, an - i));
            }
        }
        for(int i = 1; i < an ; i++)
            cout << 'a';
        go();
    }
}


#include <bits/stdc++.h>

#define fr first
#define sc second
#define mk make_pair
#define ll long long
#define pb push_back
#define sz(s) (int)s.size()
#define all(s) s.begin(), s.end()

using namespace std;

const int N = 2e5+10;
const int inf = 1e9+7;

int n, k, an = 0;
char c[3000][3000];
int dp[3000][3000];
int u[3000][3000];
vector <pair <int, int> > v;

void go() {
    vector <pair <int, int> > cr;
    char h = char('z' + 1);
    for(auto i : v) {
        if(i.fr + 1 <= n) h = min(h, c[i.fr + 1][i.sc]);
        if(i.sc + 1 <= n) h = min(h, c[i.fr][i.sc + 1]);
    }
    if(h == char('z' + 1)) return;
    cout << h;
    for(auto i : v) {
        if(i.fr + 1 <= n && c[i.fr + 1][i.sc] == h && !u[i.fr + 1][i.sc]) {
            u[i.fr + 1][i.sc] = 1;
            cr.pb(mk(i.fr + 1, i.sc));
        }
        if(i.sc + 1 <= n && c[i.fr][i.sc + 1] == h && !u[i.fr][i.sc + 1]) {
            u[i.fr][i.sc + 1] = 1;
            cr.pb(mk(i.fr, i.sc + 1));
        }
    }
    v.swap(cr);
    go();
}

int main() {
    cin >> n >> k;
    if(k >= 2 * n - 1) {
        for(int i = 1; i <= 2 * n - 1; i++)
            cout << 'a';
        return 0;
    }
    for(int i = 1; i <= n; i++) {
        scanf("\n");
        for(int j = 1; j <= n; j++) {
            scanf("%c", &c[i][j]);
            int o = 1;
            if(c[i][j] == 'a') o = 0;
            if(i == 1 && j == 1)
                dp[i][j] = o;
            else if(i == 1)
                dp[i][j] = dp[i][j - 1] + o;
            else if(j == 1)
                dp[i][j] = dp[i - 1][j] + o;
            else
                dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + o;
            if(dp[i][j] <= k) {
                an = max(an, i + j);
            }
        }
    }
    if(k == 0) {
        v.pb(mk(1, 1));
        cout << c[1][1];
        go();
    }
    else {
        for(int i = 1; i < an; i++) {
            if(an - i <= n && dp[i][an - i] == k) {
                v.pb(mk(i, an - i));
            }
        }
        for(int i = 1; i < an ; i++)
            cout << 'a';
        go();
    }
}


#include <bits/stdc++.h>

#define fr first
#define sc second
#define mk make_pair
#define ll long long
#define pb push_back
#define sz(s) (int)s.size()
#define all(s) s.begin(), s.end()

using namespace std;

const int N = 2e5+10;
const int inf = 1e9+7;

int n, k, an = 0;
char c[5000][5000];
int dp[5000][5000];
int u[5000][5000];
vector <pair <int, int> > v;

void go() {
    vector <pair <int, int> > cr;
    char h = char('z' + 1);
    for(auto i : v) {
        if(i.fr + 1 <= n) h = min(h, c[i.fr + 1][i.sc]);
        if(i.sc + 1 <= n) h = min(h, c[i.fr][i.sc + 1]);
    }
    if(h == char('z' + 1)) return;
    cout << h;
    for(auto i : v) {
        if(i.fr + 1 <= n && c[i.fr + 1][i.sc] == h && !u[i.fr + 1][i.sc]) {
            u[i.fr + 1][i.sc] = 1;
            cr.pb(mk(i.fr + 1, i.sc));
        }
        if(i.sc + 1 <= n && c[i.fr][i.sc + 1] == h && !u[i.fr][i.sc + 1]) {
            u[i.fr][i.sc + 1] = 1;
            cr.pb(mk(i.fr, i.sc + 1));
        }
    }
    v.swap(cr);
    go();
}

int main() {
    cin >> n >> k;
    if(k >= 2 * n - 1) {
        for(int i = 1; i <= 2 * n - 1; i++)
            cout << 'a';
        return 0;
    }
    for(int i = 1; i <= n; i++) {
        scanf("\n");
        for(int j = 1; j <= n; j++) {
            scanf("%c", &c[i][j]);
            int o = 1;
            if(c[i][j] == 'a') o = 0;
            if(i == 1 && j == 1)
                dp[i][j] = o;
            else if(i == 1)
                dp[i][j] = dp[i][j - 1] + o;
            else if(j == 1)
                dp[i][j] = dp[i - 1][j] + o;
            else
                dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + o;
            if(dp[i][j] <= k) {
                an = max(an, i + j);
            }
        }
    }
    if(k == 0) {
        v.pb(mk(1, 1));
        cout << c[1][1];
        go();
    }
    else {
        for(int i = 1; i < an; i++) {
            if(dp[i][an - i] == k) {
                v.pb(mk(i, an - i));
            }
        }
        for(int i = 1; i < an ; i++)
            cout << 'a';
        go();
    }
}


#include <bits/stdc++.h>

#define fr first
#define sc second
#define mk make_pair
#define ll long long
#define pb push_back
#define sz(s) (int)s.size()
#define all(s) s.begin(), s.end()

using namespace std;

const int N = 2e5+10;
const int inf = 1e9+7;

int n, k, an = 0;
char c[3000][3000];
int dp[3000][3000];
int u[3000][3000];
vector <pair <int, int> > v;

void go() {
    vector <pair <int, int> > cr;
    char h = char('z' + 1);
    for(auto i : v) {
        if(i.fr + 1 <= n) h = min(h, c[i.fr + 1][i.sc]);
        if(i.sc + 1 <= n) h = min(h, c[i.fr][i.sc + 1]);
    }
    if(h == char('z' + 1)) return;
    cout << h;
    for(auto i : v) {
        if(i.fr + 1 <= n && c[i.fr + 1][i.sc] == h && !u[i.fr + 1][i.sc]) {
            u[i.fr + 1][i.sc] = 1;
            cr.pb(mk(i.fr + 1, i.sc));
        }
        if(i.sc + 1 <= n && c[i.fr][i.sc + 1] == h && !u[i.fr][i.sc + 1]) {
            u[i.fr][i.sc + 1] = 1;
            cr.pb(mk(i.fr, i.sc + 1));
        }
    }
    v.swap(cr);
    go();
}

int main() {
    cin >> n >> k;
    if(k >= 2 * n - 1) {
        for(int i = 1; i <= 2 * n - 1; i++)
            cout << 'a';
        return 0;
    }
    for(int i = 1; i <= n; i++) {
        scanf("\n");
        for(int j = 1; j <= n; j++) {
            scanf("%c", &c[i][j]);
            int o = 1;
            if(c[i][j] == 'a') o = 0;
            if(i == 1 && j == 1)
                dp[i][j] = o;
            else if(i == 1)
                dp[i][j] = dp[i][j - 1] + o;
            else if(j == 1)
                dp[i][j] = dp[i - 1][j] + o;
            else
                dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + o;
            if(dp[i][j] <= k) {
                an = max(an, i + j);
            }
        }
    }
    if(k == 0) {
        v.pb(mk(1, 1));
        cout << c[1][1];
        go();
    }
    else {
        for(int i = 1; i < an; i++) {
            if(dp[i][an - i] == k) {
                v.pb(mk(i, an - i));
            }
        }
        for(int i = 1; i < an ; i++)
            cout << 'a';
        go();
    }
}


#include <bits/stdc++.h>
using namespace std;

using pii = pair<int,int>;
const int maxn = 2020;
int n, k;
char G[maxn][maxn];
queue<pii> pq;
int p[maxn][maxn];
vector<char> ret;
bool flag;
int dp[maxn][maxn];

bool ok(int x, int y) {
	return x >= 1 && x <= n && y >= 1 && y <= n;
}

void dfs(int x, int y) {
	if(x == 1 && y == 1) {
		reverse(ret.begin(), ret.end());
		int cnt = 0;
		for(int i = 0; i < ret.size(); i++) {
			printf("%c", ret[i]);
		}
		printf("\n");
		flag = 1;
		return;
	}
	if(ok(x-1,y)&&p[x-1][y]) {
		ret.push_back(G[x-1][y]);
		dfs(x-1,y);
		if(flag) return;
		ret.pop_back();
	}
	if(ok(x,y-1)&&p[x][y-1]) {
		ret.push_back(G[x][y-1]);
		dfs(x,y-1);
		if(flag) return;
		ret.pop_back();
	}
}

bool vis[maxn][maxn];

signed main() {
	// freopen("in", "r", stdin);
	while(~scanf("%d%d",&n,&k)) {
		flag = 0;
		memset(vis, 0, sizeof vis);
		memset(p, 0, sizeof p);
		memset(dp ,0, sizeof(dp));
		for(int i = 1; i <= n; i++) {
			scanf("%s", G[i]+1);
		}
		for(int i = 1; i <= n; i++) {
			for(int j = 1; j <= n; j++) {
				dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
				if(G[i][j] == 'a') dp[i][j]++;
				if(i + j - 1 - dp[i][j] <= k) G[i][j] = 'a';
			}
		}
		pq.push(pii(1, 1));
		p[1][1] = 1;
		while(!pq.empty()) {
			vector<pii> tmp;
			int cur = 200;
			while(!pq.empty()) {
				tmp.push_back(pq.front());
				cur = min(cur, (int)G[pq.front().first][pq.front().second]);
				pq.pop();
			}
			for(int i = 0; i < tmp.size(); i++) {
				int x = tmp[i].first, y = tmp[i].second;
				if(cur == (int)G[x][y]) {
					p[x][y] = 1;
					if(ok(x+1, y)&&!vis[x+1][y]) {
						vis[x+1][y] = 1;
						pq.push(pii(x+1, y));
					}
					if(ok(x, y+1)&&!vis[x][y+1]) {
						vis[x][y+1] = 1;
						pq.push(pii(x, y+1));
					}
				}
			}
		}
		ret.clear();
		ret.push_back(G[n][n]);
		dfs(n,n);
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

using pii = pair<int,int>;
const int maxn = 2020;
int n, k;
char G[maxn][maxn];
queue<pii> pq;
int p[maxn][maxn];
vector<char> ret;
bool flag;
int dp[maxn][maxn];

bool ok(int x, int y) {
	return x >= 1 && x <= n && y >= 1 && y <= n;
}

void dfs(int x, int y) {
	if(x == 1 && y == 1) {
		reverse(ret.begin(), ret.end());
		int cnt = 0;
		for(int i = 0; i < ret.size(); i++) {
			printf("%c", ret[i]);
		}
		printf("\n");
		flag = 1;
		return;
	}
	if(ok(x-1,y)&&p[x-1][y]) {
		ret.push_back(G[x-1][y]);
		dfs(x-1,y);
		if(flag) return;
		ret.pop_back();
	}
	if(ok(x,y-1)&&p[x][y-1]) {
		ret.push_back(G[x][y-1]);
		dfs(x,y-1);
		if(flag) return;
		ret.pop_back();
	}
}

bool vis[maxn][maxn];

signed main() {
	// freopen("in", "r", stdin);
	while(~scanf("%d%d",&n,&k)) {
		flag = 0;
		memset(vis, 0, sizeof vis);
		memset(p, 0, sizeof p);
		memset(dp ,0, sizeof(dp));
		for(int i = 1; i <= n; i++) {
			scanf("%s", G[i]+1);
		}
		for(int i = 1; i <= n; i++) {
			for(int j = 1; j <= n; j++) {
				dp[i][j] = max(dp[i-1][j], dp[i][j-1]) + (G[i][j] == 'a');
				if(i + j - 1 - dp[i][j] <= k) G[i][j] = 'a';
			}
		}
		pq.push(pii(1, 1));
		p[1][1] = 1;
		while(!pq.empty()) {
			vector<pii> tmp;
			int cur = 200;
			while(!pq.empty()) {
				tmp.push_back(pq.front());
				cur = min(cur, (int)G[pq.front().first][pq.front().second]);
				pq.pop();
			}
			for(int i = 0; i < tmp.size(); i++) {
				int x = tmp[i].first, y = tmp[i].second;
				if(cur == (int)G[x][y]) {
					p[x][y] = 1;
					if(ok(x+1, y)&&!vis[x+1][y]) {
						vis[x+1][y] = 1;
						pq.push(pii(x+1, y));
					}
					if(ok(x, y+1)&&!vis[x][y+1]) {
						vis[x][y+1] = 1;
						pq.push(pii(x, y+1));
					}
				}
			}
		}
		ret.clear();
		ret.push_back(G[n][n]);
		dfs(n,n);
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

using pii = pair<int,int>;
const int maxn = 2020;
int n, k;
char G[maxn][maxn];
queue<pii> pq;
int p[maxn][maxn];
vector<char> ret;
bool flag;

bool ok(int x, int y) {
	return x >= 1 && x <= n && y >= 1 && y <= n;
}

void dfs(int x, int y) {
	if(x == 1 && y == 1) {
		reverse(ret.begin(), ret.end());
		int cnt = 0;
		for(int i = 0; i < ret.size(); i++) {
			if(ret[i] == 'a') printf("%c", ret[i]);
			else printf("%c", cnt++>=k?ret[i]:'a');
		}
		printf("\n");
		flag = 1;
		return;
	}
	if(ok(x-1,y)&&p[x-1][y]) {
		ret.push_back(G[x-1][y]);
		dfs(x-1,y);
		if(flag) return;
		ret.pop_back();
	}
	if(ok(x,y-1)&&p[x][y-1]) {
		ret.push_back(G[x][y-1]);
		dfs(x,y-1);
		if(flag) return;
		ret.pop_back();
	}
}

bool vis[maxn][maxn];

signed main() {
	// freopen("in", "r", stdin);
	while(~scanf("%d%d",&n,&k)) {
		for(int i = 1; i <= n; i++) {
			scanf("%s", G[i]+1);
		}
		flag = 0;
		memset(vis, 0, sizeof vis);
		memset(p, 0, sizeof p);
		pq.push(pii(1, 1));
		p[1][1] = 1;
		while(!pq.empty()) {
			vector<pii> tmp;
			int cur = 200;
			while(!pq.empty()) {
				tmp.push_back(pq.front());
				cur = min(cur, (int)G[pq.front().first][pq.front().second]);
				pq.pop();
			}
			for(int i = 0; i < tmp.size(); i++) {
				int x = tmp[i].first, y = tmp[i].second;
				if(cur == (int)G[x][y]) {
					p[x][y] = 1;
					if(ok(x+1, y)&&!vis[x+1][y]) {
						vis[x+1][y] = 1;
						pq.push(pii(x+1, y));
					}
					if(ok(x, y+1)&&!vis[x][y+1]) {
						vis[x][y+1] = 1;
						pq.push(pii(x, y+1));
					}
				}
			}
		}
		ret.clear();
		ret.push_back(G[n][n]);
		dfs(n,n);
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int maxn = 2020;
int n, k;
char G[maxn][maxn];
typedef struct Node {
	int x, y, p, py;
}Node;

queue<Node> pq;
int p[maxn][maxn];
vector<char> ret;
bool flag;

bool ok(int x, int y) {
	return x >= 1 && x <= n && y >= 1 && y <= n;
}

void dfs(int x, int y) {
	if(x == 1 && y == 1) {
		reverse(ret.begin(), ret.end());
		int cnt = 0;
		for(int i = 0; i < ret.size(); i++) {
			if(ret[i] == 'a') printf("%c", ret[i]);
			else printf("%c", cnt++>=k?ret[i]:'a');
		}
		printf("\n");
		flag = 1;
		return;
	}
	if(ok(x-1,y)&&p[x-1][y]) {
		ret.push_back(G[x-1][y]);
		dfs(x-1,y);
		if(flag) return;
		ret.pop_back();
	}
	if(ok(x,y-1)&&p[x][y-1]) {
		ret.push_back(G[x][y-1]);
		dfs(x,y-1);
		if(flag) return;
		ret.pop_back();
	}
}

signed main() {
	// freopen("in", "r", stdin);
	while(~scanf("%d%d",&n,&k)) {
		for(int i = 1; i <= n; i++) {
			scanf("%s", G[i]+1);
		}
		flag = 0;
		memset(p, 0, sizeof p);
		pq.push(Node{1, 1, -1, -1});
		p[1][1] = 1;
		while(!pq.empty()) {
			vector<Node> tmp;
			int cur = 200;
			while(!pq.empty()) {
				tmp.push_back(pq.front());
				cur = min(cur, (int)G[pq.front().x][pq.front().y]);
				pq.pop();
			}
			assert(pq.empty());
			for(int i = 0; i < tmp.size(); i++) {
				int x = tmp[i].x, y = tmp[i].y;
				if(cur == (int)G[x][y]) {
					p[x][y] = 1;
					if(ok(x+1, y)) pq.push(Node{x+1, y});
					if(ok(x, y+1)) pq.push(Node{x, y+1});
				}
			}
		}
		ret.clear();
		ret.push_back(G[n][n]);
		dfs(n,n);
	}
	return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#define debug(x) //std::cerr << #x << " = " << (x) << std::endl
using namespace std;
typedef long long LL;
const int MAXN = 2e3 + 17;
const int MOD = 998244353;
int n,vis[MAXN][MAXN],k;
char mp[MAXN][MAXN];
int f[MAXN][MAXN];
string ans;
queue<pair<int,int > > que;
void dfs(int x,int y)
{
	debug(x);
	debug(y);
	debug(ans);
	if(x==n-1&&y==n-1)
	{
		return ;
	}
	else if(x==n-1)
	{
		ans.push_back(mp[x][y+1]);
		dfs(x,y+1);
	}
	else if(y==n-1)
	{
		ans.push_back(mp[x+1][y]);
		dfs(x+1,y);
	}
	else
	{
		if(mp[x][y+1]<mp[x+1][y])
		{
			ans.push_back(mp[x][y+1]);
			dfs(x,y+1);
		}
		else if(mp[x][y+1]>mp[x+1][y])
		{
			ans.push_back(mp[x+1][y]);
			dfs(x+1,y);
		}
		else
		{
			if(x!=-1&&y!=-1)
			{
				ans.push_back(mp[x+1][y]);
				if(y+1!=n)	que.push({x,y+1});
				if(x+1!=n)	que.push({x+1,y});
			}
			int sx,sy;
			while(que.size()>1)
			{
				queue<pair<int,int > > nque;
				char mn = 'z'+1;
				int sum = 0;
				while(que.size())
				{
					auto now = que.front();
					que.pop();
					int tx = now.first,ty = now.second;
					debug(tx);
					debug(ty);
					if(tx+1<n&&!vis[tx+1][ty])
					{
						vis[tx+1][ty] = 1;
						if(mp[tx+1][ty]<=mn)
						{
							debug(mp[tx+1][ty]);
							nque.push({tx+1,ty});
							if(mp[tx+1][ty]!=mn)
								sum = 0,sx = tx+1,sy = ty;
							mn = mp[tx+1][ty];
							++sum;
						}
					}
					if(ty+1<n&&vis[tx][ty+1]!=1)
					{
						vis[tx][ty+1] = 1;
						if(mp[tx][ty+1]<=mn)
						{
							debug(mp[tx][ty+1]);
							nque.push({tx,ty+1});
							if(mp[tx][ty+1]!=mn)
								sum = 0,sx = tx,sy = ty+1;
							mn = mp[tx][ty+1];
							++sum;
						}
					}
				}
				debug(mn);
				ans.push_back(mn);
				if(sum==1) break;
				while(!nque.empty())
				{
					auto now = nque.front();
					nque.pop();
					if(mp[now.first][now.second]==mn)
						que.push(now);
				}
			}
			dfs(sx,sy);
		}
	}
}
int main(int argc, char const *argv[])
{
#ifdef noob
    freopen("Input.txt", "r", stdin);
    freopen("Output.txt", "w", stdout);
#endif
	cin>>n>>k;
	for (int i = 0; i < n; i++)
	{
		cin>>mp[i];
	}
	int mx = 0;
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			int l = j==0?100000000:f[i][j-1];
			int u = i==0?100000000:f[i-1][j];
			f[i][j] = min(l,u)+(mp[i][j]=='a'?0:1);
			if(i+j==0) f[i][j] = mp[i][j]=='a'?0:1;
			if(f[i][j]<=k) mx = max(mx,i+j);
		}
	}
	debug(f[0][0]);
	debug(f[0][1]);
	debug(f[0][2]);
	debug(mx);
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			if(j == mx-i)
				if(f[i][j]<=k)
				{
					debug(i);
					debug(j);
					que.push({i,j});
				}
		}
	}
	dfs(-1,-1);
	debug(ans);
	mx++;
	while(mx--)
		ans = "a"+ans;
	// for(auto & i: ans)
	// {
	// 	if(k==2292) i = 'a';
	// 	else if(k&&i!='a') i = 'a',--k;
	// }
	cout<<ans<<endl;
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#define debug(x) //std::cerr << #x << " = " << (x) << std::endl
using namespace std;
typedef long long LL;
const int MAXN = 2e3 + 17;
const int MOD = 998244353;
int n,vis[MAXN][MAXN],k;
char mp[MAXN][MAXN];
int f[MAXN][MAXN];
string ans;
queue<pair<int,int > > que;
void dfs(int x,int y)
{
	debug(x);
	debug(y);
	debug(ans);
	if(x==n-1&&y==n-1)
	{
		return ;
	}
	else if(x==n-1)
	{
		ans.push_back(mp[x][y+1]);
		dfs(x,y+1);
	}
	else if(y==n-1)
	{
		ans.push_back(mp[x+1][y]);
		dfs(x+1,y);
	}
	else
	{
		if(mp[x][y+1]<mp[x+1][y])
		{
			ans.push_back(mp[x][y+1]);
			dfs(x,y+1);
		}
		else if(mp[x][y+1]>mp[x+1][y])
		{
			ans.push_back(mp[x+1][y]);
			dfs(x+1,y);
		}
		else
		{
			if(x!=-1&&y!=-1)
			{
				ans.push_back(mp[x+1][y]);
				if(y+1!=n)	que.push({x,y+1});
				if(x+1!=n)	que.push({x+1,y});
			}
			int sx,sy;
			while(que.size()>1)
			{
				queue<pair<int,int > > nque;
				char mn = 'z'+1;
				int sum = 0;
				while(que.size())
				{
					auto now = que.front();
					que.pop();
					int tx = now.first,ty = now.second;
					debug(tx);
					debug(ty);
					if(tx+1<n&&!vis[tx+1][ty])
					{
						vis[tx+1][ty] = 1;
						if(mp[tx+1][ty]<=mn)
						{
							debug(mp[tx+1][ty]);
							nque.push({tx+1,ty});
							if(mp[tx+1][ty]!=mn)
								sum = 0,sx = tx+1,sy = ty;
							mn = mp[tx+1][ty];
							++sum;
						}
					}
					if(ty+1<n&&vis[tx][ty+1]!=1)
					{
						vis[tx][ty+1] = 1;
						if(mp[tx][ty+1]<=mn)
						{
							debug(mp[tx][ty+1]);
							nque.push({tx,ty+1});
							if(mp[tx][ty+1]!=mn)
								sum = 0,sx = tx,sy = ty+1;
							mn = mp[tx][ty+1];
							++sum;
						}
					}
				}
				debug(mn);
				ans.push_back(mn);
				if(sum==1) break;
				while(!nque.empty())
				{
					auto now = nque.front();
					nque.pop();
					if(mp[now.first][now.second]==mn)
						que.push(now);
				}
			}
			dfs(sx,sy);
		}
	}
}
int main(int argc, char const *argv[])
{
#ifdef noob
    freopen("Input.txt", "r", stdin);
    freopen("Output.txt", "w", stdout);
#endif
	cin>>n>>k;
	for (int i = 0; i < n; i++)
	{
		cin>>mp[i];
	}
	int mx = 0;
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			int l = j==0?100000000:f[i][j-1];
			int u = i==0?100000000:f[i-1][j];
			f[i][j] = min(l,u)+(mp[i][j]=='a'?0:1);
			if(i+j==0) f[i][j] = mp[i][j]=='a'?0:1;
			if(f[i][j]<=k) mx = max(mx,i+j);
		}
	}
	debug(f[0][0]);
	debug(f[0][1]);
	debug(f[0][2]);
	debug(mx);
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			if(j == mx-i)
				if(f[i][j]<=k)
				{
					debug(i);
					debug(j);
					que.push({i,j});
				}
		}
	}
	if(mx!=0)	dfs(-1,-1);
	else dfs(0,0);
	debug(ans);
	if(mx!=0) mx++;
	else
	{
		string nil = "";
		nil.push_back(mp[0][0]);
		ans = nil+ans;
	}
	while(mx--)
		ans = "a"+ans;
	// for(auto & i: ans)
	// {
	// 	if(k==2292) i = 'a';
	// 	else if(k&&i!='a') i = 'a',--k;
	// }
	cout<<ans<<endl;
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#define debug(x) //std::cerr << #x << " = " << (x) << std::endl
using namespace std;
typedef long long LL;
const int MAXN = 2e3 + 17;
const int MOD = 998244353;
int n,vis[MAXN][MAXN],k;
char mp[MAXN][MAXN];
int f[MAXN][MAXN];
string ans;
queue<pair<int,int > > que;
void dfs(int x,int y)
{
	debug(x);
	debug(y);
	debug(ans);
	if(x==n-1&&y==n-1)
	{
		return ;
	}
	else if(x==n-1)
	{
		ans.push_back(mp[x][y+1]);
		dfs(x,y+1);
	}
	else if(y==n-1)
	{
		ans.push_back(mp[x+1][y]);
		dfs(x+1,y);
	}
	else
	{
		if(mp[x][y+1]<mp[x+1][y])
		{
			ans.push_back(mp[x][y+1]);
			dfs(x,y+1);
		}
		else if(mp[x][y+1]>mp[x+1][y])
		{
			ans.push_back(mp[x+1][y]);
			dfs(x+1,y);
		}
		else
		{
			if(x!=-1&&y!=-1)
			{
				ans.push_back(mp[x+1][y]);
				if(y+1!=n)	que.push({x,y+1});
				if(x+1!=n)	que.push({x+1,y});
			}
			int sx,sy;
			while(que.size()>1)
			{
				queue<pair<int,int > > nque;
				char mn = 'z'+1;
				int sum = 0;
				while(que.size())
				{
					auto now = que.front();
					que.pop();
					int tx = now.first,ty = now.second;
					debug(tx);
					debug(ty);
					if(tx+1<n&&!vis[tx+1][ty])
					{
						vis[tx+1][ty] = 1;
						if(mp[tx+1][ty]<=mn)
						{
							debug(mp[tx+1][ty]);
							nque.push({tx+1,ty});
							if(mp[tx+1][ty]!=mn)
								sum = 0,sx = tx+1,sy = ty;
							mn = mp[tx+1][ty];
							++sum;
						}
					}
					if(ty+1<n&&vis[tx][ty+1]!=1)
					{
						vis[tx][ty+1] = 1;
						if(mp[tx][ty+1]<=mn)
						{
							debug(mp[tx][ty+1]);
							nque.push({tx,ty+1});
							if(mp[tx][ty+1]!=mn)
								sum = 0,sx = tx,sy = ty+1;
							mn = mp[tx][ty+1];
							++sum;
						}
					}
				}
				debug(mn);
				ans.push_back(mn);
				if(sum==1) break;
				while(!nque.empty())
				{
					auto now = nque.front();
					nque.pop();
					if(mp[now.first][now.second]==mn)
						que.push(now);
				}
			}
			dfs(sx,sy);
		}
	}
}
int main(int argc, char const *argv[])
{
#ifdef noob
    freopen("Input.txt", "r", stdin);
    freopen("Output.txt", "w", stdout);
#endif
	cin>>n>>k;
	for (int i = 0; i < n; i++)
	{
		cin>>mp[i];
	}
	int mx = 0;
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			int l = j==0?100000000:f[i][j-1];
			int u = i==0?100000000:f[i-1][j];
			f[i][j] = min(l,u)+(mp[i][j]=='a'?0:1);
			if(i+j==0) f[i][j] = mp[i][j]=='a'?0:1;
			if(f[i][j]<=k) mx = max(mx,i+j);
		}
	}
	debug(f[0][0]);
	debug(f[0][1]);
	debug(f[0][2]);
	debug(mx);
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			if(j == mx-i)
				if(f[i][j]<=k)
				{
					debug(i);
					debug(j);
					que.push({i,j});
				}
		}
	}
	if(mx!=0)	dfs(-1,-1);
	else dfs(0,0);
	debug(ans);
	mx++;
	while(mx--)
		ans = "a"+ans;
	// for(auto & i: ans)
	// {
	// 	if(k==2292) i = 'a';
	// 	else if(k&&i!='a') i = 'a',--k;
	// }
	cout<<ans<<endl;
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <string>
#define debug(x) //std::cerr << #x << " = " << (x) << std::endl
using namespace std;
typedef long long LL;
const int MAXN = 2e3 + 17;
const int MOD = 998244353;
int n,vis[MAXN][MAXN],k;
char mp[MAXN][MAXN];
string f[MAXN][MAXN];
void dfs(int x,int y)
{
	if(vis[x][y]) return ;
	vis[x][y] = 1;
	string nil = "";
	nil.push_back(mp[x][y]);
	if(x==n-1&&y==n-1)
	{
		f[x][y] = nil;
	}
	else if(x==n-1)
	{
		dfs(x,y+1);
		f[x][y] = nil+f[x][y+1];
	}
	else if(y==n-1)
	{
		dfs(x+1,y);
		f[x][y] = nil+f[x+1][y];
	}
	else
	{
		dfs(x+1,y);
		dfs(x,y+1);
		if(mp[x][y+1]<mp[x+1][y])
		{
			f[x][y] = nil+f[x][y+1];
		}
		else if(mp[x][y+1]>mp[x+1][y])
			f[x][y] = nil+f[x+1][y];
		else
			f[x][y] = nil+min(f[x][y+1],f[x+1][y]);
	}
	debug(x);
	debug(y);
	debug(mp[x][y]);
	debug(nil);
	debug(f[x][y]);
}
int main(int argc, char const *argv[])
{
#ifdef noob
    freopen("Input.txt", "r", stdin);
    freopen("Output.txt", "w", stdout);
#endif
	cin>>n>>k;
	for (int i = 0; i < n; i++)
	{
		cin>>mp[i];
	}
	dfs(0,0);
	for(auto & i: f[0][0])
	{
		if(k&&i!='a') i = 'a',--k;
	}
	cout<<f[0][0]<<endl;
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <string>
#define debug(x) //std::cerr << #x << " = " << (x) << std::endl
using namespace std;
typedef long long LL;
const int MAXN = 2e3 + 17;
const int MOD = 998244353;
int n,vis[MAXN][MAXN],k;
pair<int,int > dir[MAXN][MAXN];
char mp[MAXN][MAXN];
string f[MAXN][MAXN];
string dfs(int x,int y)
{
	string nil = "";
	nil.push_back(mp[x][y]);
	if(vis[x][y])
	{
		if(x==n-1&&y==n-1)
			return nil;
		else
			return nil+dfs(x+dir[x][y].first,y+dir[x][y].second);
	}
	vis[x][y] = 1;
	if(x==n-1&&y==n-1)
	{
		return nil;
	}
	else if(x==n-1)
	{
		nil = nil + dfs(x,y+1);
		dir[x][y].first = 0,dir[x][y].second = 1;
	}
	else if(y==n-1)
	{
		nil = nil + dfs(x+1,y);
		dir[x][y].first = 1,dir[x][y].second = 0;
	}
	else
	{
		string s1 = dfs(x+1,y);
		string s2 = dfs(x,y+1);
		if(mp[x][y+1]<mp[x+1][y])
		{
			nil = nil + s1;
			dir[x][y].first = 0,dir[x][y].second = 1;
		}
		else if(mp[x][y+1]>mp[x+1][y])
		{
			nil = nil + s2;
			dir[x][y].first = 1,dir[x][y].second = 0;
		}
		else
		{
			if(s1<s2)
			{
				nil = nil + s1;
				dir[x][y].first = 0,dir[x][y].second = 1;
			}
			else
			{
				nil = nil + s2;
				dir[x][y].first = 1,dir[x][y].second = 0;
			}
		}
	}
	return nil;
}
int main(int argc, char const *argv[])
{
#ifdef noob
    freopen("Input.txt", "r", stdin);
    freopen("Output.txt", "w", stdout);
#endif
	cin>>n>>k;
	for (int i = 0; i < n; i++)
	{
		cin>>mp[i];
	}
	string ans = dfs(0,0);
	for(auto & i: ans)
	{
		if(k&&i!='a') i = 'a',--k;
	}
	cout<<ans<<endl;
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <string>
#define debug(x) //std::cerr << #x << " = " << (x) << std::endl
using namespace std;
typedef long long LL;
const int MAXN = 2e3 + 17;
const int MOD = 998244353;
int n,vis[MAXN][MAXN],k;
pair<int,int > dir[MAXN][MAXN];
char mp[MAXN][MAXN];
string f[MAXN][MAXN];
string dfs(int x,int y)
{
	string nil = "";
	nil.push_back(mp[x][y]);
	if(vis[x][y])
	{
		if(x==n-1&&y==n-1)
			return nil;
		else
			return nil+dfs(x+dir[x][y].first,y+dir[x][y].second);
	}
	vis[x][y] = 1;
	if(x==n-1&&y==n-1)
	{
		return nil;
	}
	else if(x==n-1)
	{
		nil = nil + dfs(x,y+1);
		dir[x][y].first = 0,dir[x][y].second = 1;
	}
	else if(y==n-1)
	{
		nil = nil + dfs(x+1,y);
		dir[x][y].first = 1,dir[x][y].second = 0;
	}
	else
	{
		string s1 = dfs(x+1,y);
		string s2 = dfs(x,y+1);

		if(mp[x][y+1]<mp[x+1][y])
		{
			nil = nil + s2;
			dir[x][y].first = 0,dir[x][y].second = 1;
		}
		else if(mp[x][y+1]>mp[x+1][y])
		{
			nil = nil + s1;
			dir[x][y].first = 1,dir[x][y].second = 0;
		}
		else
		{
			if(s1<s2)
			{
				nil = nil + s1;
				dir[x][y].first = 0,dir[x][y].second = 1;
			}
			else
			{
				nil = nil + s2;
				dir[x][y].first = 1,dir[x][y].second = 0;
			}
		}
		if(x==2&&y==0)
		{
			debug(s1);
			debug(s2);
			debug(nil);
		}
	}
	// debug(x);
	// debug(y);
	// debug(dir[x][y].first);
	// debug(dir[x][y].second);
	return nil;
}
int main(int argc, char const *argv[])
{
#ifdef noob
    freopen("Input.txt", "r", stdin);
    freopen("Output.txt", "w", stdout);
#endif
	cin>>n>>k;
	for (int i = 0; i < n; i++)
	{
		cin>>mp[i];
	}
	string ans = dfs(0,0);
	debug(ans);
	for(auto & i: ans)
	{
		if(k&&i!='a') i = 'a',--k;
	}
	cout<<ans<<endl;
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <string>
#define debug(x) //std::cerr << #x << " = " << (x) << std::endl
using namespace std;
typedef long long LL;
const int MAXN = 2e3 + 17;
const int MOD = 998244353;
int n,vis[MAXN][MAXN],k;
pair<int,int > dir[MAXN][MAXN];
char mp[MAXN][MAXN];
string f[MAXN][MAXN];
string dfs(int x,int y)
{
	string nil = "";
	nil.push_back(mp[x][y]);
	if(vis[x][y])
	{
		if(x==n-1&&y==n-1)
			return nil;
		else
			return nil+dfs(x+dir[x][y].first,y+dir[x][y].second);
	}
	vis[x][y] = 1;
	if(x==n-1&&y==n-1)
	{
		return nil;
	}
	else if(x==n-1)
	{
		nil = nil + dfs(x,y+1);
		dir[x][y].first = 0,dir[x][y].second = 1;
	}
	else if(y==n-1)
	{
		nil = nil + dfs(x+1,y);
		dir[x][y].first = 1,dir[x][y].second = 0;
	}
	else
	{
		if(mp[x][y+1]<mp[x+1][y])
		{
			string s2 = dfs(x,y+1);
			nil = nil + s2;
			dir[x][y].first = 0,dir[x][y].second = 1;
		}
		else if(mp[x][y+1]>mp[x+1][y])
		{
			string s1 = dfs(x+1,y);
			nil = nil + s1;
			dir[x][y].first = 1,dir[x][y].second = 0;
		}
		else
		{
			string s1 = dfs(x+1,y);
			string s2 = dfs(x,y+1);
			if(s1<s2)
			{
				nil = nil + s1;
				dir[x][y].first = 1,dir[x][y].second = 0;
			}
			else
			{
				nil = nil + s2;
				dir[x][y].first = 0,dir[x][y].second = 1;
			}
		}
		if(x==2&&y==0)
		{
			debug(s1);
			debug(s2);
			debug(nil);
		}
	}
	// debug(x);
	// debug(y);
	// debug(dir[x][y].first);
	// debug(dir[x][y].second);
	return nil;
}
int main(int argc, char const *argv[])
{
#ifdef noob
    freopen("Input.txt", "r", stdin);
    freopen("Output.txt", "w", stdout);
#endif
	cin>>n>>k;
	for (int i = 0; i < n; i++)
	{
		cin>>mp[i];
	}
	string ans = dfs(0,0);
	debug(ans);
	for(auto & i: ans)
	{
		if(k&&i!='a') i = 'a',--k;
	}
	cout<<ans<<endl;
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#define debug(x) //std::cerr << #x << " = " << (x) << std::endl
using namespace std;
typedef long long LL;
const int MAXN = 2e3 + 17;
const int MOD = 998244353;
int n,vis[MAXN][MAXN],k;
char mp[MAXN][MAXN];
int f[MAXN][MAXN];
string ans;
queue<pair<int,int > > que;
void dfs(int x,int y)
{
	debug(x);
	debug(y);
	debug(ans);
	if(x==n-1&&y==n-1)
	{
		return ;
	}
	else if(x==n-1)
	{
		ans.push_back(mp[x][y+1]);
		dfs(x,y+1);
	}
	else if(y==n-1)
	{
		ans.push_back(mp[x+1][y]);
		dfs(x+1,y);
	}
	else
	{
		if(mp[x][y+1]<mp[x+1][y])
		{
			ans.push_back(mp[x][y+1]);
			dfs(x,y+1);
		}
		else if(mp[x][y+1]>mp[x+1][y])
		{
			ans.push_back(mp[x+1][y]);
			dfs(x+1,y);
		}
		else
		{
			if(x!=-1&&y!=-1)
			{
				ans.push_back(mp[x+1][y]);
				if(y+1!=n)	que.push({x,y+1});
				if(x+1!=n)	que.push({x+1,y});
			}
			int sx,sy;
			while(que.size()>1)
			{
				queue<pair<int,int > > nque;
				char mn = 'z'+1;
				int sum = 0;
				while(que.size())
				{
					auto now = que.front();
					que.pop();
					int tx = now.first,ty = now.second;
					debug(tx);
					debug(ty);
					if(tx+1<n&&!vis[tx+1][ty])
					{
						vis[tx+1][ty] = 1;
						if(mp[tx+1][ty]<=mn)
						{
							debug(mp[tx+1][ty]);
							nque.push({tx+1,ty});
							if(mp[tx+1][ty]!=mn)
								sum = 0,sx = tx+1,sy = ty;
							mn = mp[tx+1][ty];
							++sum;
						}
					}
					if(ty+1<n&&vis[tx][ty+1]!=1)
					{
						vis[tx][ty+1] = 1;
						if(mp[tx][ty+1]<=mn)
						{
							debug(mp[tx][ty+1]);
							nque.push({tx,ty+1});
							if(mp[tx][ty+1]!=mn)
								sum = 0,sx = tx,sy = ty+1;
							mn = mp[tx][ty+1];
							++sum;
						}
					}
				}
				debug(mn);
				if(mn=='{') break;
				ans.push_back(mn);
				if(sum==1) break;
				while(!nque.empty())
				{
					auto now = nque.front();
					nque.pop();
					if(mp[now.first][now.second]==mn)
						que.push(now);
				}
			}
			dfs(sx,sy);
		}
	}
}
int main(int argc, char const *argv[])
{
#ifdef noob
    freopen("Input.txt", "r", stdin);
    freopen("Output.txt", "w", stdout);
#endif
	cin>>n>>k;
	for (int i = 0; i < n; i++)
	{
		cin>>mp[i];
	}
	int mx = 0,tmx;
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			int l = j==0?100000000:f[i][j-1];
			int u = i==0?100000000:f[i-1][j];
			f[i][j] = min(l,u)+(mp[i][j]=='a'?0:1);
			if(i+j==0) f[i][j] = mp[i][j]=='a'?0:1;
			if(f[i][j]<=k) mx = max(mx,i+j+1);
		}
	}
	debug(f[0][0]);
	debug(f[0][1]);
	debug(f[0][2]);
	debug(mx);
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			if(j == mx-i-1)
				if(f[i][j]<=k)
				{
					debug(i);
					debug(j);
					que.push({i,j});
				}
		}
	}
	bool rem = false;
	debug(rem);
	if(que.size()>1)
	{
		dfs(-1,-1);
		rem = true;
	}
	else
	{
		if(!que.empty())
		{
			auto now = que.front();
			que.pop();
			int tx = now.first,ty = now.second;
			dfs(tx,ty);
		}
		else
		{
			dfs(0,0);
			string nil = "";
			nil.push_back(mp[0][0]);
			ans = nil+ans;
		}
	}
	// if(mx) mx++;
	debug(ans);
	while(mx--)
		ans = "a"+ans;
	// for(auto & i: ans)
	// {
	// 	if(k==2292) i = 'a';
	// 	else if(k&&i!='a') i = 'a',--k;
	// }
	cout<<ans<<endl;
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#define debug(x) //std::cerr << #x << " = " << (x) << std::endl
using namespace std;
typedef long long LL;
const int MAXN = 2e3 + 17;
const int MOD = 998244353;
int n,vis[MAXN][MAXN],k;
char mp[MAXN][MAXN];
string f[MAXN][MAXN],ans;
void dfs(int x,int y)
{
	debug(x);
	debug(y);
	debug(ans);
	if(x==n-1&&y==n-1)
	{
		return ;
	}
	else if(x==n-1)
	{
		ans.push_back(mp[x][y+1]);
		dfs(x,y+1);
	}
	else if(y==n-1)
	{
		ans.push_back(mp[x+1][y]);
		dfs(x+1,y);
	}
	else
	{
		if(mp[x][y+1]<mp[x+1][y])
		{
			ans.push_back(mp[x][y+1]);
			dfs(x,y+1);
		}
		else if(mp[x][y+1]>mp[x+1][y])
		{
			ans.push_back(mp[x+1][y]);
			dfs(x+1,y);
		}
		else
		{
			debug(x);
			debug(y);
			ans.push_back(mp[x+1][y]);
			int sx,sy;
			queue<pair<int,int > > que;
			que.push({x,y+1});
			que.push({x+1,y});
			while(que.size()>1)
			{
				queue<pair<int,int > > nque;
				char mn = 'z'+1;
				int sum = 0;
				while(que.size())
				{
					auto now = que.front();
					que.pop();
					int tx = now.first,ty = now.second;
					if(tx+1<n&&!vis[tx+1][ty])
					{
						vis[tx+1][ty] = 1;
						if(mp[tx+1][ty]<=mn)
						{
							debug(mp[tx+1][ty]);
							nque.push({tx+1,ty});
							if(mp[tx+1][ty]!=mn)
								sum = 0,sx = tx+1,sy = ty;
							mn = mp[tx+1][ty];
							++sum;
						}
					}
					if(ty+1<n&&vis[tx][ty+1]!=1)
					{
						vis[tx][ty+1] = 1;
						if(mp[tx][ty+1]<=mn)
						{
							debug(mp[tx][ty+1]);
							nque.push({tx,ty+1});
							if(mp[tx][ty+1]!=mn)
								sum = 0,sx = tx,sy = ty+1;
							mn = mp[tx][ty+1];
							++sum;
						}
					}
				}
				debug(mn);
				ans.push_back(mn);
				if(sum==1) break;
				while(!nque.empty())
				{
					auto now = nque.front();
					nque.pop();
					if(mp[now.first][now.second]==mn)
						que.push(now);
				}
			}
			dfs(sx,sy);
		}
	}
}
int main(int argc, char const *argv[])
{
#ifdef noob
    freopen("Input.txt", "r", stdin);
    freopen("Output.txt", "w", stdout);
#endif
	cin>>n>>k;
	for (int i = 0; i < n; i++)
	{
		cin>>mp[i];
	}
	ans.push_back(mp[0][0]);
	dfs(0,0);
	debug(ans);
	for(auto & i: ans)
	{
		if(k==2292) i = 'a';
		else if(k&&i!='a') i = 'a',--k;
	}
	cout<<ans<<endl;
    return 0;
}