import java.util.*;

public class ShaassandOskols {

	public static void main (String[] args){

		Scanner f = new Scanner(System.in);
		int n = Integer.parseInt(f.next());
		int[] answer = new int[n];

		for (int i = 0; i < n; i++){
			answer[i] = Integer.parseInt(f.next());
		}
		int m = Integer.parseInt(f.next());

		for (int i = 0; i < m; i++){
			int x = Integer.parseInt(f.next());
			int y = Integer.parseInt(f.next());
			if (n == 1){
				answer[0] = 0;
				break;
			}
			if (x == 1){
				answer[x] += answer[x - 1] - y;
				answer[x - 1] = 0;
			}else if (x == n){
				answer[x - 2] += y - 1;
				answer[x - 1] = 0;
			}else{
				answer[x] += answer[x - 1] - y;
				answer[x - 2] += y - 1;
				answer[x - 1] = 0;
			}
		}

		for (int i = 0; i < n; i++){
			System.out.println(answer[i]);
		}
	}
}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class Solution {
   BufferedReader in;
   StringTokenizer str;
   PrintWriter out;
   String SK;

   String next() throws IOException {
      while ((str == null) || (!str.hasMoreTokens())) {
      SK = in.readLine();
      if (SK == null)
      return null;
      str = new StringTokenizer(SK);
      }
      return str.nextToken();
   }
   int nextInt() throws IOException {
      return Integer.parseInt(next());
   }
   double nextDouble() throws IOException {
      return Double.parseDouble(next());
   }
   long nextLong() throws IOException {
      return Long.parseLong(next());
   }
   char[] charArray() throws IOException{
      return next().toCharArray();
   }
   public static void main(String[] args) throws IOException {
      new Solution().run();
   }
   void run() throws IOException {
      in = new BufferedReader(new InputStreamReader(System.in));
      out = new PrintWriter(System.out);
      //in = new BufferedReader(new FileReader("input.txt"));
      //out = new PrintWriter("output.txt");
      solve();
      out.close();
   }
   void solve() throws IOException {
     int n=nextInt();
     int a[]=new int[n+5];
      for (int i = 1; i <= n; i++) {
         a[i]=nextInt();
      }
     int m=nextInt();
     for(int i=0;i<m;i++){
        int x=nextInt();
        int y=nextInt();
        if(x==1){
           a[x+1]+=a[x]-y;
           a[x]=0;
        }
        else if(x == n){
           a[x-1]+=y-1;
           a[x]=0;
        }
        else{
          a[x-1]+=y-1;
          a[x+1]+=a[x]-y;
          a[x]=0;
        }

     }
     for(int i=1;i<=n;i++){
           out.println(a[i]);
     }
   }

}


import java.io.IOException;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.util.Vector;

public class CmdProgram {
    protected StringTokenizer tokenizer;
    protected PrintWriter outputWriter;
    protected BufferedReader inputReader;

    public CmdProgram(){
        this.inputReader = new BufferedReader(new InputStreamReader(System.in));
        this.outputWriter = new PrintWriter(System.out);
    }

    public String nextInput(){
        return this.tokenizer.nextToken();
    }

    public int nextInt(){
        return Integer.parseInt(nextInput());
    }

    public long nextLong(){
        return Long.parseLong(nextInput());
    }

    public void nextLine() throws IOException{
    	this.tokenizer = new StringTokenizer(this.inputReader.readLine());
    }

    public static void main(String[] args) throws IOException{
		Oskols osk = new Oskols();
		osk.init();
		osk.nextLine();
		int round = osk.nextInt();
		for(int i=0; i<round; i++){
			osk.kill();
		}
		for(int i=0; i<osk.wires.size(); i++){
			osk.outputWriter.write(osk.wires.get(i).toString());
			osk.outputWriter.write("\n");
		}
		osk.inputReader.close();
		osk.outputWriter.close();
	}
}

class Oskols extends CmdProgram{

	public Vector<Integer> wires = new Vector();

	public void init() throws IOException{
		this.nextLine();
		int num = this.nextInt();
		this.nextLine();
		for(int i=0; i<num; i++){
			wires.add(i, this.nextInt());
		}
	}

	public void kill() throws IOException{
		this.nextLine();
		int index = this.nextInt();
		int nth = this.nextInt();
		if(index == wires.size()){
			int oriNum = (int) wires.get(wires.size()-1);
			wires.set(wires.size(), 0);
			wires.set(wires.size()-1, oriNum+nth-1);
		}else if(index == 1){
			int oriNum1= (int) wires.get(1);
			int oriNum = (int) wires.get(0);
			wires.set(0, 0);
			wires.set(1, oriNum1 + oriNum - nth);
		}else{
			int oriNum1 = (int) wires.get(index);
			int oriNum2 = (int) wires.get(index - 2);
			int oriNum = (int) wires.get(index - 1);
			wires.set(index - 1, 0);
			wires.set(index, oriNum1 + oriNum - nth);
			wires.set(index - 2, oriNum2 + nth - 1);
		}
	}
}


import java.io.IOException;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.util.Vector;

public class CmdProgram {
    protected StringTokenizer tokenizer;
    protected PrintWriter outputWriter;
    protected BufferedReader inputReader;

    public CmdProgram(){
        this.inputReader = new BufferedReader(new InputStreamReader(System.in));
        this.outputWriter = new PrintWriter(System.out);
    }

    public String nextInput(){
        return this.tokenizer.nextToken();
    }

    public int nextInt(){
        return Integer.parseInt(nextInput());
    }

    public long nextLong(){
        return Long.parseLong(nextInput());
    }

    public void nextLine() throws IOException{
    	this.tokenizer = new StringTokenizer(this.inputReader.readLine());
    }

    public static void main(String[] args) throws IOException{
		Oskols osk = new Oskols();
		osk.init();
		osk.nextLine();
		int round = osk.nextInt();
		for(int i=0; i<round; i++){
			osk.kill();
		}
		for(int i=0; i<osk.wires.size(); i++){
			osk.outputWriter.write(osk.wires.get(i).toString());
			osk.outputWriter.write("\n");
		}
		osk.inputReader.close();
		osk.outputWriter.close();
	}
}

class Oskols extends CmdProgram{

	public Vector<Integer> wires = new Vector();

	public void init() throws IOException{
		this.nextLine();
		int num = this.nextInt();
		this.nextLine();
		for(int i=0; i<num; i++){
			wires.add(i, this.nextInt());
		}
	}

	public void kill() throws IOException{
		this.nextLine();
		int index = this.nextInt();
		int nth = this.nextInt();
		if(1 == wires.size()){
			wires.set(0, 0);
		}else if(index == wires.size()){
			int oriNum = (int) wires.get(wires.size()-2);
			wires.set(wires.size()-1, 0);
			wires.set(wires.size()-2, oriNum+nth-1);
		}else if(index == 1){
			int oriNum1= (int) wires.get(1);
			int oriNum = (int) wires.get(0);
			wires.set(0, 0);
			wires.set(1, oriNum1 + oriNum - nth);
		}else{
			int oriNum1 = (int) wires.get(index);
			int oriNum2 = (int) wires.get(index - 2);
			int oriNum = (int) wires.get(index - 1);
			wires.set(index - 1, 0);
			wires.set(index, oriNum1 + oriNum - nth);
			wires.set(index - 2, oriNum2 + nth - 1);
		}
	}
}


import java.io.IOException;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.util.Vector;

public class CmdProgram {
    protected StringTokenizer tokenizer;
    protected PrintWriter outputWriter;
    protected BufferedReader inputReader;

    public CmdProgram(){
        this.inputReader = new BufferedReader(new InputStreamReader(System.in));
        this.outputWriter = new PrintWriter(System.out);
    }

    public String nextInput(){
        return this.tokenizer.nextToken();
    }

    public int nextInt(){
        return Integer.parseInt(nextInput());
    }

    public long nextLong(){
        return Long.parseLong(nextInput());
    }

    public void nextLine() throws IOException{
    	this.tokenizer = new StringTokenizer(this.inputReader.readLine());
    }

    public static void main(String[] args) throws IOException{
		Oskols osk = new Oskols();
		osk.init();
		osk.nextLine();
		int round = osk.nextInt();
		for(int i=0; i<round; i++){
			osk.kill();
		}
		for(int i=0; i<osk.wires.size(); i++){
			osk.outputWriter.write(osk.wires.get(i).toString());
			osk.outputWriter.write("\n");
		}
		osk.inputReader.close();
		osk.outputWriter.close();
	}
}

class Oskols extends CmdProgram{

	public Vector<Integer> wires = new Vector();

	public void init() throws IOException{
		this.nextLine();
		int num = this.nextInt();
		this.nextLine();
		for(int i=0; i<num; i++){
			wires.add(i, this.nextInt());
		}
	}

	public void kill() throws IOException{
		this.nextLine();
		int index = this.nextInt();
		int nth = this.nextInt();
		if(1 == wires.size()){
			wires.set(0, 0);
		}else if(index == wires.size()){
			int oriNum = (int) wires.get(wires.size()-1);
			wires.set(wires.size()-1, 0);
			wires.set(wires.size()-2, oriNum+nth-1);
		}else if(index == 1){
			int oriNum1= (int) wires.get(1);
			int oriNum = (int) wires.get(0);
			wires.set(0, 0);
			wires.set(1, oriNum1 + oriNum - nth);
		}else{
			int oriNum1 = (int) wires.get(index);
			int oriNum2 = (int) wires.get(index - 2);
			int oriNum = (int) wires.get(index - 1);
			wires.set(index - 1, 0);
			wires.set(index, oriNum1 + oriNum - nth);
			wires.set(index - 2, oriNum2 + nth - 1);
		}
	}
}


import java.io.IOException;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.util.Vector;

public class CmdProgram {
    protected StringTokenizer tokenizer;
    protected PrintWriter outputWriter;
    protected BufferedReader inputReader;

    public CmdProgram(){
        this.inputReader = new BufferedReader(new InputStreamReader(System.in));
        this.outputWriter = new PrintWriter(System.out);
    }

    public String nextInput(){
        return this.tokenizer.nextToken();
    }

    public int nextInt(){
        return Integer.parseInt(nextInput());
    }

    public long nextLong(){
        return Long.parseLong(nextInput());
    }

    public void nextLine() throws IOException{
    	this.tokenizer = new StringTokenizer(this.inputReader.readLine());
    }

    public static void main(String[] args) throws IOException{
		Oskols osk = new Oskols();
		osk.init();
		osk.nextLine();
		int round = osk.nextInt();
		for(int i=0; i<round; i++){
			osk.kill();
		}
		for(int i=0; i<osk.wires.size(); i++){
			osk.outputWriter.write(osk.wires.get(i).toString());
			osk.outputWriter.write("\n");
		}
		osk.inputReader.close();
		osk.outputWriter.close();
	}
}

class Oskols extends CmdProgram{

	public Vector<Integer> wires = new Vector();

	public void init() throws IOException{
		this.nextLine();
		int num = this.nextInt();
		this.nextLine();
		for(int i=0; i<num; i++){
			wires.add(i, this.nextInt());
		}
	}

	public void kill() throws IOException{
		this.nextLine();
		int index = this.nextInt();
		int nth = this.nextInt();
		if(1 == wires.size()){
			wires.set(0, 0);
		}else if(index == wires.size()){
			int oriNum = (int) wires.get(wires.size()-1);
			wires.set(wires.size(), 0);
			wires.set(wires.size()-1, oriNum+nth-1);
		}else if(index == 1){
			int oriNum1= (int) wires.get(1);
			int oriNum = (int) wires.get(0);
			wires.set(0, 0);
			wires.set(1, oriNum1 + oriNum - nth);
		}else{
			int oriNum1 = (int) wires.get(index);
			int oriNum2 = (int) wires.get(index - 2);
			int oriNum = (int) wires.get(index - 1);
			wires.set(index - 1, 0);
			wires.set(index, oriNum1 + oriNum - nth);
			wires.set(index - 2, oriNum2 + nth - 1);
		}
	}
}


import java.io.*;
import java.util.*;

public class ShaassAndOskols {
	public static void main(String[] args) throws IOException {
		BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
		int n = Integer.parseInt(f.readLine());
		int[] a = new int[n+2];
		StringTokenizer st = new StringTokenizer(f.readLine());
		for (int i = 1; i <= n; i++)
			a[i] = Integer.parseInt(st.nextToken());
		int m = Integer.parseInt(f.readLine());
		for (int i = 0; i < m; i++)
		{
			st = new StringTokenizer(f.readLine());
			int x = Integer.parseInt(st.nextToken());
			int y = Integer.parseInt(st.nextToken());
			a[x-1] += y-1;
			a[x+1] += a[x]-y;
			a[x] = 0;
		}
		for (int i = 1; i <= n; i++)
			System.out.println(a[i]+" ");
	}
}


import java.util.Scanner;

public class Aaa {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int [] a = new int[n];
        for (int i=0;i<n;i++) {
            a[i] = scanner.nextInt();
        }

        int m = scanner.nextInt();
        for (int i=0;i<m;i++) {
            int x = scanner.nextInt();
            int y = scanner.nextInt();
            x--;
            int size = a[x];
            if (x > 0) {
              //  a[x+1] += size - y;
                a[x-1] += y - 1;
               // a[x] -= 0;
            }

            if (x < n - 1) {
                a[x+1] += size - y;
            }
            a[x] = 0;
        }
        for (int i=0;i<n;i++) System.out.println(a[i]);
    }
}


import java.io.InputStreamReader;
import java.util.Scanner;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author pttrung
 */
public class A {

    public static void main(String[] args) {
        Scanner in = new Scanner(new InputStreamReader(System.in));
        int n = in.nextInt();
        int [] data = new int[n];
        for(int i = 0; i < n ; i++){
            data[i] = in.nextInt();
        }
        int m = in.nextInt();
        for(int i = 0; i < m ; i++){
            int x = in.nextInt() - 1;
            int y = in.nextInt();
            int val = data[x];
            data[x]= 0;
            if(x > 0){
                data[x - 1] += y - 1;
            }
            if(x + 1 < n){
                data[x + 1] += val -y;
            }
        }
        for(int i = 0; i < n ; i++){
            System.out.println(data[i]);
        }

    }
}


import java.util.Scanner;

public class ShaassandOskols
{
	public static void main(String[] args)
	{
		Scanner input = new Scanner(System.in);
		int n = input.nextInt();
		int[] a = new int[n];
		for (int i = 0; i < n; ++i)
		{
			a[i] = input.nextInt();
		}
		int m = input.nextInt();
		int x, y;
		for (int i = 0; i < m; ++i)
		{
			x = input.nextInt();
			y = input.nextInt();
			if (x != 1 && x != n)
			{
				a[x - 2] += y - 1;
				a[x] += a[x - 1] - y;
			}
			else if (x == 1 && x == n)
			{
				a[0] = 0;
			}
			else if (x == 1)
			{
				a[1] += a[0] - y;
			}
			else if (x == n)
			{
				a[n - 2] += y - 1;
			}
			a[x - 1] = 0;
		}
		for (int i = 0; i < n; ++i)
		{
			System.out.println(a[i]);
		}
	}
}


import java.util.*;
public class A294 {
    public static void main(String[] args){
        Scanner br = new Scanner(System.in);
        int n = br.nextInt();
        int[] ams = new int[n];
        for(int i = 0;i<n;i++){
            ams[i] = br.nextInt();
        }
        int k = br.nextInt();
        for(int i = 0;i<k;i++){
            int wire = br.nextInt()-1;
            int pos = br.nextInt();
            if(wire > 0)
                ams[wire-1]+=(pos-1);
            if(wire < n-1)
                ams[wire+1]+=(ams[wire]-pos);
            ams[wire] = 0;
        }
        for(int i = 0;i<n;i++){
            System.out.println(ams[i]);
        }
    }
}


import java.util.Scanner;

public class Draw
{

    public static void main (String[] args) throws java.lang.Exception
    {
        Scanner myScanner = new Scanner(System.in);

        int n = myScanner.nextInt();
        int[] wire = new int[n+1];

        myScanner.nextLine();

        for(int i = 1;i<n+1;i++){
            wire[i] = myScanner.nextInt();
        }

        myScanner.nextLine();

        int shots = myScanner.nextInt();

        myScanner.nextLine();

        for(int i = 0; i<shots;i++){
            int w = myScanner.nextInt();
            int bird = myScanner.nextInt();

            if(w > 1) wire[w-1] += bird - 1;
            if(w < n) wire[w+1] += wire[w] - bird;

            wire[w] = 0;

            myScanner.nextLine();
        }

        for(int i =1; i<n+1;i++){
            System.out.println(wire[i]);
        }

        myScanner.close();
    }
}


import java.util.Scanner;

public class A_294_Shaass_and_Oskols {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int a[] = new int[n + 2];
		for (int i = 1; i <= n; ++i) {
			a[i] = sc.nextInt();
		}
		int m = sc.nextInt();
		for (int j = 0; j < m; ++j) {
			int x = sc.nextInt();
			int y = sc.nextInt();
			a[x - 1] += (y - 1);
			a[x + 1] += (a[x] - y);
			a[x] = 0;
		}
		for (int i = 1; i <= n; ++i) {
			System.out.println(a[i]);
		}
	}
}


import java.awt.Point;
import java.io.*;
import java.math.BigInteger;
import java.util.*;
import static java.lang.Math.*;

public class Solution implements Runnable {

    BufferedReader in;
    PrintWriter out;
    StringTokenizer tok = new StringTokenizer("");

    public static void main(String[] args) {
        new Thread(null, new Solution(), "", 256 * (1L << 20)).start();
    }

    public void run() {
        try {
            long t1 = System.currentTimeMillis();
            if (System.getProperty("ONLINE_JUDGE") != null) {
                in = new BufferedReader(new InputStreamReader(System.in));
                out = new PrintWriter(System.out);
            } else {
                in = new BufferedReader(new FileReader("src/input.txt"));
                out = new PrintWriter("src/output.txt");
            }
            Locale.setDefault(Locale.US);
            solve();
            in.close();
            out.close();
            long t2 = System.currentTimeMillis();
            System.err.println("Time = " + (t2 - t1));
        } catch (Throwable t) {
            t.printStackTrace(System.err);
            System.exit(-1);
        }
    }

    String readString() throws IOException {
        while (!tok.hasMoreTokens()) {
            tok = new StringTokenizer(in.readLine());
        }
        return tok.nextToken();
    }

    int readInt() throws IOException {
        return Integer.parseInt(readString());
    }

    long readLong() throws IOException {
        return Long.parseLong(readString());
    }

    double readDouble() throws IOException {
        return Double.parseDouble(readString());
    }

    // solution

    void solve() throws IOException {
        int n = readInt();
        int[] a = new int[n + 1];
        for (int i = 1; i <= n; i++) {
            a[i] = readInt();
        }

        int m = readInt();
        for (int i = 0; i < m; i++) {
            int x = readInt();
            int y = readInt();

            if (x > 1) {
                a[x - 1] += (y - 1);
            }
            if (x < n) {
                a[x + 1] += a[x] - y;
            }
            a[x] = 0;
        }

        for (int i = 1; i <= n; i++) {
            out.println(a[i]);
        }
    }
}


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.Integer;
import java.io.IOException;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        int i, x, y, n, m, z;
        String[] sta;
        int[] wire = null;
        String line = null;
        while((line= reader.readLine()) != null) {
            n = Integer.parseInt(line);
            i = 0;
            wire = new int[n];
            StringTokenizer st = new StringTokenizer(reader.readLine());
            while (st.hasMoreTokens()) {
                wire[i++] = Integer.parseInt(st.nextToken());
            }
            m = Integer.parseInt(reader.readLine());
            while(m-- != 0) {
                sta = reader.readLine().split("\\s+");
                x = Integer.parseInt(sta[0]) - 1;
                y = Integer.parseInt(sta[1]);
                if (x-1 >= 0) {
                    wire[x-1] += y-1;
                }
                if (x+1 < n) {
                    wire[x+1] += wire[x] - y;
                }
                wire[x] = 0;
            }
            z = 0;
            while(z < n) {
                System.out.println(wire[z++]);
            }
        }

    }
}


import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Scanner;

public class ProblemA {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);

		int n = in.nextInt();
		int[] a = new int[n];
		for (int i = 0 ; i < n ; i++) {
			a[i] = in.nextInt();
		}

		int m = in.nextInt();
		for (int i = 0 ; i < m ; i++) {
			int w = in.nextInt() - 1;
			int p = in.nextInt();

			int left = p - 1;
			int right = a[w] - p;
			if (w >= 1) {
				a[w-1] += left;
			}
			if (w < n - 1) {
				a[w+1] += right;
			}
			a[w] = 0;
		}

		for (int i = 0 ; i < n ; i++) {
			out.println(a[i]);
		}
		out.flush();
	}

	public static void debug(Object... o) {
		System.err.println(Arrays.deepToString(o));
	}
}


import java.util.Scanner;

public class Round178A {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] a = new int[n+1];

        for(int i=0; i<n; i++) {
            a[i+1] = sc.nextInt();
        }
        int m = sc.nextInt();

        for(int i=0; i<m; i++) {
            int x = sc.nextInt();
            int y = sc.nextInt();

            if (x > 1) {
                a[x - 1] += y - 1;
            }
            if (x < n) {
                a[x + 1] += a[x] - y;
            }

            a[x] = 0;
        }

        for(int i=1; i<=n; i++) {
            System.out.println(a[i]);
        }
    }
}


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;

import java.util.StringTokenizer;

public class Problem1 {

    public Integer[] count(){
        int n = 0, m = 0;
        Integer[] a = new Integer[0];
        String[] shotBirds;
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//                  (new FileReader("C://temp//test.txt"));
//                  new InputStreamReader(System.in));
            n = Integer.parseInt(br.readLine());
            a = new Integer[n+1];
            String ai = br.readLine();
            StringTokenizer tokenizer = new StringTokenizer(ai);
            for (int i =1; i<=n; i++){
                a[i] = (Integer.parseInt(tokenizer.nextToken()));
            }
            m = Integer.parseInt(br.readLine());
            shotBirds = new String[m+1];
            for (int i =1; i<=m; i++){
                String birdsLines = br.readLine();
                tokenizer = new StringTokenizer(birdsLines);
                shotBirds[i] = birdsLines;
            }

            for (int i =1; i<= m; i++){
                StringTokenizer tokenizer2 = new StringTokenizer(shotBirds[i]);

                int lineShot = Integer.parseInt(tokenizer2.nextToken());// this is the line of the ith shot
                int birdShot = Integer.parseInt(tokenizer2.nextToken());

                int left = Math.min(a[lineShot], birdShot - 1);
                int right = Math.max(0,a[lineShot] -birdShot);
                a[lineShot] = 0;
                if (lineShot>1) a[lineShot-1] += left;
                if (lineShot<n) a[lineShot+1] += right;

            }
            br.close();
        } catch (IOException ioe){
            ioe.printStackTrace();
        }

        return a;
    }

    public static void main(String[] args) {
        Problem1 problem1 = new Problem1();
        Integer[] output = problem1.count();
        for (int i=1;i<output.length; i++){
            System.out.println(output[i]);
        }
    }

}


import java.util.Scanner;

public class Main {
  public static void main(String[] args) {
    Scanner s = new Scanner(System.in);
    int n = s.nextInt();
    int[] nBirds = new int[n];
    for (int j = 0; j < n; j++) nBirds[j] = s.nextInt();
    int tests = s.nextInt();
    for (int k = 0; k < tests; ++k) {
      int x = s.nextInt();
      int y = s.nextInt();
      if (x > 1) { nBirds[x-2] += y - 1; }
      if (x < n) { nBirds[x] += nBirds[x-1] - y; }
      nBirds[x-1] = 0;
    }
    for (int j = 0; j < n; j++) System.out.println(nBirds[j]);
  }
}


import java.util.Scanner;

public class Main {
  public static void main(String[] args) {
    Scanner s = new Scanner(System.in);
    int n = s.nextInt();
    int[] nBirds = new int[n];
    for (int j = 0; j < n; j++) nBirds[j] = s.nextInt();
    int tests = s.nextInt();
    for (int k = 0; k < tests; ++k) {
      int x = s.nextInt();
      int y = s.nextInt();
      if (x > 1) { nBirds[x-2] += nBirds[x-1] - y; }
      if (x < n) { nBirds[x] += y - 1; }
      nBirds[x-1] = 0;
    }
    for (int j = 0; j < n; j++) System.out.println(nBirds[j]);
  }
}


import java.util.Scanner;

public class Main
{
    public static void main (String[] args) throws java.lang.Exception
    {
        Scanner scanner = new Scanner(System.in);
        int nb = scanner.nextInt();
        int[] birds = new int[nb];
        for(int i = 0 ; i <nb ; i++)  {
            birds[i] = scanner.nextInt();
        }
        int m = scanner.nextInt();
        int x = 0, y = 0, nbBirdsLeft = 0, nbBirdsRight = 0;
        for(int j = 0 ; j < m ; j++) {
            x = scanner.nextInt()-1;
            y = scanner.nextInt();
            nbBirdsLeft = y -1;
            nbBirdsRight = birds[x] - y;
            if(x > 0) {
                birds[x-1]+=nbBirdsLeft;
            }
            if(x < (nb-1)) {
                birds[x+1]+=nbBirdsRight;
            }
            birds[x] = 0;
        }
        for(int i = 0 ; i <nb ; i++)  {
            System.out.println(birds[i]);
        }
    }
}


import java.util.Scanner;

public class Main
{
    public static void main (String[] args) throws java.lang.Exception
    {
        Scanner scanner = new Scanner(System.in);
        int nb = scanner.nextInt();
        int[] birds = new int[nb];
        for(int i = 0 ; i <nb ; i++)  {
            birds[i] = scanner.nextInt();
        }
        int m = scanner.nextInt();
        int x = 0, y = 0, nbBirdsLeft = 0, nbBirdsRight = 0;
        for(int j = 0 ; j < m ; j++) {
            x = scanner.nextInt()-1;
            y = scanner.nextInt();
            nbBirdsLeft = y -1;
            nbBirdsRight = birds[x] - y;
            if(x > 0) {
                birds[x-1]+=nbBirdsLeft;
            }
            if(x < (nb-2)) {
                birds[x+1]+=nbBirdsRight;
            }
            birds[x] = 0;
        }
        for(int i = 0 ; i <nb ; i++)  {
            System.out.println(birds[i]);
        }
    }
}


import java.util.*;
import java.io.*;

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        int[] wires = new int[n + 2];
        for(int i = 1; i <= n; i++) {
            wires[i] = scan.nextInt();
        }
        int m = scan.nextInt();
        for(int i = 0; i < m; i++) {
            int wn = scan.nextInt();
            int bn = scan.nextInt();
            int tot = wires[wn];
            int x = bn - 1;
            int y = tot - x - 1;
            wires[wn - 1] += x;
            wires[wn] = 0;
            wires[wn + 1] += y;
        }
        for(int i = 1; i <= n; i++) System.out.println(wires[i]);
    }
}


import java.io.*;
import java.util.*;

public class Main {
	boolean eof;

	public String nextToken() {
		while (st == null || !st.hasMoreTokens()) {
			try {
				st = new StringTokenizer(br.readLine());
			} catch (Exception e) {
				eof = true;
				return "-1";
			}
		}
		return st.nextToken();
	}

	public int nextInt() {
		return Integer.parseInt(nextToken());
	}

	BufferedReader br;
	StringTokenizer st;
	PrintWriter out;

	public static void main(String[] args) {
		new Main().run();
	}

	void run() {
		try {
			File f;
			try {
				f = new File("input.txt");
				if (f.exists()) {
					br = new BufferedReader(new FileReader("input.txt"));
					out = new PrintWriter(new FileWriter("output.txt"));
				} else {
					br = new BufferedReader(new InputStreamReader(System.in));
					out = new PrintWriter(new OutputStreamWriter(System.out));
				}
			} catch (Throwable e) {
				br = new BufferedReader(new InputStreamReader(System.in));
				out = new PrintWriter(new OutputStreamWriter(System.out));
			}

			solve();
			br.close();
			out.close();
		} catch (Throwable e) {
			e.printStackTrace();
			System.exit(1);
		}
	}

	void solve() {
		int n = nextInt();
		int[] a = new int[n];
		for (int i = 0; i< n; ++i){
			a[i] = nextInt();
		}
		int m = nextInt();
		for (int i = 0; i < m; ++i){
			int x = nextInt() - 1, y = nextInt();
			if (x > 0){
				a[x - 1] += y - 1;
			}
			if (x  + 1 < n){
				a[x + 1] += a[x] - y;
			}
			a[x] = 0;
		}
		for (int i =0; i<n; ++i){
			out.println(a[i]);
		}

	}
}


import java.io.*;
import java.util.*;

public class Main {
	boolean eof;

	public String nextToken() {
		while (st == null || !st.hasMoreTokens()) {
			try {
				st = new StringTokenizer(br.readLine());
			} catch (Exception e) {
				eof = true;
				return "-1";
			}
		}
		return st.nextToken();
	}

	public int nextInt() {
		return Integer.parseInt(nextToken());
	}

	BufferedReader br;
	StringTokenizer st;
	PrintWriter out;

	public static void main(String[] args) {
		new Main().run();
	}

	void run() {
		try {
			File f;
			try {
				f = new File("input.txt");
				if (f.exists()) {
					br = new BufferedReader(new FileReader("input.txt"));
					out = new PrintWriter(new FileWriter("output.txt"));
				} else {
					br = new BufferedReader(new InputStreamReader(System.in));
					out = new PrintWriter(new OutputStreamWriter(System.out));
				}
			} catch (Throwable e) {
				br = new BufferedReader(new InputStreamReader(System.in));
				out = new PrintWriter(new OutputStreamWriter(System.out));
			}

			solve();
			br.close();
			out.close();
		} catch (Throwable e) {
			e.printStackTrace();
			System.exit(1);
		}
	}

	void solve() {
		int n = nextInt();
		int[] a = new int[n];
		for (int i = 0; i< n; ++i){
			a[i] = nextInt();
		}
		int m = nextInt();
		for (int i = 0; i < m; ++i){
			int x = nextInt() - 1, y = nextInt();
			if (x > 0){
				a[x - 1] += y - 1;
			}
			if (x  + 1 < n){
				a[x + 1] += a[x] - y;
			}
			a[x] = 0;
		}
		for (int i =0; i<n; ++i){
			out.println(a[i]);
		}
		out.print(n);
	}
}


import java.util.*;
public class Main {

	public static void main(String[] args){
		Scanner in = new Scanner(System.in);
		int n,wire[],x,y,tmp;
		while(in.hasNext()){
			n = in.nextInt();
			wire = new int[n+2];
			for(int i=1;i<wire.length-1;i++){
				wire[i] = in.nextInt();
			} n = in.nextInt();
			while(n-->0){
				x = in.nextInt();
				y = in.nextInt();
				tmp = wire[x];
				wire[x] = 0;
				wire[x-1] += y-1;
				wire[x+1] += tmp-y;
			}for(int i=1;i<wire.length-1;i++){
				System.out.println(wire[i]);
			}
		}
	}
}


import java.util.Scanner;
import java.io.OutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author chlupnoha (jordan4@seznam.cz)
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        Scanner in = new Scanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskA solver = new TaskA();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskA {
    public void solve(int testNumber, Scanner in, PrintWriter out) {
        int n  = Integer.parseInt(in.nextLine());
        int[] ptaci = new int[n+1];
        String[] s = in.nextLine().split(" ");
        for (int i = 1; i < n+1; i++) {
            ptaci[i] = Integer.parseInt(s[i-1]);
        }
        int m = Integer.parseInt(in.nextLine());
        int[] strely = new int[m+1];
        int[] ptactvo = new int[m+1];
        for (int i = 1; i < m+1; i++) {
            String[] s1 = in.nextLine().split(" ");
            strely[i] = Integer.parseInt(s1[0]);
            ptactvo[i] = Integer.parseInt(s1[1]);
        }

        //simulace

        for (int i = 1; i < m+1; i++) {
            ptaci[strely[i]-1] +=  ptactvo[i]-1;
            ptaci[strely[i]+1] += (ptaci[strely[i]] - (ptactvo[i]));
            ptaci[strely[i]] = 0;
        }

        for (int i = 1; i < n+1; i++) {
            out.println(ptaci[i]);
        }

    }
}


import java.util.Scanner;
import java.io.OutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author chlupnoha (jordan4@seznam.cz)
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        Scanner in = new Scanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskA solver = new TaskA();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskA {
    public void solve(int testNumber, Scanner in, PrintWriter out) {
        int n  = Integer.parseInt(in.nextLine());
        int[] ptaci = new int[n+2];
        String[] s = in.nextLine().split(" ");
        for (int i = 1; i < n+1; i++) {
            ptaci[i] = Integer.parseInt(s[i-1]);
        }
        int m = Integer.parseInt(in.nextLine());
        int[] strely = new int[m+1];
        int[] ptactvo = new int[m+1];
        for (int i = 1; i < m+1; i++) {
            String[] s1 = in.nextLine().split(" ");
            strely[i] = Integer.parseInt(s1[0]);
            ptactvo[i] = Integer.parseInt(s1[1]);
        }

        //simulace

        for (int i = 1; i < m+1; i++) {
            ptaci[strely[i]-1] += ((ptactvo[i])-1);
            ptaci[strely[i]+1] += ptaci[strely[i]] - (ptactvo[i]);
            ptaci[strely[i]] = 0;
        }

        for (int i = 1; i < n+1; i++) {
            out.println(ptaci[i]);
        }

    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Scanner;
import java.util.StringTokenizer;

public class A {

	public static void main(String[] args) throws IOException{
		Scanner sc = new Scanner(System.in);

		final int n = sc.nextInt();

		int[] array = new int[n];
		for(int i = 0; i < n; i++){
			array[i] = sc.nextInt();
		}

		final int m = sc.nextInt();
		for(int i = 0; i < m; i++){
			final int x = sc.nextInt() - 1;
			final int y = sc.nextInt();

			int tmp = array[x];
			array[x] -= y - 1;
			if(x != 0){
				array[x - 1] += y - 1;
			}

			array[x] -= tmp - y + 1;
			if(x != n - 1){
				array[x + 1] += tmp - y;
			}
		}

		for(int i = 0; i < n; i++){
			System.out.println(array[i]);
		}
	}

	public static class Scanner {

		private BufferedReader br;
		private StringTokenizer tok;

		public Scanner(InputStream is) throws IOException{
			br = new BufferedReader(new InputStreamReader(is));
			getLine();
		}

		private void getLine() throws IOException{
			while(tok == null || !tok.hasMoreTokens()){
				tok = new StringTokenizer(br.readLine());
			}
		}

		private boolean hasNext(){
			return tok.hasMoreTokens();
		}

		public int nextInt() throws IOException{
			if(hasNext()){
				return Integer.parseInt(tok.nextToken());
			}else{
				getLine();
				return Integer.parseInt(tok.nextToken());
			}
		}

		public long nextLong() throws IOException{
			if(hasNext()){
				return Long.parseLong(tok.nextToken());
			}else{
				getLine();
				return Long.parseLong(tok.nextToken());
			}
		}

		public double nextDouble() throws IOException{
			if(hasNext()){
				return Double.parseDouble(tok.nextToken());
			}else{
				getLine();
				return Double.parseDouble(tok.nextToken());
			}
		}
	}
}


import java.util.Arrays;
import java.util.Locale;
import java.util.Scanner;
public class Codeforces2 {
    public static void main(String[] args){
    	Scanner sc=new Scanner(System.in);
    	int n=sc.nextInt();
    	int []a=new int[n];
    	for(int i=0;i<n;i++){
    		a[i]=sc.nextInt();
    	}
    	int m=sc.nextInt();int x=0;int y=0;
    	for(int i=0;i<m;i++){
    		x=sc.nextInt()-1;
    		y=sc.nextInt();
    		if(x!=0){
    			a[x-1]+=y-1;
    		}
    		if(n-1-x!=0){
    			a[x+1]+=a[x]-y;
    		}
    		a[x]=0;
    	}
    	for(int i=0;i<n;i++){
    		System.out.println(a[i]);
    	}
    }
}


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

#define rep(i,a,b) for(i=(a);i<=(b);++i)
#define rev(i,a,b) for(i=(a);i>=(b);--i)
#define max2(a,b)  ((a)>(b)?(a):(b))
#define min2(a,b)  ((a)<(b)?(a):(b))
#define all(x) x.begin(),x.end()
#define sz(x) (long long)x.size()
#define fi first
#define se second
#define pb emplace_back // push_back
#define mp make_pair
#define endl '\n'

#ifdef Wild4Stone
template<typename T>
void __p(T a) { cout << a << " "; }
template<typename T, typename F>
void __p(pair<T, F> a) { cout << "{ "; __p(a.fi); __p(a.se); cout << "}"; }
template<typename T>
void __f(const char* s, T t) { cout << s << " : "; __p(t); }
template<typename T>
void __t(const char* s, const T &x) { cout << s << " : { "; for (auto it : x) __p(it); cout << "} ";}
template<typename T, typename ... F>
void __f(const char* s, T t, F ... f) {
	int i = 0; for (;; ++i) if (s[i] == ',') break;
	cout.write(s, i) << " : "; __p(t); cout << " | "; __f(s + i + 1, f...);
}
#define trace(...) { cout<<"LINE: "<<__LINE__<<" || "; __f(#__VA_ARGS__,__VA_ARGS__); cout<<"\n\n"; }
#define autra(...) { cout<<"LINE: "<<__LINE__<<" || "; __t(#__VA_ARGS__,__VA_ARGS__); cout<<"\n\n"; }
#else
#define trace(...) {}
#define autra(...) {}
#endif

typedef long long int ll;
typedef pair<ll, ll> pll;

const ll mod = 1000000007;  //998244353;
const ll inf = 0x3f3f3f3f3f3f3f3fLL;
const double eps = 1e-9;
const double PI = acos(-1);

ll i, j, k;
void solve(void);
inline bool equal(double a, double b) { return fabs(a - b) < eps; }
// inline ll gcd(ll a, ll b) { a=abs(a); b=abs(b); while(a>0 && b>0) (a>b?a%=b:b%=a); return (a==0?b:a); }
// inline ll power(ll x, ll n, ll m = LLONG_MAX)
//        {  ll res=1; x = (x%m + m)%m;
//             while(n) { if(n&1) res=(res*x)%m;  x=(x*x)%m;  n >>= 1; }  return res;
//        }

int main()
{
	ios_base::sync_with_stdio(false); cin.tie(0);
	cout << fixed << setprecision(10);
	int t = 1;
	// cin>>t;
	while (t--)  solve();
	return 0;
}

//***************** Code Starts Here *******************//

bool check(int x, int y, int n)
{
	if (x < 1 || x > n || y < 1 || y > n) return 0;
	return 1;
}
void solve()
{
	ll n, k; cin >> n >> k;
	char c[n + 1][n + 1];
	rep(i, 1, n) rep(j, 1, n) cin >> c[i][j];

	vector<vector<int>> s;
	string ans;

	int x = 1, y = 1, z = k;
	char C = c[x][y];

	// if (C != 'a' && z > 0) C = 'a', z--;
	vector<int> temp = {x, y, z};
	s.pb(temp);
	ans += C;

	while (sz(s))
	{
		vector<vector<int>> t[26];

		while (sz(s))
		{
			vector<int> it = s.back();
			int x = it[0], y = it[1], zz = it[2];
			s.pop_back();

			if (check(x + 1, y, n))
			{
				char C = c[x + 1][y];
				int z = zz;

				// if (C != 'a' && z > 0) C = 'a', z--;

				vector<int> temp = {x + 1, y, z};
				t[C - 'a'].pb(temp);
			}
			if (check(x, y + 1, n))
			{
				char C = c[x][y + 1];
				int z = zz;

				// if (C != 'a' && z > 0) C = 'a', z--;

				vector<int> temp = {x, y + 1, z};
				t[C - 'a'].pb(temp);
			}
		}

		char C;
		rep(i, 0, 25)
		if (sz(t[i]))
		{
			C = 'a' + i;
			ans += C;
			break;
		}

		rep(i, 0, 25)
		if (sz(t[i]))
		{
			for (auto it : t[i])
				s.pb(it);
			break;
		}
	}

	rep(i, 0, sz(ans) - 1)
	if (ans[i] != 'a' && k > 0) ans[i] = 'a', --k;
	cout << ans << endl;
}


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

#define ll  int
#define intmax INT_MAX
#define pi 3.14159265358979323846
//~ #define ff first
//~ #define ss second
#define pb push_back
#define watch(x) cerr<<(#x)<<"  "<<x<<"\n";
const int mod=998244353;
const int MAXN = 2e3+2;
int dp[MAXN][MAXN],vis[MAXN][MAXN];

struct nd{
	int ff,ss,st;
}p;

int main(){
 int n,k; cin>>n>>k;
 string s[n];
 for(int i=0;i<n;i++)cin>>s[i];
 dp[0][0]=(s[0][0]!='a');
 for(int i=1;i<n;i++){
	 dp[i][0]=dp[i-1][0]+(s[i][0]!='a');
	 dp[0][i]=dp[0][i-1]+(s[0][i]!='a');
 }
 for(int i=1;i<n;i++){
	 for(int j=1;j<n;j++) dp[i][j]=min(dp[i-1][j],dp[i][j-1])+(s[i][j]!='a');
 }
  queue<nd> q;
  int maxx=0;
 for(int i=0;i<n;i++){
	 for(int j=0;j<n;j++){
		 if(dp[i][j]==k && i+j>maxx) maxx=i+j;
	 }
 }
 char mc[1<<17];
 for(int i=0;i<n+n+1;i++) mc[i]='z';

 for(int i=0;i<n;i++){
	 for(int j=0;j<n;j++){
		 if(dp[i][j]==k && i+j==maxx) q.push({i,j,i+j}),mc[i+j]='a';
	 }
 }

 for(int i=0;i<maxx;i++) mc[i]='a';

while(!q.empty()){

       p=q.front(); q.pop();
       if(p.st!=maxx && mc[p.st]!=s[p.ff][p.ss]) continue;
	  if(p.ff+1<n && dp[p.ff+1][p.ss] && !vis[p.ff+1][p.ss]){
		  mc[p.st+1]=min(s[p.ff+1][p.ss],mc[p.st+1]);
		 vis[p.ff+1][p.ss]=1;
		 q.push((nd){p.ff+1,p.ss,p.st+1});
	  }
	  if(p.ss+1<n && dp[p.ff][p.ss+1] && !vis[p.ff][p.ss+1]){
		 mc[p.st+1]=min(s[p.ff][p.ss+1],mc[p.st+1]);
		 vis[p.ff][p.ss+1]=1;
		 q.push((nd){p.ff,p.ss+1,p.st+1});
	  }
}

 for(int i=0;i<n+n-1;i++)cout<<mc[i];

	return 0;
}


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

#define ll  int
#define intmax INT_MAX
#define pi 3.14159265358979323846
//~ #define ff first
//~ #define ss second
#define pb push_back
#define watch(x) cerr<<(#x)<<"  "<<x<<"\n";
const int mod=998244353;
const int MAXN = 2e3+2;
int dp[MAXN][MAXN],vis[MAXN][MAXN];

struct nd{
	int ff,ss,st;
}p;

int main(){
 int n,k; cin>>n>>k;
 string s[n];
 for(int i=0;i<n;i++)cin>>s[i];
 dp[0][0]=(s[0][0]!='a');
 for(int i=1;i<n;i++){
	 dp[i][0]=dp[i-1][0]+(s[i][0]!='a');
	 dp[0][i]=dp[0][i-1]+(s[0][i]!='a');
 }
 for(int i=1;i<n;i++){
	 for(int j=1;j<n;j++) dp[i][j]=min(dp[i-1][j],dp[i][j-1])+(s[i][j]!='a');
 }
  queue<nd> q;
  int maxx=0;
 for(int i=0;i<n;i++){
	 for(int j=0;j<n;j++){
		 if(dp[i][j]==k && i+j>maxx) maxx=i+j;
	 }
 }
 char mc[1<<17];
 for(int i=0;i<n+n+1;i++) mc[i]='z';

 for(int i=0;i<n;i++){
	 for(int j=0;j<n;j++){
		 if(dp[i][j]==k && i+j==maxx) q.push({i,j,i+j}),mc[i+j]='a';
	 }
 }
  if(k==0) { mc[0]=s[0][0]; q.push((nd){0,0,0});}
 for(int i=0;i<maxx;i++) mc[i]='a';

while(!q.empty()){

       p=q.front(); q.pop();
       if(p.st!=maxx && mc[p.st]!=s[p.ff][p.ss]) continue;
	  if(p.ff+1<n && dp[p.ff+1][p.ss] && !vis[p.ff+1][p.ss]){
		  mc[p.st+1]=min(s[p.ff+1][p.ss],mc[p.st+1]);
		 vis[p.ff+1][p.ss]=1;
		 q.push((nd){p.ff+1,p.ss,p.st+1});
	  }
	  if(p.ss+1<n && dp[p.ff][p.ss+1] && !vis[p.ff][p.ss+1]){
		 mc[p.st+1]=min(s[p.ff][p.ss+1],mc[p.st+1]);
		 vis[p.ff][p.ss+1]=1;
		 q.push((nd){p.ff,p.ss+1,p.st+1});
	  }
}

 for(int i=0;i<n+n-1;i++)cout<<mc[i];

	return 0;
}


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

#define ll  int
#define intmax INT_MAX
#define pi 3.14159265358979323846
//~ #define ff first
//~ #define ss second
#define pb push_back
#define watch(x) cerr<<(#x)<<"  "<<x<<"\n";
const int mod=998244353;
const int MAXN = 2e3+2;
int dp[MAXN][MAXN],vis[MAXN][MAXN];

struct nd{
	int ff,ss,st;
}p;

int main(){
 int n,k; cin>>n>>k;
 string s[n];
 for(int i=0;i<n;i++)cin>>s[i];
 dp[0][0]=(s[0][0]!='a');
 for(int i=1;i<n;i++){
	 dp[i][0]=dp[i-1][0]+(s[i][0]!='a');
	 dp[0][i]=dp[0][i-1]+(s[0][i]!='a');
 }

 for(int i=1;i<n;i++){
	 for(int j=1;j<n;j++) dp[i][j]=min(dp[i-1][j],dp[i][j-1])+(s[i][j]!='a');
 }
  queue<nd> q;
  int maxx=0;
 for(int i=0;i<n;i++){
	 for(int j=0;j<n;j++){
		 if(dp[i][j]==k && i+j>maxx) maxx=i+j;
	 }
 }
 char mc[1<<17];
 for(int i=0;i<n+n+1;i++) mc[i]='z';

 for(int i=0;i<n;i++){
	 for(int j=0;j<n;j++){
		 if(dp[i][j]==k && i+j==maxx) q.push({i,j,i+j}),mc[i+j]='a';
	 }
 }
  if(k==0) { mc[0]=s[0][0]; q.push((nd){0,0,0});}
  if(k>=dp[n-1][n-1]){for(int i=0;i<2*n-1;i++) cout<<'a'; return 0;}
 for(int i=0;i<maxx;i++) mc[i]='a';

while(!q.empty()){

       p=q.front(); q.pop();
       if(p.st!=maxx && mc[p.st]!=s[p.ff][p.ss]) continue;
	  if(p.ff+1<n && dp[p.ff+1][p.ss] && !vis[p.ff+1][p.ss]){
		  mc[p.st+1]=min(s[p.ff+1][p.ss],mc[p.st+1]);
		 vis[p.ff+1][p.ss]=1;
		 q.push((nd){p.ff+1,p.ss,p.st+1});
	  }
	  if(p.ss+1<n && dp[p.ff][p.ss+1] && !vis[p.ff][p.ss+1]){
		 mc[p.st+1]=min(s[p.ff][p.ss+1],mc[p.st+1]);
		 vis[p.ff][p.ss+1]=1;
		 q.push((nd){p.ff,p.ss+1,p.st+1});
	  }
}

 for(int i=0;i<n+n-1;i++)cout<<mc[i];

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define printvector(v,n) for(int i=1;i<=n;i++) cout<<v[i]<<" "; cout<<ln;
#define printint(v) copy(begin(v), end(v), ostream_iterator<int>(cout," "))
#define printintv(s,e) copy(s,e, ostream_iterator<int>(cout," "))
#define clz(a) __builtin_clz(a) // count leading zeroes
#define ctz(a) __builtin_ctz(a) // count trailing zeroes
#define popc(a) __builtin_popcount(a) // count set bits (for ints only diff for int64)
//https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html for other in built
#define ln "\n"
#define FOR(i,a,b) for(int i=a; i<=b; i++)
#define RFOR(i,b,a) for(int i=b; i>=a; i--)
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define setPresent(x,s) (s.find(x)!=s.end())
typedef long long int64;
typedef pair<int,int> p32;
typedef pair<int64,int64> p64;
typedef pair<double,double> pdd;
typedef vector<int64> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
#pragma GCC optimize ("-O2")
template<class T> using min_heap = priority_queue<T, std::vector<T>, std::greater<T> >;
const int lim=2006;
const int inf=1e9;
string s;
int n,k,mm=-1e9; char t,maxx='a'+27,mmin;
vector<p32> q,v;
vector<char> ans;

bool check(int x,int y){
	return x>=1 && x<=n && y>=1 && y<=n;
}
int main(){
	ios_base::sync_with_stdio(false); cin.tie(NULL);
	cin>>n>>k;
	char a[n+5][n+5];int dp[n+5][n+5];
	FOR(i,1,n){
		cin>>s; a[i][0]=maxx; a[i][n+1]=maxx;
		FOR(j,1,n) a[i][j]=s[j-1];
	}
	FOR(i,0,n) FOR(j,0,n) dp[i][j]=inf;
	FOR(i,1,n){
		FOR(j,1,n){
			if(i==1 && j==1){
				dp[i][j]=(a[i][j]!='a');
				if(dp[i][j]<=k) mm=max(i+j-1,mm);
				continue;
			}
 			dp[i][j]=min(dp[i-1][j],dp[i][j-1])+(a[i][j]!='a');
 			if(dp[i][j]<=k) mm=max(i+j-1,mm);

		}
	}
	FOR(i,1,n){
		FOR(j,1,n){
			if(dp[i][j]<=k && i+j-1==mm){
				q.pb(mp(i,j));
			}
		}
	}
	FOR(k,1,mm) ans.pb('a');
	if(q.empty()){
		ans.pb(a[1][1]);
		q.pb(mp(1,1));
	}
	FOR(i,1,2*n+3){
		if(q.empty()) break;
		mmin='a'+27;
		for(p32 p:q){
			if(check(p.fi+1,p.se)) mmin=min(mmin,a[p.fi+1][p.se]);
			if(check(p.fi,p.se+1)) mmin=min(mmin,a[p.fi][p.se+1]);
		}
		for(p32 p:q){
			if(check(p.fi+1,p.se) && a[p.fi+1][p.se]==mmin){
				v.pb(mp(p.fi+1,p.se));
			}
			if(check(p.fi,p.se+1)&& a[p.fi][p.se+1]==mmin){
				v.pb(mp(p.fi,p.se+1));
			}
		}
		while(!q.empty()) q.pop_back();
		while(!v.empty()){
			q.pb(v.back()); v.pop_back();
		}
		if(mmin!='a'+27) ans.pb(mmin);
	}
	for(char c:ans) cout<<c; cout<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define printvector(v,n) for(int i=1;i<=n;i++) cout<<v[i]<<" "; cout<<ln;
#define printint(v) copy(begin(v), end(v), ostream_iterator<int>(cout," "))
#define printintv(s,e) copy(s,e, ostream_iterator<int>(cout," "))
#define clz(a) __builtin_clz(a) // count leading zeroes
#define ctz(a) __builtin_ctz(a) // count trailing zeroes
#define popc(a) __builtin_popcount(a) // count set bits (for ints only diff for int64)
//https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html for other in built
#define ln "\n"
#define FOR(i,a,b) for(int i=a; i<=b; i++)
#define RFOR(i,b,a) for(int i=b; i>=a; i--)
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define setPresent(x,s) (s.find(x)!=s.end())
typedef long long int64;
typedef pair<int,int> p32;
typedef pair<int64,int64> p64;
typedef pair<double,double> pdd;
typedef vector<int64> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
#pragma GCC optimize ("-O2")
template<class T> using min_heap = priority_queue<T, std::vector<T>, std::greater<T> >;
const int lim=2006;
const int inf=1e9;
char a[lim][lim];
string s;
int n,k,mm=-1e9,dp[lim][lim]; char t,maxx='a'+27;
vector<p32> q;
vector<char> ans;

int main(){
	ios_base::sync_with_stdio(false); cin.tie(NULL);
	cin>>n>>k;
	FOR(i,1,n){
		cin>>s; a[i][0]=maxx; a[i][n+1]=maxx;
		FOR(j,1,n) a[i][j]=s[j-1];
	}
	FOR(i,0,n) FOR(j,0,n) dp[i][j]=inf;
	FOR(i,1,n){
		FOR(j,1,n){
			if(i==1 && j==1){
				dp[i][j]=(a[i][j]!='a');
				if(dp[i][j]<=k) mm=max(i+j-1,mm);
				continue;
			}
 			dp[i][j]=min(dp[i-1][j],dp[i][j-1])+(a[i][j]!='a');
 			if(dp[i][j]<=k) mm=max(i+j-1,mm);

		}
	}
	FOR(i,1,n){
		FOR(j,1,n){
			if(dp[i][j]<=k && i+j-1==mm){
				q.pb(mp(i,j));
			}
		}
	}
	FOR(k,1,mm) ans.pb('a');
	if(q.empty()) q.pb(mp(0,0));
	FOR(i,1,n+3){
		if(q.empty()) break;
		vector<p32> v; char mmin='a'+27;
		for(p32 p:q){
			if(p.fi+1<=n) mmin=min(mmin,a[p.fi+1][p.se]);
			if(p.se+1<=n) mmin=min(mmin,a[p.fi][p.se+1]);
		}
		for(p32 p:q){
			if(p.fi+1<=n && a[p.fi+1][p.se]==mmin){
				v.pb(mp(p.fi+1,p.se));
			}
			if(p.se+1<=n && a[p.fi][p.se+1]==mmin){
				v.pb(mp(p.fi,p.se+1));
			}
		}
		while(!q.empty()) q.pop_back();
		q=v;
		ans.pb(mmin);
	}
	ans.pop_back();
	for(char c:ans) cout<<c; cout<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define printvector(v,n) for(int i=1;i<=n;i++) cout<<v[i]<<" "; cout<<ln;
#define printint(v) copy(begin(v), end(v), ostream_iterator<int>(cout," "))
#define printintv(s,e) copy(s,e, ostream_iterator<int>(cout," "))
#define forstl(i,v) for(auto &i: v)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define clz(a) __builtin_clz(a) // count leading zeroes
#define ctz(a) __builtin_ctz(a) // count trailing zeroes
#define popc(a) __builtin_popcount(a) // count set bits (for ints only diff for int64)
//https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html for other in built
#define ln "\n"
#define FOR(i,a,b) for(int i=a; i<=b; i++)
#define RFOR(i,b,a) for(int i=b; i>=a; i--)
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define setPresent(x,s) (s.find(x)!=s.end())
typedef long long int64;
typedef pair<int,int> p32;
typedef pair<int64,int64> p64;
typedef pair<double,double> pdd;
typedef vector<int64> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
typedef map<int64,int64> m64;
#pragma GCC optimize ("-O2")
template<class T> using min_heap = priority_queue<T, std::vector<T>, std::greater<T> >;
const int LIM=2e3+5;
int n,k,inf=2e9,t=-1,p,x,y,z;
int dp[LIM][LIM]; // steps needed to make a prefix of a ending at i,j
string s;
char a[LIM][LIM],m='z';
vp32 q,q1;
vector<char> ans;
bool vis[LIM][LIM];

int main()
{
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    cin>>n>>k;
    FOR(i,0,n) dp[i][0]=inf;
    FOR(i,1,n) dp[0][i]=inf;
    FOR(i,1,n){
    	cin>>s;
    	FOR(j,1,n){
    		a[i][j]=s[j-1];
    	}
    }
    FOR(i,1,n){
    	FOR(j,1,n){
    		if(i==1 && j==1) dp[i][j]=int(a[i][j]!='a');
    		else dp[i][j]=int(a[i][j]!='a')+min(dp[i][j-1],dp[i-1][j]);
    		if(dp[i][j]<=k) t=max(t,i+j);
    	}
    }
    FOR(i,1,n){
    	FOR(j,1,n){
    		if(i+j==t && dp[i][j]<=k){
    			q.pb(mp(i,j));
    		}
    	}
    }
    FOR(i,1,t-1) ans.pb('a');
    if(k==0){
    	cout<<a[1][1];
    	q.pb(mp(1,1));
    	t=2;
    }
    FOR(z,t,2*n-1){
    	m='z'+1;
  //   	dbg(z);
		// int aa=q.size(); dbg(aa);
  //   	for(auto & u:q){
  //   		cout<<u.fi<<" "<<u.se<<endl;
  //   	}
    	for(auto & u:q){
    		if(u.se+1<=n) m=min(m,a[u.fi][u.se+1]);
    		if(u.fi+1<=n) m=min(m,a[u.fi+1][u.se]);
    	}
    	for(auto & u:q){
    		if(u.se<n && a[u.fi][u.se+1]==m && !vis[u.fi][u.se+1]){
    			q1.pb(mp(u.fi,u.se+1));
    			vis[u.fi][u.se+1]=1;
    		}
    		if(u.fi<n && a[u.fi+1][u.se]==m && !vis[u.fi+1][u.se]){
    			q1.pb(mp(u.fi+1,u.se));
    			vis[u.fi+1][u.se]=1;
    		}
    	}
    	while(!q.empty()) q.pop_back();
    	//aa=q.size(); dbg(aa);
    	while(!q1.empty()){
    		q.pb(q1.back()); q1.pop_back();
    	}
    	// dbg(m);
    	// cout<<"-----"<<endl;
    	ans.pb(m);
    }
    for(char c:ans) cout<<c;
    cout<<endl;
    // dbg(n);
    // dbg(t);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define printvector(v,n) for(int i=1;i<=n;i++) cout<<v[i]<<" "; cout<<ln;
#define printint(v) copy(begin(v), end(v), ostream_iterator<int>(cout," "))
#define printintv(s,e) copy(s,e, ostream_iterator<int>(cout," "))
#define clz(a) __builtin_clz(a) // count leading zeroes
#define ctz(a) __builtin_ctz(a) // count trailing zeroes
#define popc(a) __builtin_popcount(a) // count set bits (for ints only diff for int64)
//https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html for other in built
#define ln "\n"
#define FOR(i,a,b) for(int i=a; i<=b; i++)
#define RFOR(i,b,a) for(int i=b; i>=a; i--)
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define setPresent(x,s) (s.find(x)!=s.end())
typedef long long int64;
typedef pair<int,int> p32;
typedef pair<int64,int64> p64;
typedef pair<double,double> pdd;
typedef vector<int64> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
#pragma GCC optimize ("-O2")
template<class T> using min_heap = priority_queue<T, std::vector<T>, std::greater<T> >;
const int lim=2006;
const int inf=1e9;
char a[lim][lim];
string s;
int n,k,mm=-1e9,dp[lim][lim]; char t,maxx='a'+27,mmin;
vector<p32> q,v;
vector<char> ans;

bool check(int x,int y){
	return x>=1 && x<=n && y>=1 && y<=n;
}
int main(){
	ios_base::sync_with_stdio(false); cin.tie(NULL);
	cin>>n>>k;
	FOR(i,1,n){
		cin>>s; a[i][0]=maxx; a[i][n+1]=maxx;
		FOR(j,1,n) a[i][j]=s[j-1];
	}
	FOR(i,0,n) FOR(j,0,n) dp[i][j]=inf;
	FOR(i,1,n){
		FOR(j,1,n){
			if(i==1 && j==1){
				dp[i][j]=(a[i][j]!='a');
				if(dp[i][j]<=k) mm=max(i+j-1,mm);
				continue;
			}
 			dp[i][j]=min(dp[i-1][j],dp[i][j-1])+(a[i][j]!='a');
 			if(dp[i][j]<=k) mm=max(i+j-1,mm);

		}
	}
	FOR(i,1,n){
		FOR(j,1,n){
			if(dp[i][j]<=k && i+j-1==mm){
				q.pb(mp(i,j));
			}
		}
	}
	FOR(k,1,mm) ans.pb('a');
	if(q.empty()){
		ans.pb(a[1][1]);
		q.pb(mp(1,1));
	}
	FOR(i,1,2*n+3){
		if(q.empty()) break;
		mmin='a'+27;
		for(p32 p:q){
			if(check(p.fi+1,p.se)) mmin=min(mmin,a[p.fi+1][p.se]);
			if(check(p.fi,p.se+1)) mmin=min(mmin,a[p.fi][p.se+1]);
		}
		for(p32 p:q){
			if(check(p.fi+1,p.se) && a[p.fi+1][p.se]==mmin){
				v.pb(mp(p.fi+1,p.se));
			}
			if(check(p.fi,p.se+1)&& a[p.fi][p.se+1]==mmin){
				v.pb(mp(p.fi,p.se+1));
			}
		}
		while(!q.empty()) q.pop_back();
		while(!v.empty()){
			q.pb(v.back()); v.pop_back();
		}
		if(mmin!='a'+27) ans.pb(mmin);
	}
	for(char c:ans) cout<<c; cout<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define printvector(v,n) for(int i=1;i<=n;i++) cout<<v[i]<<" "; cout<<ln;
#define printint(v) copy(begin(v), end(v), ostream_iterator<int>(cout," "))
#define printintv(s,e) copy(s,e, ostream_iterator<int>(cout," "))
#define clz(a) __builtin_clz(a) // count leading zeroes
#define ctz(a) __builtin_ctz(a) // count trailing zeroes
#define popc(a) __builtin_popcount(a) // count set bits (for ints only diff for int64)
//https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html for other in built
#define ln "\n"
#define FOR(i,a,b) for(int i=a; i<=b; i++)
#define RFOR(i,b,a) for(int i=b; i>=a; i--)
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define setPresent(x,s) (s.find(x)!=s.end())
typedef long long int64;
typedef pair<int,int> p32;
typedef pair<int64,int64> p64;
typedef pair<double,double> pdd;
typedef vector<int64> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
#pragma GCC optimize ("-O2")
template<class T> using min_heap = priority_queue<T, std::vector<T>, std::greater<T> >;
const int lim=2006;
const int inf=1e9;
char a[lim][lim];
string s;
int n,k,mm=-1e9,dp[lim][lim]; char t,maxx='a'+27,mmin;
vector<p32> q,v;
vector<char> ans;

bool check(int & x,int & y){
	return x>=1 && x<=n && y>=1 && y<=n;
}
int main(){
	ios_base::sync_with_stdio(false); cin.tie(NULL);
	cin>>n>>k;
	FOR(i,1,n){
		cin>>s; a[i][0]=maxx; a[i][n+1]=maxx;
		FOR(j,1,n) a[i][j]=s[j-1];
	}
	FOR(i,0,n) FOR(j,0,n) dp[i][j]=inf;
	FOR(i,1,n){
		FOR(j,1,n){
			if(i==1 && j==1){
				dp[i][j]=(a[i][j]!='a');
				if(dp[i][j]<=k) mm=max(i+j-1,mm);
				continue;
			}
 			dp[i][j]=min(dp[i-1][j],dp[i][j-1])+(a[i][j]!='a');
 			if(dp[i][j]<=k) mm=max(i+j-1,mm);

		}
	}
	FOR(i,1,n){
		FOR(j,1,n){
			if(dp[i][j]<=k && i+j-1==mm){
				q.pb(mp(i,j));
			}
		}
	}
	FOR(k,1,mm) ans.pb('a');
	if(q.empty()){
		ans.pb(a[1][1]);
		q.pb(mp(1,1));
	}
	FOR(i,1,2*n+3){
		if(q.empty()) break;
		mmin='a'+27;
		for(p32 p:q){
			if(check(p.fi+1,p.se)) mmin=min(mmin,a[p.fi+1][p.se]);
			if(check(p.fi,p.se+1)) mmin=min(mmin,a[p.fi][p.se+1]);
		}
		for(p32 p:q){
			if(check(p.fi+1,p.se) && a[p.fi+1][p.se]==mmin){
				v.pb(mp(p.fi+1,p.se));
			}
			if(check(p.fi,p.se+1)&& a[p.fi][p.se+1]==mmin){
				v.pb(mp(p.fi,p.se+1));
			}
		}
		while(!q.empty()) q.pop_back();
		while(!v.empty()){
			q.pb(v.back()); v.pop_back();
		}
		if(mmin!='a'+27) ans.pb(mmin);
	}
	for(char c:ans) cout<<c; cout<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define printvector(v,n) for(int i=1;i<=n;i++) cout<<v[i]<<" "; cout<<ln;
#define printint(v) copy(begin(v), end(v), ostream_iterator<int>(cout," "))
#define printintv(s,e) copy(s,e, ostream_iterator<int>(cout," "))
#define clz(a) __builtin_clz(a) // count leading zeroes
#define ctz(a) __builtin_ctz(a) // count trailing zeroes
#define popc(a) __builtin_popcount(a) // count set bits (for ints only diff for int64)
//https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html for other in built
#define ln "\n"
#define FOR(i,a,b) for(int i=a; i<=b; i++)
#define RFOR(i,b,a) for(int i=b; i>=a; i--)
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define setPresent(x,s) (s.find(x)!=s.end())
typedef long long int64;
typedef pair<int,int> p32;
typedef pair<int64,int64> p64;
typedef pair<double,double> pdd;
typedef vector<int64> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
#pragma GCC optimize ("-O2")
template<class T> using min_heap = priority_queue<T, std::vector<T>, std::greater<T> >;
const int lim=2006;
const int inf=1e9;
string a[lim];
string s;
int n,k,mm=-1e9,dp[lim][lim]; char t,maxx='a'+27;
vector<p32> q;
vector<char> ans;

int main(){
	ios_base::sync_with_stdio(false); cin.tie(NULL);
	cin>>n>>k;
	FOR(i,1,n){
		cin>>s; a[i]=maxx+s+maxx;
	}
	FOR(i,0,n) FOR(j,0,n) dp[i][j]=inf;
	FOR(i,1,n){
		FOR(j,1,n){
			if(i==1 && j==1){
				dp[i][j]=(a[i][j]!='a'); continue;
			}
 			dp[i][j]=min(dp[i-1][j],dp[i][j-1])+(a[i][j]!='a');
 			if(dp[i][j]<=k) mm=max(i+j-1,mm);

		}
	}
	// find longest prefix that can be obtained within k moves

	FOR(i,1,n){
		FOR(j,1,n){
			if(dp[i][j]<=k && i+j-1==mm){
				q.pb(mp(i,j));
			}
		}
	}
	FOR(k,1,mm) ans.pb('a');
	FOR(i,1,n+3){
		if(q.empty()) break;
		vector<p32> v; char mmin='a'+27;
		for(p32 p:q){
			if(p.fi+1<=n) mmin=min(mmin,a[p.fi+1][p.se]);
			if(p.se+1<=n) mmin=min(mmin,a[p.fi][p.se+1]);
		}
		for(p32 p:q){
			if(p.fi+1<=n && a[p.fi+1][p.se]==mmin){
				v.pb(mp(p.fi+1,p.se));
			}
			if(p.se+1<=n && a[p.fi][p.se+1]==mmin){
				v.pb(mp(p.fi,p.se+1));
			}
		}
		while(!q.empty()) q.pop_back();
		q=v;
		ans.pb(mmin);
	}
	ans.pop_back();
	for(char c:ans) cout<<c; cout<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define printvector(v,n) for(int i=1;i<=n;i++) cout<<v[i]<<" "; cout<<ln;
#define printint(v) copy(begin(v), end(v), ostream_iterator<int>(cout," "))
#define printintv(s,e) copy(s,e, ostream_iterator<int>(cout," "))
#define forstl(i,v) for(auto &i: v)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define clz(a) __builtin_clz(a) // count leading zeroes
#define ctz(a) __builtin_ctz(a) // count trailing zeroes
#define popc(a) __builtin_popcount(a) // count set bits (for ints only diff for int64)
//https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html for other in built
#define ln "\n"
#define FOR(i,a,b) for(int i=a; i<=b; i++)
#define RFOR(i,b,a) for(int i=b; i>=a; i--)
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define setPresent(x,s) (s.find(x)!=s.end())
typedef long long int64;
typedef pair<int,int> p32;
typedef pair<int64,int64> p64;
typedef pair<double,double> pdd;
typedef vector<int64> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
typedef map<int64,int64> m64;
#pragma GCC optimize ("-O2")
template<class T> using min_heap = priority_queue<T, std::vector<T>, std::greater<T> >;
const int LIM=2e3+5;
int n,k,inf=2e9,t=-1,p,x,y,z;
int dp[LIM][LIM]; // steps needed to make a prefix of a ending at i,j
string s;
char a[LIM][LIM],m='z';
vp32 q,q1;
vector<char> ans;
bool vis[LIM][LIM];

int main()
{
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    cin>>n>>k;
    FOR(i,0,n) dp[i][0]=inf;
    FOR(i,1,n) dp[0][i]=inf;
    FOR(i,1,n){
    	cin>>s;
    	FOR(j,1,n){
    		a[i][j]=s[j-1];
    	}
    }
    FOR(i,1,n){
    	FOR(j,1,n){
    		if(i==1 && j==1) dp[i][j]=int(a[i][j]!='a');
    		else dp[i][j]=int(a[i][j]!='a')+min(dp[i][j-1],dp[i-1][j]);
    		if(dp[i][j]<=k) t=max(t,i+j);
    	}
    }
    FOR(i,1,n){
    	FOR(j,1,n){
    		if(i+j==t && dp[i][j]<=k){
    			q.pb(mp(i,j));
    		}
    	}
    }
    FOR(i,1,t-1) ans.pb('a');
    if(k==0){
    	cout<<a[1][1];
    	q.pb(mp(1,1));
    	t=2;
    }
    FOR(z,t,2*n-1){
    	m='z'+1;
  //   	dbg(z);
		// int aa=q.size(); dbg(aa);
  //   	for(auto & u:q){
  //   		cout<<u.fi<<" "<<u.se<<endl;
  //   	}
    	for(auto & u:q){
    		if(u.se+1<=n && !vis[u.fi][u.se+1]) m=min(m,a[u.fi][u.se+1]);
    		if(u.fi+1<=n && !vis[u.fi+1][u.se]) m=min(m,a[u.fi+1][u.se]);
    	}
    	for(auto & u:q){
    		if(u.se<n && a[u.fi][u.se+1]==m && !vis[u.fi][u.se+1]){
    			q1.pb(mp(u.fi,u.se+1));
    			vis[u.fi][u.se+1]=1;
    		}
    		if(u.fi<n && a[u.fi+1][u.se]==m && !vis[u.fi+1][u.se]){
    			q1.pb(mp(u.fi+1,u.se));
    			vis[u.fi][u.se+1]=1;
    		}
    	}
    	while(!q.empty()) q.pop_back();
    	//aa=q.size(); dbg(aa);
    	while(!q1.empty()){
    		q.pb(q1.back()); q1.pop_back();
    	}
    	// dbg(m);
    	// cout<<"-----"<<endl;
    	ans.pb(m);
    }
    for(char c:ans) cout<<c;
    cout<<endl;
    // dbg(n);
    // dbg(t);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define printvector(v,n) for(int i=1;i<=n;i++) cout<<v[i]<<" "; cout<<ln;
#define printint(v) copy(begin(v), end(v), ostream_iterator<int>(cout," "))
#define printintv(s,e) copy(s,e, ostream_iterator<int>(cout," "))
#define clz(a) __builtin_clz(a) // count leading zeroes
#define ctz(a) __builtin_ctz(a) // count trailing zeroes
#define popc(a) __builtin_popcount(a) // count set bits (for ints only diff for int64)
//https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html for other in built
#define ln "\n"
#define FOR(i,a,b) for(int i=a; i<=b; i++)
#define RFOR(i,b,a) for(int i=b; i>=a; i--)
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define setPresent(x,s) (s.find(x)!=s.end())
typedef long long int64;
typedef pair<int,int> p32;
typedef pair<int64,int64> p64;
typedef pair<double,double> pdd;
typedef vector<int64> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
#pragma GCC optimize ("-O2")
template<class T> using min_heap = priority_queue<T, std::vector<T>, std::greater<T> >;
const int lim=2006;
const int inf=1e9;
char a[lim][lim];
string s;
int n,k,mm=-1e9,dp[lim][lim]; char t,maxx='a'+27;
vector<p32> q;
vector<char> ans;

bool check(int x,int y){
	return x>=1 && x<=n && y>=1 && y<=n;
}
int main(){
	ios_base::sync_with_stdio(false); cin.tie(NULL);
	cin>>n>>k;
	FOR(i,1,n){
		cin>>s; a[i][0]=maxx; a[i][n+1]=maxx;
		FOR(j,1,n) a[i][j]=s[j-1];
	}
	FOR(i,0,n) FOR(j,0,n) dp[i][j]=inf;
	FOR(i,1,n){
		FOR(j,1,n){
			if(i==1 && j==1){
				dp[i][j]=(a[i][j]!='a');
				if(dp[i][j]<=k) mm=max(i+j-1,mm);
				continue;
			}
 			dp[i][j]=min(dp[i-1][j],dp[i][j-1])+(a[i][j]!='a');
 			if(dp[i][j]<=k) mm=max(i+j-1,mm);

		}
	}
	FOR(i,1,n){
		FOR(j,1,n){
			if(dp[i][j]<=k && i+j-1==mm){
				q.pb(mp(i,j));
			}
		}
	}
	FOR(k,1,mm) ans.pb('a');
	if(q.empty()) q.pb(mp(0,1));
	FOR(i,1,n+3){
		if(q.empty()) break;
		vector<p32> v; char mmin='a'+27;
		for(p32 p:q){
			if(check(p.fi+1,p.se)) mmin=min(mmin,a[p.fi+1][p.se]);
			if(check(p.fi,p.se+1)) mmin=min(mmin,a[p.fi][p.se+1]);
		}
		for(p32 p:q){
			if(check(p.fi+1,p.se) && a[p.fi+1][p.se]==mmin){
				v.pb(mp(p.fi+1,p.se));
			}
			if(check(p.fi,p.se+1)&& a[p.fi][p.se+1]==mmin){
				v.pb(mp(p.fi,p.se+1));
			}
		}
		while(!q.empty()) q.pop_back();
		q=v;
		ans.pb(mmin);
	}
	ans.pop_back();
	for(char c:ans) cout<<c; cout<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define printvector(v,n) for(int i=1;i<=n;i++) cout<<v[i]<<" "; cout<<ln;
#define printint(v) copy(begin(v), end(v), ostream_iterator<int>(cout," "))
#define printintv(s,e) copy(s,e, ostream_iterator<int>(cout," "))
#define clz(a) __builtin_clz(a) // count leading zeroes
#define ctz(a) __builtin_ctz(a) // count trailing zeroes
#define popc(a) __builtin_popcount(a) // count set bits (for ints only diff for int64)
//https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html for other in built
#define ln "\n"
#define FOR(i,a,b) for(int i=a; i<=b; i++)
#define RFOR(i,b,a) for(int i=b; i>=a; i--)
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define setPresent(x,s) (s.find(x)!=s.end())
typedef long long int64;
typedef pair<int,int> p32;
typedef pair<int64,int64> p64;
typedef pair<double,double> pdd;
typedef vector<int64> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
#pragma GCC optimize ("-O2")
template<class T> using min_heap = priority_queue<T, std::vector<T>, std::greater<T> >;
const int lim=2006;
const int inf=1e9;
string s;
int n,k,mm=-1e9; char t,maxx='a'+27,mmin;
vector<p32> q,v;
vector<char> ans;
char a[lim][lim];int dp[lim][lim];

bool check(int x,int y){
	return x>=1 && x<=n && y>=1 && y<=n;
}
int main(){
	ios_base::sync_with_stdio(false); cin.tie(NULL);
	cin>>n>>k;
	FOR(i,1,n){
		cin>>s; a[i][0]=maxx; a[i][n+1]=maxx;
		FOR(j,1,n) a[i][j]=s[j-1];
	}
	FOR(i,0,n) FOR(j,0,n) dp[i][j]=inf;
	FOR(i,1,n){
		FOR(j,1,n){
			if(i==1 && j==1){
				dp[i][j]=(a[i][j]!='a');
				if(dp[i][j]<=k) mm=max(i+j-1,mm);
				continue;
			}
 			dp[i][j]=min(dp[i-1][j],dp[i][j-1])+(a[i][j]!='a');
 			if(dp[i][j]<=k) mm=max(i+j-1,mm);

		}
	}
	FOR(i,1,n){
		FOR(j,1,n){
			if(dp[i][j]<=k && i+j-1==mm){
				q.pb(mp(i,j));
			}
		}
	}
	FOR(k,1,mm) ans.pb('a');
	if(q.empty()){
		ans.pb(a[1][1]);
		q.pb(mp(1,1));
	}
	FOR(i,1,2*n+3){
		if(q.empty()) break;
		mmin='a'+27;
		for(p32 & p:q){
			if(check(p.fi+1,p.se)) mmin=min(mmin,a[p.fi+1][p.se]);
			if(check(p.fi,p.se+1)) mmin=min(mmin,a[p.fi][p.se+1]);
		}
		for(p32 & p:q){
			if(check(p.fi+1,p.se) && a[p.fi+1][p.se]==mmin){
				v.pb(mp(p.fi+1,p.se));
			}
			if(check(p.fi,p.se+1)&& a[p.fi][p.se+1]==mmin){
				v.pb(mp(p.fi,p.se+1));
			}
		}
		while(!q.empty()) q.pop_back();
		while(!v.empty()){
			q.pb(v.back()); v.pop_back();
		}
		if(mmin!='a'+27) ans.pb(mmin);
	}
	for(char & c:ans) cout<<c; cout<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define printvector(v,n) for(int i=1;i<=n;i++) cout<<v[i]<<" "; cout<<ln;
#define printint(v) copy(begin(v), end(v), ostream_iterator<int>(cout," "))
#define printintv(s,e) copy(s,e, ostream_iterator<int>(cout," "))
#define forstl(i,v) for(auto &i: v)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define clz(a) __builtin_clz(a) // count leading zeroes
#define ctz(a) __builtin_ctz(a) // count trailing zeroes
#define popc(a) __builtin_popcount(a) // count set bits (for ints only diff for int64)
//https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html for other in built
#define ln "\n"
#define FOR(i,a,b) for(int i=a; i<=b; i++)
#define RFOR(i,b,a) for(int i=b; i>=a; i--)
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define setPresent(x,s) (s.find(x)!=s.end())
typedef long long int64;
typedef pair<int,int> p32;
typedef pair<int64,int64> p64;
typedef pair<double,double> pdd;
typedef vector<int64> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
typedef map<int64,int64> m64;
#pragma GCC optimize ("-O2")
template<class T> using min_heap = priority_queue<T, std::vector<T>, std::greater<T> >;
const int LIM=2e3+5;
int n,k,inf=2e9,t=-1,p,x,y,z;
int dp[LIM][LIM]; // steps needed to make a prefix of a ending at i,j
string s;
char a[LIM][LIM],m='z';
vp32 q,q1;
vector<char> ans;
bool vis[LIM][LIM];

int main()
{
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    cin>>n>>k;
    FOR(i,0,n) dp[i][0]=inf;
    FOR(i,1,n) dp[0][i]=inf;
    FOR(i,1,n){
    	cin>>s;
    	FOR(j,1,n) a[i][j]=s[j-1];
    }
    if(k==0){
    	cout<<a[1][1];
    	q.pb(mp(1,1));
    	t=2;
    }
    else{
	    FOR(i,1,n){
	    	FOR(j,1,n){
	    		if(i==1 && j==1) dp[i][j]=int(a[i][j]!='a');
	    		else dp[i][j]=int(a[i][j]!='a')+min(dp[i][j-1],dp[i-1][j]);
	    		if(dp[i][j]<=k) t=max(t,i+j);
	    	}
	    }
	    FOR(i,1,n){
	    	FOR(j,1,n){
	    		if(i+j==t && dp[i][j]<=k) q.pb(mp(i,j));
	    	}
	    }
	    FOR(i,1,t-1) ans.pb('a');
	}
    FOR(z,t,2*n-1){
    	m='z'+1;
    	for(auto & u:q){
    		if(u.se+1<=n) m=min(m,a[u.fi][u.se+1]);
    		if(u.fi+1<=n) m=min(m,a[u.fi+1][u.se]);
    	}
    	for(auto & u:q){
    		if(u.se+1<=n && a[u.fi][u.se+1]==m && !vis[u.fi][u.se+1]){
    			q1.pb(mp(u.fi,u.se+1));
    			vis[u.fi][u.se+1]=1;
    		}
    		if(u.fi+1<=n && a[u.fi+1][u.se]==m && !vis[u.fi+1][u.se]){
    			q1.pb(mp(u.fi+1,u.se));
    			vis[u.fi+1][u.se]=1;
    		}
    	}
    	while(!q.empty()) q.pop_back();
    	while(!q1.empty()){
    		q.pb(q1.back()); q1.pop_back();
    	}
    	ans.pb(m);
    }
    for(char c:ans) cout<<c;
    cout<<endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define printvector(v,n) for(int i=1;i<=n;i++) cout<<v[i]<<" "; cout<<ln;
#define printint(v) copy(begin(v), end(v), ostream_iterator<int>(cout," "))
#define printintv(s,e) copy(s,e, ostream_iterator<int>(cout," "))
#define clz(a) __builtin_clz(a) // count leading zeroes
#define ctz(a) __builtin_ctz(a) // count trailing zeroes
#define popc(a) __builtin_popcount(a) // count set bits (for ints only diff for int64)
//https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html for other in built
#define ln "\n"
#define FOR(i,a,b) for(int i=a; i<=b; i++)
#define RFOR(i,b,a) for(int i=b; i>=a; i--)
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define setPresent(x,s) (s.find(x)!=s.end())
typedef long long int64;
typedef pair<int,int> p32;
typedef pair<int64,int64> p64;
typedef pair<double,double> pdd;
typedef vector<int64> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
#pragma GCC optimize ("-O2")
template<class T> using min_heap = priority_queue<T, std::vector<T>, std::greater<T> >;
const int lim=2006;
const int inf=1e9;
char a[lim][lim];
string s;
int n,k,mm=-1e9,dp[lim][lim]; char t,maxx='a'+27;
vector<p32> q;
vector<char> ans;

bool check(int x,int y){
	return x>=1 && x<=n && y>=1 && y<=n;
}
int main(){
	ios_base::sync_with_stdio(false); cin.tie(NULL);
	cin>>n>>k;
	FOR(i,1,n){
		cin>>s; a[i][0]=maxx; a[i][n+1]=maxx;
		FOR(j,1,n) a[i][j]=s[j-1];
	}
	FOR(i,0,n) FOR(j,0,n) dp[i][j]=inf;
	FOR(i,1,n){
		FOR(j,1,n){
			if(i==1 && j==1){
				dp[i][j]=(a[i][j]!='a');
				if(dp[i][j]<=k) mm=max(i+j-1,mm);
				continue;
			}
 			dp[i][j]=min(dp[i-1][j],dp[i][j-1])+(a[i][j]!='a');
 			if(dp[i][j]<=k) mm=max(i+j-1,mm);

		}
	}
	FOR(i,1,n){
		FOR(j,1,n){
			if(dp[i][j]<=k && i+j-1==mm){
				q.pb(mp(i,j));
			}
		}
	}
	FOR(k,1,mm) ans.pb('a');
	if(q.empty()){
		ans.pb(a[1][1]);
		q.pb(mp(1,1));
	}
	FOR(i,1,2*n+3){
		if(q.empty()) break;
		vector<p32> v; char mmin='a'+27;
		for(p32 p:q){
			if(check(p.fi+1,p.se)) mmin=min(mmin,a[p.fi+1][p.se]);
			if(check(p.fi,p.se+1)) mmin=min(mmin,a[p.fi][p.se+1]);
		}
		for(p32 p:q){
			if(check(p.fi+1,p.se) && a[p.fi+1][p.se]==mmin){
				v.pb(mp(p.fi+1,p.se));
			}
			if(check(p.fi,p.se+1)&& a[p.fi][p.se+1]==mmin){
				v.pb(mp(p.fi,p.se+1));
			}
		}
		q=v;
		if(mmin!='a'+27) ans.pb(mmin);
	}
	for(char c:ans) cout<<c; cout<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define printvector(v,n) for(int i=1;i<=n;i++) cout<<v[i]<<" "; cout<<ln;
#define printint(v) copy(begin(v), end(v), ostream_iterator<int>(cout," "))
#define printintv(s,e) copy(s,e, ostream_iterator<int>(cout," "))
#define forstl(i,v) for(auto &i: v)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define clz(a) __builtin_clz(a) // count leading zeroes
#define ctz(a) __builtin_ctz(a) // count trailing zeroes
#define popc(a) __builtin_popcount(a) // count set bits (for ints only diff for int64)
//https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html for other in built
#define ln "\n"
#define FOR(i,a,b) for(int i=a; i<=b; i++)
#define RFOR(i,b,a) for(int i=b; i>=a; i--)
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define setPresent(x,s) (s.find(x)!=s.end())
typedef long long int64;
typedef pair<int,int> p32;
typedef pair<int64,int64> p64;
typedef pair<double,double> pdd;
typedef vector<int64> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
typedef map<int64,int64> m64;
#pragma GCC optimize ("-O2")
template<class T> using min_heap = priority_queue<T, std::vector<T>, std::greater<T> >;
const int LIM=2e3+5;
int n,k,inf=2e9,t=-1,p,x,y,z;
int dp[LIM][LIM]; // steps needed to make a prefix of a ending at i,j
string s;
char a[LIM][LIM],m='z';
vp32 q,q1;
vector<char> ans;
bool vis[LIM][LIM];

int main()
{
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    cin>>n>>k;
    FOR(i,0,n) dp[i][0]=inf;
    FOR(i,1,n) dp[0][i]=inf;
    FOR(i,1,n){
    	cin>>s;
    	FOR(j,1,n){
    		a[i][j]=s[j-1];
    	}
    }
    if(k==0){
    	cout<<a[1][1];
    	q.pb(mp(1,1));
    	t=2;
    }
    else{
	    FOR(i,1,n){
	    	FOR(j,1,n){
	    		if(i==1 && j==1) dp[i][j]=int(a[i][j]!='a');
	    		else dp[i][j]=int(a[i][j]!='a')+min(dp[i][j-1],dp[i-1][j]);
	    		if(dp[i][j]<=k) t=max(t,i+j);
	    	}
	    }
	    FOR(i,1,n){
	    	FOR(j,1,n){
	    		if(i+j==t && dp[i][j]<=k){
	    			q.pb(mp(i,j));
	    		}
	    	}
	    }
	    FOR(i,1,t-1) ans.pb('a');
	}
    FOR(z,t,2*n-1){
    	m='z'+1;
  //   	dbg(z);
		// int aa=q.size(); dbg(aa);
  //   	for(auto & u:q){
  //   		cout<<u.fi<<" "<<u.se<<endl;
  //   	}
    	for(auto & u:q){
    		if(u.se+1<=n) m=min(m,a[u.fi][u.se+1]);
    		if(u.fi+1<=n) m=min(m,a[u.fi+1][u.se]);
    	}
    	for(auto & u:q){
    		if(u.se+1<=n && a[u.fi][u.se+1]==m && !vis[u.fi][u.se+1]){
    			q1.pb(mp(u.fi,u.se+1));
    			vis[u.fi][u.se+1]=1;
    		}
    		if(u.fi+1<=n && a[u.fi+1][u.se]==m && !vis[u.fi+1][u.se]){
    			q1.pb(mp(u.fi+1,u.se));
    			vis[u.fi+1][u.se]=1;
    		}
    	}
    	while(!q.empty()) q.pop_back();
    	//aa=q.size(); dbg(aa);
    	while(!q1.empty()){
    		q.pb(q1.back()); q1.pop_back();
    	}
    	// dbg(m);
    	// cout<<"-----"<<endl;
    	ans.pb(m);
    }
    for(char c:ans) cout<<c;
    cout<<endl;
    // dbg(n);
    // dbg(t);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define printvector(v,n) for(int i=1;i<=n;i++) cout<<v[i]<<" "; cout<<ln;
#define printint(v) copy(begin(v), end(v), ostream_iterator<int>(cout," "))
#define printintv(s,e) copy(s,e, ostream_iterator<int>(cout," "))
#define forstl(i,v) for(auto &i: v)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define clz(a) __builtin_clz(a) // count leading zeroes
#define ctz(a) __builtin_ctz(a) // count trailing zeroes
#define popc(a) __builtin_popcount(a) // count set bits (for ints only diff for int64)
//https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html for other in built
#define ln "\n"
#define FOR(i,a,b) for(int i=a; i<=b; i++)
#define RFOR(i,b,a) for(int i=b; i>=a; i--)
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define setPresent(x,s) (s.find(x)!=s.end())
typedef long long int64;
typedef pair<int,int> p32;
typedef pair<int64,int64> p64;
typedef pair<double,double> pdd;
typedef vector<int64> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
typedef map<int64,int64> m64;
#pragma GCC optimize ("-O2")
template<class T> using min_heap = priority_queue<T, std::vector<T>, std::greater<T> >;
const int LIM=2e3+5;
int n,k,inf=2e9,t=-1,p,x,y,z;
int dp[LIM][LIM]; // steps needed to make a prefix of a ending at i,j
string s;
char a[LIM][LIM],m='z';
vp32 q,q1;

int main()
{
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    cin>>n>>k;
    FOR(i,0,n) dp[i][0]=inf;
    FOR(i,1,n) dp[0][i]=inf;
    FOR(i,1,n){
    	cin>>s;
    	FOR(j,1,n){
    		a[i][j]=s[j-1];
    	}
    }
    FOR(i,1,n){
    	FOR(j,1,n){
    		if(i==1 && j==1) dp[i][j]=int(a[i][j]!='a');
    		else dp[i][j]=int(a[i][j]!='a')+min(dp[i][j-1],dp[i-1][j]);
    		if(dp[i][j]<=k) t=max(t,i+j);
    	}
    }
    FOR(i,1,n){
    	FOR(j,1,n){
    		if(i+j==t && dp[i][j]<=k){
    			q.pb(mp(i,j));
    		}
    	}
    }
    FOR(i,1,t-1) cout<<"a";
    if(k==0){
    	cout<<a[1][1];
    	q.pb(mp(1,1));
    	t=2;
    }
    FOR(z,t,2*n-1){
    	m='z'+1;
    	for(auto & u:q){
    		if(u.se+1<=n) m=min(m,a[u.fi][u.se+1]);
    		if(u.fi+1<=n) m=min(m,a[u.fi+1][u.se]);
    	}
    	for(auto & u:q){
    		if(u.se+1<=n && a[u.fi][u.se+1]==m) q1.pb(mp(u.fi,u.se+1));
    		if(u.fi+1<=n && a[u.fi+1][u.se]==m) q1.pb(mp(u.fi+1,u.se));
    	}
    	while(!q.empty()) q.pop_back();
    	while(!q1.empty()){
    		q.pb(q1.back()); q1.pop_back();
    	}
    	cout<<m;
    }
    cout<<endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define printvector(v,n) for(int i=1;i<=n;i++) cout<<v[i]<<" "; cout<<ln;
#define printint(v) copy(begin(v), end(v), ostream_iterator<int>(cout," "))
#define printintv(s,e) copy(s,e, ostream_iterator<int>(cout," "))
#define clz(a) __builtin_clz(a) // count leading zeroes
#define ctz(a) __builtin_ctz(a) // count trailing zeroes
#define popc(a) __builtin_popcount(a) // count set bits (for ints only diff for int64)
//https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html for other in built
#define ln "\n"
#define FOR(i,a,b) for(int i=a; i<=b; i++)
#define RFOR(i,b,a) for(int i=b; i>=a; i--)
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define setPresent(x,s) (s.find(x)!=s.end())
typedef long long int64;
typedef pair<int,int> p32;
typedef pair<int64,int64> p64;
typedef pair<double,double> pdd;
typedef vector<int64> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
#pragma GCC optimize ("-O2")
template<class T> using min_heap = priority_queue<T, std::vector<T>, std::greater<T> >;
const int lim=2006;
const int inf=1e9;
char a[lim][lim];
string s;
int n,k,mm=-1e9,dp[lim][lim]; char t,maxx='a'+27;
vector<p32> q;
vector<char> ans;

bool check(int x,int y){
	return x>=1 && x<=n && y>=1 && y<=n;
}
int main(){
	ios_base::sync_with_stdio(false); cin.tie(NULL);
	cin>>n>>k;
	FOR(i,1,n){
		cin>>s; a[i][0]=maxx; a[i][n+1]=maxx;
		FOR(j,1,n) a[i][j]=s[j-1];
	}
	FOR(i,0,n) FOR(j,0,n) dp[i][j]=inf;
	FOR(i,1,n){
		FOR(j,1,n){
			if(i==1 && j==1){
				dp[i][j]=(a[i][j]!='a');
				if(dp[i][j]<=k) mm=max(i+j-1,mm);
				continue;
			}
 			dp[i][j]=min(dp[i-1][j],dp[i][j-1])+(a[i][j]!='a');
 			if(dp[i][j]<=k) mm=max(i+j-1,mm);

		}
	}
	FOR(i,1,n){
		FOR(j,1,n){
			if(dp[i][j]<=k && i+j-1==mm){
				q.pb(mp(i,j));
			}
		}
	}
	FOR(k,1,mm) ans.pb('a');
	if(q.empty()){
		ans.pb(a[1][1]);
		q.pb(mp(1,1));
	}
	FOR(i,1,n+3){
		if(q.empty()) break;
		vector<p32> v; char mmin='a'+27;
		for(p32 p:q){
			if(check(p.fi+1,p.se)) mmin=min(mmin,a[p.fi+1][p.se]);
			if(check(p.fi,p.se+1)) mmin=min(mmin,a[p.fi][p.se+1]);
		}
		for(p32 p:q){
			if(check(p.fi+1,p.se) && a[p.fi+1][p.se]==mmin){
				v.pb(mp(p.fi+1,p.se));
			}
			if(check(p.fi,p.se+1)&& a[p.fi][p.se+1]==mmin){
				v.pb(mp(p.fi,p.se+1));
			}
		}
		q=v;
		if(mmin!='a'+27) ans.pb(mmin);
	}
	for(char c:ans) cout<<c; cout<<endl;
	return 0;
}


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

using ull = unsigned long long;
using ll = long long;

#define REP(i, n) for (int i = 0; i < n; i++)
#define REPR(i, n) for (int i = n; i >= 0; i--)
#define FOR(i, m, n) for (int i = m; i < n; i++)
#define pb push_back
#define fill(x, y) memset(x, y, sizeof(x))
#define even(x) x % 2 == 0
#define odd(x) x % 2 != 0
#define all(x) x.begin(), x.end()
#define pcnt __builtin_popcount
#define buli(x) __builtin_popcountll(x)
#define F first
#define S second
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());
#define IN1(x) ll x; cin >> x;

// these functions return the position of result of Binary Search.
#define LB(s, t, x) (int) (lower_bound(s, t, x) - s)
#define UB(s, t, x) (int) (upper_bound(s, t, x) - s)

ll qp(ll a, ll b, int mo) { ll ans = 1; do { if (b & 1) ans = 1ll * ans * a % mo; a = 1ll * a * a % mo; } while (b >>= 1); return ans; }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b) { ll temp = gcd(a, b); return temp ? (a / temp * b) : 0; }
int mDays[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
int dx8[] = { 1, -1, 0, 0, 1, 1, -1, -1 }, dy8[] = { 0, 0, -1, 1, -1, 1, -1, 1 };

template <typename T>
vector<T> make_v(size_t a) { return vector<T>(a); }
template <typename T, typename... Ts>
auto make_v(size_t a, size_t b, Ts... ts) { return vector<decltype(make_v<T>(b, ts...))>(a, make_v<T>(b, ts...)); }
template <typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type
fill_v(T &t, const V &v) { t = v; }
template <typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type
fill_v(T &t, const V &v) { for (auto &e : t) fill_v(e, v); }
// auto dp = make_v<int>(4, h, w);
// fill_v(dp, 0);

const ll INF_LL = (1ll << 60);
const int INF_INT = (int)1e9;
const ll MOD_CONST = (ll)(1e9 + 7);

template <typename T>
vector<T> pows(int b, int n) {
    vector<T> ret;
    T x = 1;
    while (ret.size() < n) {
        ret.push_back(x);
        x *= b;
    }
    return ret;
}
// find string "from" in "str", and replace them to "to"
void strReplace(std::string& str, const std::string& from, const std::string& to) {
	std::string::size_type pos = 0;
	while (pos = str.find(from, pos), pos != std::string::npos) {
		str.replace(pos, from.length(), to);
		pos += to.length();
	}
}
template <class T>
bool chmax(T &a, const T &b) { if (a < b) { a = b; return 1; } return 0; }
template <class T>
bool chmin(T &a, const T &b) { if (b < a) { a = b; return 1; } return 0; }

inline tuple<ll, ll> rotate45(tuple<ll, ll> point) { ll x = get<0>(point), y = get<1>(point); return tuple<ll, ll>(x + y, x - y); }
inline bool rangeCheck2D(int nx, int ny, int Width, int Height) { return nx >= 0 and nx < Width and ny >= 0 and ny < Height; }

template <typename T>
vector<T> INPA(ll n) {
	vector<T> x;
	REP(i, n) {
		T tmp; cin >> tmp;
		x.push_back(tmp);
	}
	return move(x);
}
template <typename T>
void out(T o) { cout << o << endl; }
template <typename T>
void out(vector<T> &out) { REP(i, (int)out.size()) { cout << out[i]; if (i == (int)out.size() - 1) cout << endl; else cout << " "; } }
template <typename T>
void out(vector<vector<T>> o) { REP(i, o.size()) out(o[i]); }
void YesNo(bool f) { cout << (f?"Yes":"No") << endl; }
void YESNO(bool f) { cout << (f?"YES":"NO") << endl; }

// don't use " for (auto v : V) "
// use " for (const auto& e : V), for (auto&& e : V) "

// min({1, 2, 0}) = 0
// max({1, 2, 0}) = 2

int main(void)
{
    cin.tie(0); ios::sync_with_stdio(0); cout << fixed << setprecision(20);

	IN1(N); IN1(K);

	vector<string> f(N);
	REP(i, N) cin >> f[i];

	auto dp = make_v<ll>(N, N);
	if (f[0][0] != 'a') dp[0][0]++;
	FOR(i, 1, N) {
		dp[0][i] = dp[0][i-1];
		if (f[0][i] != 'a') dp[0][i]++;
	}
	FOR(i, 1, N) {
		dp[i][0] = dp[i-1][0];
		if (f[i][0] != 'a') dp[i][0]++;
	}

	int msum = 0;
	FOR(i, 1, N) {
		FOR(j, 1, N) {
			dp[i][j] = min(dp[i][j-1], dp[i-1][j]);
			if (f[i][j] != 'a')
				dp[i][j]++;
			if (dp[i][j] <= K) {
				chmax(msum, i + j);
			}
		}
	}

	string ans;
	REP(i, msum) ans.push_back('a');

	priority_queue<
		pair<char, pair<int, int>>,
		vector<pair<char, pair<int, int>>>,
		greater<>
	> q;
	REP(i, N) {
		REP(j, N) {
			if (dp[i][j] <= K and msum == (i + j)) {
				q.push({'a', {i, j}});
			}
		}
	}
	if (K == 0) q.push({f[0][0], {0, 0}});
	while (true) {
		auto ff = q.top(); q.pop();
		char c = ff.first;
		ans.push_back(c);
		queue<pair<int, int>> next;
		next.push(ff.second);
		while (q.size()) {
			if (c == q.top().first) {
				next.push(q.top().second);
			}
			q.pop();
		}
		while (next.size()) {
			auto p = next.front(); next.pop();
			if (p.first + 1 < N)
				q.push({f[p.first + 1][p.second], {p.first + 1, p.second}});
			if (p.second + 1 < N)
				q.push({f[p.first][p.second + 1], {p.first, p.second + 1}});
		}
		if (q.size() == 0) break;
	}
	out(ans);

    return 0;
}


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

using ull = unsigned long long;
using ll = long long;

#define REP(i, n) for (int i = 0; i < n; i++)
#define REPR(i, n) for (int i = n; i >= 0; i--)
#define FOR(i, m, n) for (int i = m; i < n; i++)
#define pb push_back
#define fill(x, y) memset(x, y, sizeof(x))
#define even(x) x % 2 == 0
#define odd(x) x % 2 != 0
#define all(x) x.begin(), x.end()
#define pcnt __builtin_popcount
#define buli(x) __builtin_popcountll(x)
#define F first
#define S second
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());
#define IN1(x) ll x; cin >> x;

// these functions return the position of result of Binary Search.
#define LB(s, t, x) (int) (lower_bound(s, t, x) - s)
#define UB(s, t, x) (int) (upper_bound(s, t, x) - s)

ll qp(ll a, ll b, int mo) { ll ans = 1; do { if (b & 1) ans = 1ll * ans * a % mo; a = 1ll * a * a % mo; } while (b >>= 1); return ans; }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b) { ll temp = gcd(a, b); return temp ? (a / temp * b) : 0; }
int mDays[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
int dx8[] = { 1, -1, 0, 0, 1, 1, -1, -1 }, dy8[] = { 0, 0, -1, 1, -1, 1, -1, 1 };

template <typename T>
vector<T> make_v(size_t a) { return vector<T>(a); }
template <typename T, typename... Ts>
auto make_v(size_t a, size_t b, Ts... ts) { return vector<decltype(make_v<T>(b, ts...))>(a, make_v<T>(b, ts...)); }
template <typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type
fill_v(T &t, const V &v) { t = v; }
template <typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type
fill_v(T &t, const V &v) { for (auto &e : t) fill_v(e, v); }
// auto dp = make_v<int>(4, h, w);
// fill_v(dp, 0);

const ll INF_LL = (1ll << 60);
const int INF_INT = (int)1e9;
const ll MOD_CONST = (ll)(1e9 + 7);

template <typename T>
vector<T> pows(int b, int n) {
    vector<T> ret;
    T x = 1;
    while (ret.size() < n) {
        ret.push_back(x);
        x *= b;
    }
    return ret;
}
// find string "from" in "str", and replace them to "to"
void strReplace(std::string& str, const std::string& from, const std::string& to) {
	std::string::size_type pos = 0;
	while (pos = str.find(from, pos), pos != std::string::npos) {
		str.replace(pos, from.length(), to);
		pos += to.length();
	}
}
template <class T>
bool chmax(T &a, const T &b) { if (a < b) { a = b; return 1; } return 0; }
template <class T>
bool chmin(T &a, const T &b) { if (b < a) { a = b; return 1; } return 0; }

inline tuple<ll, ll> rotate45(tuple<ll, ll> point) { ll x = get<0>(point), y = get<1>(point); return tuple<ll, ll>(x + y, x - y); }
inline bool rangeCheck2D(int nx, int ny, int Width, int Height) { return nx >= 0 and nx < Width and ny >= 0 and ny < Height; }

template <typename T>
vector<T> INPA(ll n) {
	vector<T> x;
	REP(i, n) {
		T tmp; cin >> tmp;
		x.push_back(tmp);
	}
	return move(x);
}
template <typename T>
void out(T o) { cout << o << endl; }
template <typename T>
void out(vector<T> &out) { REP(i, (int)out.size()) { cout << out[i]; if (i == (int)out.size() - 1) cout << endl; else cout << " "; } }
template <typename T>
void out(vector<vector<T>> o) { REP(i, o.size()) out(o[i]); }
void YesNo(bool f) { cout << (f?"Yes":"No") << endl; }
void YESNO(bool f) { cout << (f?"YES":"NO") << endl; }

// don't use " for (auto v : V) "
// use " for (const auto& e : V), for (auto&& e : V) "

// min({1, 2, 0}) = 0
// max({1, 2, 0}) = 2

int main(void)
{
    cin.tie(0); ios::sync_with_stdio(0); cout << fixed << setprecision(20);

	IN1(N); IN1(K);

	vector<string> f(N);
	REP(i, N) cin >> f[i];

	int msum = K;
	auto dp = make_v<int>(N, N);
	if (f[0][0] != 'a') dp[0][0]++;
	FOR(i, 1, N) {
		dp[0][i] = dp[0][i-1];
		if (f[0][i] != 'a') dp[0][i]++;
	}
	FOR(i, 1, N) {
		dp[i][0] = dp[i-1][0];
		if (f[i][0] != 'a') dp[i][0]++;
	}

	FOR(i, 1, N) {
		FOR(j, 1, N) {
			dp[i][j] = min(dp[i][j-1], dp[i-1][j]);
			if (f[i][j] != 'a')
				dp[i][j]++;
			if (dp[i][j] <= K) {
				chmax(msum, i + j);
			}
		}
	}

	string ans;
	if (K == 0) ans.push_back(f[0][0]);
	REP(i, msum) ans.push_back('a');

	vector<vector<pair<int, int>>> q(2);
	auto used = make_v<bool>(N, N);
	int cnt = 0;
	bool current = 0;
	REP(i, N) {
		REP(j, N) {
			if (dp[i][j] <= K and f[i][j] == 'a') {
				cnt++;
			}
			if (dp[i][j] == K and msum >= (i + j)) {
				q[current].push_back({i, j});
				used[i][j] = true;
			}
		}
	}
	dp.clear();
	REP(i, cnt) ans.push_back('a');
	if (K == 0) q[current].push_back({0, 0});
	while (true) {
		char mc = 'z' + 1;
		REP(i, q[current].size()) {
			auto p = q[current][i];
			if (p.first + 1 < N and not used[p.first + 1][p.second])
				chmin(mc, f[p.first + 1][p.second]);
			if (p.second + 1 < N and not used[p.first][p.second + 1])
				chmin(mc, f[p.first][p.second + 1]);
		}
		if (mc == 'z' + 1) break;
		ans.push_back(mc);
		bool next = not current;
		REP(i, q[current].size()) {
			auto p = q[current][i];
			if (p.first + 1 < N and not used[p.first + 1][p.second] and f[p.first + 1][p.second] == mc) {
				used[p.first + 1, p.second];
				q[next].push_back({p.first + 1, p.second});
			}
			if (p.second + 1 < N and not used[p.first][p.second + 1] and f[p.first][p.second + 1] == mc) {
				used[p.first, p.second + 1];
				q[next].push_back({p.first, p.second + 1});
			}
		}
		q[current].clear();
		current = not current;
	}
	out(ans);

    return 0;
}


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

using ull = unsigned long long;
using ll = long long;

#define REP(i, n) for (int i = 0; i < n; i++)
#define REPR(i, n) for (int i = n; i >= 0; i--)
#define FOR(i, m, n) for (int i = m; i < n; i++)
#define pb push_back
#define fill(x, y) memset(x, y, sizeof(x))
#define even(x) x % 2 == 0
#define odd(x) x % 2 != 0
#define all(x) x.begin(), x.end()
#define pcnt __builtin_popcount
#define buli(x) __builtin_popcountll(x)
#define F first
#define S second
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());
#define IN1(x) ll x; cin >> x;

// these functions return the position of result of Binary Search.
#define LB(s, t, x) (int) (lower_bound(s, t, x) - s)
#define UB(s, t, x) (int) (upper_bound(s, t, x) - s)

ll qp(ll a, ll b, int mo) { ll ans = 1; do { if (b & 1) ans = 1ll * ans * a % mo; a = 1ll * a * a % mo; } while (b >>= 1); return ans; }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b) { ll temp = gcd(a, b); return temp ? (a / temp * b) : 0; }
int mDays[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
int dx8[] = { 1, -1, 0, 0, 1, 1, -1, -1 }, dy8[] = { 0, 0, -1, 1, -1, 1, -1, 1 };

template <typename T>
vector<T> make_v(size_t a) { return vector<T>(a); }
template <typename T, typename... Ts>
auto make_v(size_t a, size_t b, Ts... ts) { return vector<decltype(make_v<T>(b, ts...))>(a, make_v<T>(b, ts...)); }
template <typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type
fill_v(T &t, const V &v) { t = v; }
template <typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type
fill_v(T &t, const V &v) { for (auto &e : t) fill_v(e, v); }
// auto dp = make_v<int>(4, h, w);
// fill_v(dp, 0);

const ll INF_LL = (1ll << 60);
const int INF_INT = (int)1e9;
const ll MOD_CONST = (ll)(1e9 + 7);

template <typename T>
vector<T> pows(int b, int n) {
    vector<T> ret;
    T x = 1;
    while (ret.size() < n) {
        ret.push_back(x);
        x *= b;
    }
    return ret;
}
// find string "from" in "str", and replace them to "to"
void strReplace(std::string& str, const std::string& from, const std::string& to) {
	std::string::size_type pos = 0;
	while (pos = str.find(from, pos), pos != std::string::npos) {
		str.replace(pos, from.length(), to);
		pos += to.length();
	}
}
template <class T>
bool chmax(T &a, const T &b) { if (a < b) { a = b; return 1; } return 0; }
template <class T>
bool chmin(T &a, const T &b) { if (b < a) { a = b; return 1; } return 0; }

inline tuple<ll, ll> rotate45(tuple<ll, ll> point) { ll x = get<0>(point), y = get<1>(point); return tuple<ll, ll>(x + y, x - y); }
inline bool rangeCheck2D(int nx, int ny, int Width, int Height) { return nx >= 0 and nx < Width and ny >= 0 and ny < Height; }

template <typename T>
vector<T> INPA(ll n) {
	vector<T> x;
	REP(i, n) {
		T tmp; cin >> tmp;
		x.push_back(tmp);
	}
	return move(x);
}
template <typename T>
void out(T o) { cout << o << endl; }
template <typename T>
void out(vector<T> &out) { REP(i, (int)out.size()) { cout << out[i]; if (i == (int)out.size() - 1) cout << endl; else cout << " "; } }
template <typename T>
void out(vector<vector<T>> o) { REP(i, o.size()) out(o[i]); }
void YesNo(bool f) { cout << (f?"Yes":"No") << endl; }
void YESNO(bool f) { cout << (f?"YES":"NO") << endl; }

// don't use " for (auto v : V) "
// use " for (const auto& e : V), for (auto&& e : V) "

// min({1, 2, 0}) = 0
// max({1, 2, 0}) = 2

int main(void)
{
    cin.tie(0); ios::sync_with_stdio(0); cout << fixed << setprecision(20);

	IN1(N); IN1(K);

	vector<string> f(N);
	REP(i, N) cin >> f[i];

	auto dp = make_v<ll>(N, N);
	if (f[0][0] != 'a') dp[0][0]++;
	FOR(i, 1, N) {
		dp[0][i] = dp[0][i-1];
		if (f[0][i] != 'a') dp[0][i]++;
	}
	FOR(i, 1, N) {
		dp[i][0] = dp[i-1][0];
		if (f[i][0] != 'a') dp[i][0]++;
	}

	int msum = 0;
	FOR(i, 1, N) {
		FOR(j, 1, N) {
			dp[i][j] = min(dp[i][j-1], dp[i-1][j]);
			if (f[i][j] != 'a')
				dp[i][j]++;
			if (dp[i][j] <= K) {
				chmax(msum, i + j);
			}
		}
	}

	string ans;
	REP(i, msum) ans.push_back('a');

	priority_queue<
		pair<char, pair<int, int>>,
		vector<pair<char, pair<int, int>>>,
		greater<>
	> q;
	REP(i, N) {
		REP(j, N) {
			if (dp[i][j] <= K and msum == (i + j)) {
				q.push({'a', {i, j}});
			}
		}
	}
	while (true) {
		auto ff = q.top(); q.pop();
		char c = ff.first;
		ans.push_back(c);
		queue<pair<int, int>> next;
		next.push(ff.second);
		while (q.size()) {
			if (c == q.top().first) {
				next.push(q.top().second);
			}
			q.pop();
		}
		while (next.size()) {
			auto p = next.front(); next.pop();
			if (p.first + 1 < N)
				q.push({f[p.first + 1][p.second], {p.first + 1, p.second}});
			if (p.second + 1 < N)
				q.push({f[p.first][p.second + 1], {p.first, p.second + 1}});
		}
		if (q.size() == 0) break;
	}
	out(ans);

    return 0;
}