import java.io.IOException;
import java.io.InputStream;
import java.util.InputMismatchException;
import java.util.TreeMap;

/*

5 2 4
4 0
1 2
2 1
0 2
1 3

3 2 4
1 2
1 3
2 2

 */

public class d {

	static int numDroids;
	static int numDetails;
	static int maxShots;
	static int[][] droids;
	static TreeMap<Integer, Integer>[] map;

	@SuppressWarnings("unchecked")
	public static void main(String[] args)
	{
		FastScanner in = new FastScanner();

		numDroids = in.nextInt();
		numDetails = in.nextInt();
		maxShots = in.nextInt();

		droids = new int[numDroids][numDetails];

		for(int currDroid = 0; currDroid < numDroids; ++currDroid)
		{
			for(int currDetail = 0; currDetail < numDetails; ++currDetail)
			{
				droids[currDroid][currDetail] = in.nextInt();
			}
		}

		int maxLen = 0;
		int[] bestShots = new int[numDetails];

		int start = 0;
		int end = 0;

		map = new TreeMap[numDetails];
		for(int currDetail = 0; currDetail < numDetails; ++currDetail)
		{
			map[currDetail] = new TreeMap<Integer, Integer>();
			map[currDetail].put(droids[end][currDetail], 1);
		}

		while(end < numDroids)
		{
			//System.out.println(start +" " + end +" " +maxLen);
			int[] numShots = new int[numDetails];
			int sum = 0;
			for(int currDetail = 0; currDetail < numDetails; ++currDetail)
			{
				numShots[currDetail] = map[currDetail].lastKey();
				sum += numShots[currDetail];
			}

			if(sum > maxShots)
			{
				for(int currDetail = 0; currDetail < numDetails; ++currDetail)
				{
					if(map[currDetail].get(droids[start][currDetail]) == 1)
					{
						map[currDetail].remove(droids[start][currDetail]);
					}
					else
					{
						map[currDetail].put(droids[start][currDetail], map[currDetail].get(droids[start][currDetail]) - 1);
					}
				}

				++start;
			}

			if(sum <= maxShots || end < start)
			{
				if(end - start + 1 > maxLen)
				{
					maxLen = end - start +1;
					bestShots = numShots;
				}

				++end;

				if(end == numDroids)
					break;

				for(int currDetail = 0; currDetail < numDetails; ++currDetail)
				{
					int count = map[currDetail].containsKey(droids[end][currDetail]) ? map[currDetail].get(droids[end][currDetail]) : 0;
					map[currDetail].put(droids[end][currDetail], count +1);

				}
			}
		}

		for(int shot: bestShots)
		{
			System.out.print(shot +" ");
		}
		System.out.println();
	}

	static class FastScanner{
		   private InputStream stream;
		   private byte[] buf = new byte[1024];
		   private int curChar;
		   private int numChars;

		   public FastScanner()
		   {
		      stream = System.in;
		   }

		   int read()
		   {
		      if (numChars == -1)
		         throw new InputMismatchException();
		      if (curChar >= numChars){
		         curChar = 0;
		         try{
		            numChars = stream.read(buf);
		         } catch (IOException e) {
		            throw new InputMismatchException();
		         }
		         if (numChars <= 0)
		            return -1;
		      }
		      return buf[curChar++];
		   }

		   boolean isSpaceChar(int c)
		   {
		      return c==' '||c=='\n'||c=='\r'||c=='\t'||c==-1;
		   }

		   boolean isEndline(int c)
		   {
		      return c=='\n'||c=='\r'||c==-1;
		   }

		   int nextInt()
		   {
		      return Integer.parseInt(next());
		   }

		   long nextLong()
		   {
		      return Long.parseLong(next());
		   }

		   double nextDouble()
		   {
		      return Double.parseDouble(next());
		   }

		   String next(){
		      int c = read();
		      while (isSpaceChar(c))
		         c = read();
		      StringBuilder res = new StringBuilder();
		      do{
		         res.appendCodePoint(c);
		         c = read();
		      }while(!isSpaceChar(c));
		      return res.toString();
		   }

		   String nextLine(){
		      int c = read();
		      while (isEndline(c))
		         c = read();
		      StringBuilder res = new StringBuilder();
		      do{
		         res.appendCodePoint(c);
		         c = read();
		      }while(!isEndline(c));
		      return res.toString();
		   }
		}
}


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

public class Main {

    static BufferedReader in;
    static StringTokenizer stk;
    static boolean[] isPrime = new boolean[5000];

    public static void main(String[] args) throws Exception {

            in = new BufferedReader(new InputStreamReader(System.in));

        stk = new StringTokenizer(in.readLine());
        // Start of User Code

        int n, m;
        long k;
        n = ni();
        m = ni();
        k = nl();

        long[][] droid = new long[n][m];

        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                droid[i][j] = nl();
            }
        }

        TreeMap<Long, Long>[] maps = new TreeMap[m];
        for(int i = 0; i < m; i++){
            maps[i] = new TreeMap<Long, Long>();
            maps[i].put(-droid[0][i], 1L);
        }

        long len = 0;
        long[] solution = new long[m];

        int st = 0;
        int en = 0;

        while(true){
            long t = 0;
            for(int i = 0; i< m; i++){
                t += -maps[i].firstKey();
            }
            if(t <= k){
                if(en - st + 1 > len) {
                    len = en - st + 1;
                    for (int i = 0; i < m; i++) {
                        solution[i] = -maps[i].firstKey();
                    }
                }
            }

            if(t <= k){
                if( en < n - 1){
                    en++;
                    for(int i = 0; i<m; i++){
                        long key = -droid[en][i];
                        if(!maps[i].containsKey(key)) maps[i].put(key, 0L);
                        maps[i].put(key, maps[i].get(key) + 1);
                    }
                }else{
                    break;
                }
            }else{
                if( st < n){
                    if(st <= en) {
                        for (int i = 0; i < m; i++) {
                            long key = -droid[st][i];
                            if (maps[i].get(key) == 1) {
                                maps[i].remove(key);
                            } else {
                                maps[i].put(key, maps[i].get(key) - 1);
                            }
                        }
                        st++;
                    }

                    if(st > en && st < n){
                        en = st;
                        for(int i = 0; i<m; i++){
                            long key = -droid[en][i];
                            if(!maps[i].containsKey(key)) maps[i].put(key, 0L);
                            maps[i].put(key, maps[i].get(key) + 1);
                        }
                    }

                }else{
                    break;
                }
            }
        }

        for(int i = 0; i < m; i++){
            if(i > 0)
                System.out.print(" ");
            System.out.print(solution[i]);

        }
        System.out.println();

        // End of User Code
        in.close();
    }

    static long modPow(long n, long pow, long mod) {
        return BigInteger.valueOf(n).modPow(BigInteger.valueOf(pow), BigInteger.valueOf(mod)).longValue();
    }

    static long modInv(long n, long mod, boolean isPrimeModuli) {
        if (isPrimeModuli) {
            return modPow(n, mod - 2, mod);
        }
        return BigInteger.valueOf(n).modInverse(BigInteger.valueOf(mod)).longValue();
    }
    // calc factorials
    static long[] fact;

    static void calcFactorials(int n) {
        fact = new long[n + 1];
        fact[0] = 1;
        for (int i = 1; i <= n; i++) {
            fact[i] = fact[i - 1] * i;
        }
    }

    static void calcFactorialsModM(int n, long M) {
        fact = new long[n + 1];
        fact[0] = 1;
        for (int i = 1; i <= n; i++) {
            fact[i] = fact[i - 1] * i;
            fact[i] %= M;
        }
    }

    static long ncr(int n, int r) {
        return fact[n] / (fact[n - r] * fact[r]);
    }

    static long ncrModM(int n, int r, long MOD, boolean isPrimeModuli) {
        return fact[n] * modInv(fact[n - r], MOD, isPrimeModuli) * modInv(fact[r], MOD, isPrimeModuli);
    }

    static long toL(String s) {
        return Long.parseLong(s);
    }

    static long toL(BigInteger n) {
        return n.longValue();
    }

    static int toI(String s) {
        return Integer.parseInt(s);
    }

    static double toD(String s) {
        return Double.parseDouble(s);
    }

    static String proc() {
        return null;
    }

    static void printf(String format, Object... args) {
        System.out.printf(format, args);
    }

    static int ni() throws Exception {
        while (!stk.hasMoreTokens()) {
            stk = new StringTokenizer(in.readLine());
        }
        return Integer.parseInt(stk.nextToken());
    }

    static long nl() throws Exception {
        while (!stk.hasMoreTokens()) {
            stk = new StringTokenizer(in.readLine());
        }
        return Long.parseLong(stk.nextToken());
    }

    static double nd() throws Exception {
        while (!stk.hasMoreTokens()) {
            stk = new StringTokenizer(in.readLine());
        }
        return Double.parseDouble(stk.nextToken());
    }

    static String ns() throws Exception {
        while (!stk.hasMoreTokens()) {
            stk = new StringTokenizer(in.readLine());
        }
        return stk.nextToken();
    }

    static int min(int a, int b) {
        return a < b ? a : b;
    }

    static int max(int a, int b) {
        return a > b ? a : b;
    }

    static long min(long a, long b) {
        return a < b ? a : b;
    }

    static long max(long a, long b) {
        return a > b ? a : b;
    }

    static int gcd(int a, int b) {
        if (b == 0) {
            return a;
        }
        return gcd(b, a % b);
    }

    static long gcd(long a, long b) {
        if (b == 0) {
            return a;
        }
        return gcd(b, a % b);
    }
}


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

public class Main {

    static BufferedReader in;
    static StringTokenizer stk;
    static boolean[] isPrime = new boolean[5000];

    public static void main(String[] args) throws Exception {

            in = new BufferedReader(new InputStreamReader(System.in));

        stk = new StringTokenizer(in.readLine());
        // Start of User Code

        int n, m;
        long k;
        n = ni();
        m = ni();
        k = nl();

        long[][] droid = new long[n][m];

        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                droid[i][j] = nl();
            }
        }

        TreeMap<Long, Long>[] maps = new TreeMap[m];
        for(int i = 0; i < m; i++){
            maps[i] = new TreeMap<Long, Long>();
            maps[i].put(-droid[0][i], 1L);
        }

        long len = 0;
        long[] solution = new long[m];

        int st = 0;
        int en = 0;

        while(true){

            long t = 0;
            try {
                for (int i = 0; i < m; i++) {
                    t += -maps[i].firstKey();
                }

                if (t <= k) {
                    if (en - st + 1 > len) {
                        len = en - st + 1;
                        for (int i = 0; i < m; i++) {
                            solution[i] = -maps[i].firstKey();
                        }
                    }
                }
            }catch (Exception e){

            }

            if(t <= k){
                if( en < n - 1){
                    en++;
                    for(int i = 0; i<m; i++){
                        long key = -droid[en][i];
                        if(!maps[i].containsKey(key)) maps[i].put(key, 0L);
                        maps[i].put(key, maps[i].get(key) + 1);
                    }
                }else{
                    break;
                }
            }else{
                if( st < n){
                    if(st <= en) {
                        for (int i = 0; i < m; i++) {
                            long key = -droid[st][i];
                            if (maps[i].get(key) == 1) {
                                maps[i].remove(key);
                            } else {
                                maps[i].put(key, maps[i].get(key) - 1);
                            }
                        }
                        st++;
                    }

                    if(st > en && st < n){
                        en = st;
                        for(int i = 0; i<m; i++){
                            long key = -droid[en][i];
                            if(!maps[i].containsKey(key)) maps[i].put(key, 0L);
                            maps[i].put(key, maps[i].get(key) + 1);
                        }
                    }

                }else{
                    break;
                }
            }
        }

        for(int i = 0; i < m; i++){
            if(i > 0)
                System.out.print(" ");
            System.out.print(solution[i]);

        }
        System.out.println();

        // End of User Code
        in.close();
    }

    static long modPow(long n, long pow, long mod) {
        return BigInteger.valueOf(n).modPow(BigInteger.valueOf(pow), BigInteger.valueOf(mod)).longValue();
    }

    static long modInv(long n, long mod, boolean isPrimeModuli) {
        if (isPrimeModuli) {
            return modPow(n, mod - 2, mod);
        }
        return BigInteger.valueOf(n).modInverse(BigInteger.valueOf(mod)).longValue();
    }
    // calc factorials
    static long[] fact;

    static void calcFactorials(int n) {
        fact = new long[n + 1];
        fact[0] = 1;
        for (int i = 1; i <= n; i++) {
            fact[i] = fact[i - 1] * i;
        }
    }

    static void calcFactorialsModM(int n, long M) {
        fact = new long[n + 1];
        fact[0] = 1;
        for (int i = 1; i <= n; i++) {
            fact[i] = fact[i - 1] * i;
            fact[i] %= M;
        }
    }

    static long ncr(int n, int r) {
        return fact[n] / (fact[n - r] * fact[r]);
    }

    static long ncrModM(int n, int r, long MOD, boolean isPrimeModuli) {
        return fact[n] * modInv(fact[n - r], MOD, isPrimeModuli) * modInv(fact[r], MOD, isPrimeModuli);
    }

    static long toL(String s) {
        return Long.parseLong(s);
    }

    static long toL(BigInteger n) {
        return n.longValue();
    }

    static int toI(String s) {
        return Integer.parseInt(s);
    }

    static double toD(String s) {
        return Double.parseDouble(s);
    }

    static String proc() {
        return null;
    }

    static void printf(String format, Object... args) {
        System.out.printf(format, args);
    }

    static int ni() throws Exception {
        while (!stk.hasMoreTokens()) {
            stk = new StringTokenizer(in.readLine());
        }
        return Integer.parseInt(stk.nextToken());
    }

    static long nl() throws Exception {
        while (!stk.hasMoreTokens()) {
            stk = new StringTokenizer(in.readLine());
        }
        return Long.parseLong(stk.nextToken());
    }

    static double nd() throws Exception {
        while (!stk.hasMoreTokens()) {
            stk = new StringTokenizer(in.readLine());
        }
        return Double.parseDouble(stk.nextToken());
    }

    static String ns() throws Exception {
        while (!stk.hasMoreTokens()) {
            stk = new StringTokenizer(in.readLine());
        }
        return stk.nextToken();
    }

    static int min(int a, int b) {
        return a < b ? a : b;
    }

    static int max(int a, int b) {
        return a > b ? a : b;
    }

    static long min(long a, long b) {
        return a < b ? a : b;
    }

    static long max(long a, long b) {
        return a > b ? a : b;
    }

    static int gcd(int a, int b) {
        if (b == 0) {
            return a;
        }
        return gcd(b, a % b);
    }

    static long gcd(long a, long b) {
        if (b == 0) {
            return a;
        }
        return gcd(b, a % b);
    }
}


import java.io.IOException;
import java.util.InputMismatchException;
import java.util.Comparator;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.TreeSet;
import java.io.InputStream;

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

class TaskD {
    int N;
    int M;
    int K;
    int[][] A;

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        N = in.nextInt();
        M = in.nextInt();
        K = in.nextInt();
        A = new int[N][M];
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                A[i][j] = in.nextInt();
            }
        }

        TreeSet<Integer>[] S = new TreeSet[M];
        for (int j = 0; j < M; j++) {
            MyComparator comp = new MyComparator(j);
            S[j] = new TreeSet<Integer>(comp);
        }

        int k = 0;
        int pi = -1;
        int pj = -2;
        int len = 0;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                S[j].add(i);
            }
            while (k <= i && calcSum(S) > K) {
                for (int j = 0; j < M; j++) {
                    S[j].remove(k);
                }
                k++;
            }
            if (i - k + 1 > len) {
                len = i - k + 1;
                pi = k;
                pj = i;
            }
        }

        for (int j = 0; j < M; j++) {
            int max = 0;
            for (int i = pi; i <= pj; i++) {
                max = Math.max(max, A[i][j]);
            }
            if (j > 0) {
                out.print(' ');
            }
            out.print(max);
        }
        out.println();
    }

    private int calcSum(TreeSet<Integer>[] s) {
        if (s[0].isEmpty()) {
            return 0;
        }
        int ret = 0;
        for (int j = 0; j < M; j++) {
            ret += A[s[j].first()][j];
        }
        return ret;
    }

    private class MyComparator implements Comparator<Integer> {
        private int col;

        private MyComparator(int col) {
            this.col = col;
        }

        public int compare(Integer o1, Integer o2) {
            if (A[o2][col] != A[o1][col]) {
                return A[o2][col] - A[o1][col];
            }
            return o1.compareTo(o2);
        }
    }
}

class InputReader {
    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;

    public InputReader(InputStream stream) {
        this.stream = stream;
    }

    public int read() {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars) {
            curChar = 0;
            try {
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }

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

    public String nextString() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        StringBuffer res = new StringBuffer();
        do {
            res.appendCodePoint(c);
            c = read();
        } while (!isSpaceChar(c));

        return res.toString();
    }

    private boolean isSpaceChar(int c) {
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

}


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

public class Main {

    public static void main(String[] args) throws Exception {
        new Main().solve();
    }
    void solve() throws Exception {
        FastScanner in = new FastScanner(System.in);

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

        ArrayDeque<Integer>[] Q = new ArrayDeque[m];
        for (int i = 0; i < Q.length; i++) {
            Q[i] = new ArrayDeque<Integer>();
        }

        int max = 0;
        int l = 0;
        String ret = "0";
        for (int jj = 1; jj < m; jj++) {
            ret += " 0";
        }
        for (int i = 0; i < n; i++) {
            for (int jj = 0; jj < m; jj++) {
                while (Q[jj].size() > 0 && a[Q[jj].getLast()][jj] <= a[i][jj]) {
                    Q[jj].removeLast();
                }
                Q[jj].addLast(i);
            }
            while (true) {
                long cnt = 0;
                for (int jj = 0; jj < m; jj++) {
                    cnt += a[Q[jj].getFirst()][jj];
                }
                if (cnt <= k) {
                    if (max < i - l + 1) {
                        max = i - l + 1;
                        ret = "" + a[Q[0].getFirst()][0];
                        for (int jj = 1; jj < m; jj++) {
                            ret += " " + a[Q[jj].getFirst()][jj];
                        }
                    }
                    break;
                } else if (l < i) {
                    l++;
                    for (int jj = 0; jj < m; jj++) {
                        if (Q[jj].getFirst() == l - 1) {
                            Q[jj].removeFirst();
                        }
                    }
                } else {
                    break;
                }
            }
        }
        System.out.println(ret);
    }
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    class FastScanner {

        private InputStream _stream;
        private byte[] _buf = new byte[1024];
        private int _curChar;
        private int _numChars;
        private StringBuilder _sb = new StringBuilder();

        FastScanner(InputStream stream) {
            this._stream = stream;
        }

        public int read() {
            if (_numChars == -1) throw new InputMismatchException();
            if (_curChar >= _numChars) {
                _curChar = 0;
                try {
                    _numChars = _stream.read(_buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (_numChars <= 0) return -1;
            }
            return _buf[_curChar++];
        }

        public String next() {
            int c = read();
            while (isWhitespace(c)) {
                c = read();
            }
            _sb.setLength(0);
            do {
                _sb.appendCodePoint(c);
                c = read();
            } while (!isWhitespace(c));
            return _sb.toString();
        }

        public int nextInt() {
            return (int) nextLong();
        }
        public long nextLong() {
            int c = read();
            while (isWhitespace(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9') throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isWhitespace(c));
            return res * sgn;
        }

        public boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }
    }
}
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//


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

public class Main {

    public static void main(String[] args) throws Exception {
        new Main().solve();
    }
    void solve() throws Exception {
        FastScanner in = new FastScanner(System.in);

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

        ArrayDeque<Integer>[] Q = new ArrayDeque[m];
        for (int i = 0; i < Q.length; i++) {
            Q[i] = new ArrayDeque<Integer>();
        }

        int max = 0;
        int l = 0;
        String ret = "";
        for (int i = 0; i < n; i++) {
            for (int jj = 0; jj < m; jj++) {
                while (Q[jj].size() > 0 && a[Q[jj].getLast()][jj] <= a[i][jj]) {
                    Q[jj].removeLast();
                }
                Q[jj].addLast(i);
            }
            while (true) {
                long cnt = 0;
                for (int jj = 0; jj < m; jj++) {
                    cnt += a[Q[jj].getFirst()][jj];
                }
                if (cnt <= k) {
                    if (max < i - l + 1) {
                        max = i - l + 1;
                        ret = "" + a[Q[0].getFirst()][0];
                        for (int jj = 1; jj < m; jj++) {
                            ret += " " + a[Q[jj].getFirst()][jj];
                        }
                    }
                    break;
                } else if (l < i) {
                    l++;
                    for (int jj = 0; jj < m; jj++) {
                        if (Q[jj].getFirst() == l - 1) {
                            Q[jj].removeFirst();
                        }
                    }
                } else {
                    break;
                }
            }
        }
        System.out.println(ret);
    }
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    class FastScanner {

        private InputStream _stream;
        private byte[] _buf = new byte[1024];
        private int _curChar;
        private int _numChars;
        private StringBuilder _sb = new StringBuilder();

        FastScanner(InputStream stream) {
            this._stream = stream;
        }

        public int read() {
            if (_numChars == -1) throw new InputMismatchException();
            if (_curChar >= _numChars) {
                _curChar = 0;
                try {
                    _numChars = _stream.read(_buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (_numChars <= 0) return -1;
            }
            return _buf[_curChar++];
        }

        public String next() {
            int c = read();
            while (isWhitespace(c)) {
                c = read();
            }
            _sb.setLength(0);
            do {
                _sb.appendCodePoint(c);
                c = read();
            } while (!isWhitespace(c));
            return _sb.toString();
        }

        public int nextInt() {
            return (int) nextLong();
        }
        public long nextLong() {
            int c = read();
            while (isWhitespace(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9') throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isWhitespace(c));
            return res * sgn;
        }

        public boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }
    }
}
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//


import java.util.Arrays;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.util.List;
import java.math.BigInteger;
import java.io.PrintStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Comparator;
import java.io.IOException;
import java.util.StringTokenizer;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author shu_mj @ http://shu-mj.com
 */
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);
		TaskD solver = new TaskD();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskD {
    Scanner in;
    PrintWriter out;

    public void solve(int testNumber, Scanner in, PrintWriter out) {
        this.in = in;
        this.out = out;
        run();
    }

    void run() {
        int n = in.nextInt();
        int m = in.nextInt();
        int k = in.nextInt();
        int[][] mat = new int[m][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                mat[j][i] = -in.nextInt();
            }
        }
        RMQ[] ms = new RMQ[m];
        for (int i = 0; i < m; i++) {
            ms[i] = new RMQ(mat[i]);
        }
        int[] res = new int[m];
        int s = 0, t = 0;
        int[] is = new int[m];
        int max = 0;
        while (t < n) {
            while (t < n) {
                t++;
                int[] js = new int[m];
                for (int i = 0; i < m; i++) {
                    js[i] = -ms[i].queryValue(s, t);
                }
                if (Algo.sum(js) > k) {
                    t--;
                    break;
                }
                is = js;
            }
            if (s == t) {
                t++;
                s++;
                continue;
            }
            if (t - s > max) {
                max = t - s;
                res = is.clone();
            }
            s++;
        }
        for (int i : res) {
            out.print(i + " ");
        }
    }
}

class Scanner {
    BufferedReader br;
    StringTokenizer st;

    public Scanner(InputStream in) {
        br = new BufferedReader(new InputStreamReader(in));
        eat("");
    }

    private void eat(String s) {
        st = new StringTokenizer(s);
    }

    public String nextLine() {
        try {
            return br.readLine();
        } catch (IOException e) {
            return null;
        }
    }

    public boolean hasNext() {
        while (!st.hasMoreTokens()) {
            String s = nextLine();
            if (s == null)
                return false;
            eat(s);
        }
        return true;
    }

    public String next() {
        hasNext();
        return st.nextToken();
    }

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

}

class RMQ {
    public int[] vs;
    int[][] min;

    public RMQ(int[] vs) {
        int n = vs.length, m = Algo.log2(n) + 1;
        this.vs = vs;
        min = new int[m][n];
        for (int i = 0; i < n; i++)
            min[0][i] = i;
        for (int i = 1, k = 1; i < m; i++, k <<= 1) {
            for (int j = 0; j + k < n; j++) {
                min[i][j] = vs[min[i - 1][j]] <= vs[min[i - 1][j + k]] ? min[i - 1][j]
                        : min[i - 1][j + k];
            }
        }
    }

    // return index
    public int query(int from, int to) {
        int k = Algo.log2(to - from);
        return vs[min[k][from]] <= vs[min[k][to - (1 << k)]] ? min[k][from]
                : min[k][to - (1 << k)];
    }

    public int queryValue(int from, int to) {
        return vs[query(from, to)];
    }

}

class Algo {

    public static long sum(int[] is) {
        long res = 0;
        for (int i = 0; i < is.length; i++) {
            res += is[i];
        }
        return res;
    }

    public static int log2(int b) {
        return 31 - Integer.numberOfLeadingZeros(b);
    }

}


/*
 * will that bs work ?
 */

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main
{

	public static void main(String[] args) throws IOException
	{
		Main main = new Main();
		main.read();
	}

	/* IO */
	private StringBuilder ans;
	private BufferedReader in;
	private StringTokenizer tok;

	/* fields */
	private int nDroids;
	private int nTypes;
	private int nMaxShots;
	private int[][] type;
	private Node[] roots;

	private void read() throws IOException
	{
		// streams
		boolean file = false;
		if (file)
			in = new BufferedReader(new FileReader("input.txt"));
		else
			in = new BufferedReader(new InputStreamReader(System.in));
		ans = new StringBuilder();

		// read input
		tok = new StringTokenizer(in.readLine());
		nDroids = Integer.parseInt(tok.nextToken());
		nTypes = Integer.parseInt(tok.nextToken());
		nMaxShots = Integer.parseInt(tok.nextToken());
		type = new int[nDroids][nTypes];
		for (int i = 0; i < nDroids; i++)
		{
			tok = new StringTokenizer(in.readLine());
			for (int j = 0; j < nTypes; j++)
				type[i][j] = Integer.parseInt(tok.nextToken());
		}

		// solve
		System.out.println(solve());
	}

	private String solve()
	{
		makeSegmentTrees();

		// bs for the answer
		int start = 0;
		int end = nDroids + 1;

		while (start < end)
		{
			int mid = (start + end + 1) / 2;
			Status statusMid = isValid(mid);
			if (!statusMid.valid)
				end = mid -1;
			else
				start = mid;

		}

		Status Final = isValid(start);
		StringBuilder strb = new StringBuilder();
		for (int i = 0; i < nTypes; i++)
			strb.append(Final.count[i] + " ");
		return strb.toString().trim();
	}

	private Status isValid(int segmentLength)
	{
		Status status = new Status();
		status.valid = false;
		status.count = new int[5];

		// keep checking if we can get that segment
		for (int start = 0; start + segmentLength - 1 < nDroids; start++)
		{
			// find max number of details in droids
			int max[] = new int[nTypes];
			Arrays.fill(max, 0);
			int end = start + segmentLength - 1;
			for (int i = 0; i < nTypes; i++)
				max[i] = getMax(start, end, roots[i]);

			// find their sum
			int sum = 0;
			for (int i = 0; i < nTypes; i++)
				sum += max[i];
			if (sum <= nMaxShots)
			{
				status.valid = true;
				status.count = new int[nTypes];
				for (int i = 0; i < nTypes; i++)
					status.count[i] = max[i];
				status.start = start;
				status.end = end;
				return status;
			}
		}

		return status;
	}

	private void makeSegmentTrees()
	{
		roots = new Node[nTypes];
		for (int i = 0; i < nTypes; i++)
			roots[i] = makeNode(0, nDroids - 1, i);
	}

	private Node makeNode(int l, int r, int typeIdx)
	{
		// base case
		if (l == r)
		{
			Node leaf = new Node();
			leaf.l = l;
			leaf.r = r;
			leaf.val = type[l][typeIdx];
			return leaf;
		}

		// make left and right
		int mid = (l + r) / 2;
		Node left = makeNode(l, mid, typeIdx);
		Node right = makeNode(mid + 1, r, typeIdx);
		Node node = new Node();
		node.l = l;
		node.r = r;
		node.right = right;
		node.left = left;
		node.val = Math.max(right.val, left.val);
		return node;
	}

	int getMax(int l, int r, Node node)
	{
		if (node.r < l || node.l > r)
			return 0;
		else if (node.l >= l && node.r <= r)
			return node.val;
		else
			return Math.max(getMax(l, r, node.left), getMax(l, r, node.right));
	}
}

class Node
{
	int l, r;
	Node left, right;
	int val;

}

class Status
{
	boolean valid;
	int[] count;
	int start;
	int end;
}


/*
 * Ossama's beloved segment tree failed me :(
 * Will you fail me too, Java's pq ?
 */

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.invoke.ConstantCallSite;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveAction;

public class Main
{

	public static void main(String[] args) throws IOException
	{
		Main main = new Main();
		main.read();
	}

	/* IO */
	private StringBuilder ans;
	private BufferedReader in;
	private StringTokenizer tok;

	/* fields */
	private int nDroids;
	private int nTypes;
	private int nMaxShots;
	private int[][] type;
	private Node[] roots;

	private void read() throws IOException
	{

		// streams
		boolean file = false;
		if (file)
			in = new BufferedReader(new FileReader("input.txt"));
		else
			in = new BufferedReader(new InputStreamReader(System.in));
		ans = new StringBuilder();

		// read input
		tok = new StringTokenizer(in.readLine());
		nDroids = Integer.parseInt(tok.nextToken());
		nTypes = Integer.parseInt(tok.nextToken());
		nMaxShots = Integer.parseInt(tok.nextToken());
		type = new int[nDroids][nTypes];
		for (int i = 0; i < nDroids; i++)
		{
			tok = new StringTokenizer(in.readLine());
			for (int j = 0; j < nTypes; j++)
				type[i][j] = Integer.parseInt(tok.nextToken());
		}

		// solve
		System.out.println(solve());
	}

	private String solve()
	{
		// bs for the answer
		int start = 1;
		int end = nDroids;
		while (start <= end)
		{
			int mid = (start + end) / 2;
			Status statusMid = isValid(mid);
			Status statusNext = isValid(mid + 1);
			if (statusMid.valid && !statusNext.valid)
			{
				// return string
				StringBuilder strb = new StringBuilder();
				for (int i = 0; i < nTypes; i++)
					strb.append(statusMid.count[i] + " ");
				return strb.toString().trim();
			} else if (!statusMid.valid)
				end = mid - 1;
			else
				start = mid + 1;
		}

		// i failed :(
		StringBuilder strb = new StringBuilder();
		for (int i = 0; i < nTypes; i++)
			strb.append("0 ");
		return strb.toString().trim();
	}

	private Status isValid(int segmentLength)
	{
		// corner
		if (segmentLength > nDroids)
		{
			Status failed = new Status();
			failed.valid = false;
			return failed;
		}

		// a wild priority queue comes along to get min
		PriorityQueue<Integer> pq[] = new PriorityQueue[nTypes];
		for (int i = 0; i < nTypes; i++)
			pq[i] = new PriorityQueue<>(7, new Comparator<Integer>()
			{

				@Override
				public int compare(Integer o1, Integer o2)
				{
					return Integer.compare(o2, o1);
				}
			});
		for (int i = 0; i <= segmentLength - 1; i++)
			for (int j = 0; j < nTypes; j++)
				pq[j].add(type[i][j]);

		// keep checking if we can get that segment
		for (int start = 0; start + segmentLength - 1 < nDroids; start++)
		{
			// find max number of details in droids
			int max[] = new int[nTypes];
			Arrays.fill(max, Integer.MIN_VALUE);
			int end = start + segmentLength - 1;
			int sum = 0;
			for (int i = 0; i < nTypes; i++)
				max[i] = pq[i].peek();

			// find their sum
			for (int i = 0; i < nTypes; i++)
				sum += max[i];
			if (sum <= nMaxShots)
			{
				Status ok = new Status();
				ok.valid = true;
				ok.count = new int[nTypes];
				for (int i = 0; i < nTypes; i++)
					ok.count[i] = max[i];
				ok.start = start;
				ok.end = end;
				return ok;
			}

			// update pq
			if (start + segmentLength < nDroids)
				for (int i = 0; i < nTypes; i++)
				{
					pq[i].remove(type[start][i]);
					pq[i].add(type[start + segmentLength][i]);
				}

		}

		Status failed = new Status();
		failed.valid = false;
		return failed;
	}

	private void makeSegmentTrees()
	{
		roots = new Node[nTypes];
		for (int i = 0; i < nTypes; i++)
			roots[i] = makeNode(0, nDroids - 1, i);
	}

	private Node makeNode(int l, int r, int typeIdx)
	{
		// base case
		if (l == r)
		{
			Node leaf = new Node();
			leaf.l = l;
			leaf.r = r;
			leaf.val = type[l][typeIdx];
			return leaf;
		}

		// make left and right
		int mid = (l + r) / 2;
		Node left = makeNode(l, mid, typeIdx);
		Node right = makeNode(mid + 1, r, typeIdx);
		Node node = new Node();
		node.l = l;
		node.r = r;
		node.right = right;
		node.left = left;
		node.val = Math.max(right.val, left.val);
		return node;
	}

	int getMax(int l, int r, Node node)
	{
		if (node.r < l || node.l > r)
			return Integer.MIN_VALUE;
		else if (node.l >= l && node.r <= r)
			return node.val;
		else
			return Math.max(getMax(l, r, node.left), getMax(l, r, node.right));
	}
}

class Node
{
	int l, r;
	Node left, right;
	int val;

}

class Status
{
	boolean valid;
	int[] count;
	int start;
	int end;
}


/*
 * Ossama told me that it wasn't the segment tree that failed me, it was him
 */

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main
{

	public static void main(String[] args) throws IOException
	{
		Main main = new Main();
		main.read();
	}

	/* IO */
	private StringBuilder ans;
	private BufferedReader in;
	private StringTokenizer tok;

	/* fields */
	private int nDroids;
	private int nTypes;
	private int nMaxShots;
	private int[][] type;
	private Node[] roots;

	private void read() throws IOException
	{
		// streams
		boolean file = false;
		if (file)
			in = new BufferedReader(new FileReader("input.txt"));
		else
			in = new BufferedReader(new InputStreamReader(System.in));
		ans = new StringBuilder();

		// read input
		tok = new StringTokenizer(in.readLine());
		nDroids = Integer.parseInt(tok.nextToken());
		nTypes = Integer.parseInt(tok.nextToken());
		nMaxShots = Integer.parseInt(tok.nextToken());
		type = new int[nDroids][nTypes];
		for (int i = 0; i < nDroids; i++)
		{
			tok = new StringTokenizer(in.readLine());
			for (int j = 0; j < nTypes; j++)
				type[i][j] = Integer.parseInt(tok.nextToken());
		}

		// solve
		System.out.println(solve());
	}

	private String solve()
	{
		makeSegmentTrees();

		// bs for the answer
		int start = 0;
		int end = nDroids + 1;

		while (end - start > 1)
		{
			int mid = (start + end) / 2;
			Status statusMid = isValid(mid);
			if (!statusMid.valid)
				end = mid;
			else
				start = mid;

		}

		Status Final = isValid(start);
		StringBuilder strb = new StringBuilder();
		for (int i = 0; i < nTypes; i++)
			strb.append(Final.count[i] + " ");
		return strb.toString().trim();
	}

	private Status isValid(int segmentLength)
	{
		Status status = new Status();
		status.valid = false;
		status.count = new int[5];

		// keep checking if we can get that segment
		for (int start = 0; start + segmentLength - 1 < nDroids; start++)
		{
			// find max number of details in droids
			int max[] = new int[nTypes];
			Arrays.fill(max, 0);
			int end = start + segmentLength - 1;
			for (int i = 0; i < nTypes; i++)
				max[i] = getMax(start, end, roots[i]);

			// find their sum
			int sum = 0;
			for (int i = 0; i < nTypes; i++)
				sum += max[i];
			if (sum <= nMaxShots)
			{
				status.valid = true;
				status.count = new int[nTypes];
				for (int i = 0; i < nTypes; i++)
					status.count[i] = max[i];
				status.start = start;
				status.end = end;
				return status;
			}
		}

		return status;
	}

	private void makeSegmentTrees()
	{
		roots = new Node[nTypes];
		for (int i = 0; i < nTypes; i++)
			roots[i] = makeNode(0, nDroids - 1, i);
	}

	private Node makeNode(int l, int r, int typeIdx)
	{
		// base case
		if (l == r)
		{
			Node leaf = new Node();
			leaf.l = l;
			leaf.r = r;
			leaf.val = type[l][typeIdx];
			return leaf;
		}

		// make left and right
		int mid = (l + r) / 2;
		Node left = makeNode(l, mid, typeIdx);
		Node right = makeNode(mid + 1, r, typeIdx);
		Node node = new Node();
		node.l = l;
		node.r = r;
		node.right = right;
		node.left = left;
		node.val = Math.max(right.val, left.val);
		return node;
	}

	int getMax(int l, int r, Node node)
	{
		if (node.r < l || node.l > r)
			return 0;
		else if (node.l >= l && node.r <= r)
			return node.val;
		else
			return Math.max(getMax(l, r, node.left), getMax(l, r, node.right));
	}
}

class Node
{
	int l, r;
	Node left, right;
	int val;

}

class Status
{
	boolean valid;
	int[] count;
	int start;
	int end;
}


/*
 * Each segment tree coded in the universe brings warmth to Ahmed Ossama's cold heart
 */

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.invoke.ConstantCallSite;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveAction;

public class Main
{

	public static void main(String[] args) throws IOException
	{
		Main main = new Main();
		main.read();
	}

	/* IO */
	private StringBuilder ans;
	private BufferedReader in;
	private StringTokenizer tok;

	/* fields */
	private int nDroids;
	private int nTypes;
	private int nMaxShots;
	private int[][] type;
	private Node[] roots;

	private void read() throws IOException
	{
		// streams
		boolean file = false;
		if (file)
			in = new BufferedReader(new FileReader("input.txt"));
		else
			in = new BufferedReader(new InputStreamReader(System.in));
		ans = new StringBuilder();

		// read input
		tok = new StringTokenizer(in.readLine());
		nDroids = Integer.parseInt(tok.nextToken());
		nTypes = Integer.parseInt(tok.nextToken());
		nMaxShots = Integer.parseInt(tok.nextToken());
		type = new int[nDroids][nTypes];
		for (int i = 0; i < nDroids; i++)
		{
			tok = new StringTokenizer(in.readLine());
			for (int j = 0; j < nTypes; j++)
				type[i][j] = Integer.parseInt(tok.nextToken());
		}

		// solve
		System.out.println(solve());
	}

	private String solve()
	{
		makeSegmentTrees();

		// bs for the answer
		int start = 1;
		int end = nDroids;
		while (start <= end)
		{
			int mid = (start + end) / 2;
			Status statusMid = isValid(mid);
			Status statusNext = isValid(mid + 1);
			if (statusMid.valid && !statusNext.valid)
			{
				// return string
				StringBuilder strb = new StringBuilder();
				for (int i = 0; i < nTypes; i++)
					strb.append(statusMid.count[i] + " ");
				return strb.toString().trim();
			} else if (!statusMid.valid)
				end = mid - 1;
			else
				start = mid + 1;
		}

		// i failed :(
		StringBuilder strb = new StringBuilder();
		for (int i = 0; i < nTypes; i++)
			strb.append("0 ");
		return strb.toString().trim();
	}

	private Status isValid(int segmentLength)
	{
		// keep checking if we can get that segment
		for (int start = 0; start + segmentLength - 1 < nDroids; start++)
		{
			// find max number of details in droids
			int max[] = new int[nTypes];
			Arrays.fill(max, Integer.MIN_VALUE);
			int end = start + segmentLength - 1;
			for (int i = 0; i < nTypes; i++)
				max[i] = getMax(start, end, roots[i]);

			// find their sum
			int sum = 0;
			for (int i = 0; i < nTypes; i++)
				sum += max[i];
			if (sum <= nMaxShots)
			{
				Status ok = new Status();
				ok.valid = true;
				ok.count = new int[nTypes];
				for (int i = 0; i < nTypes; i++)
					ok.count[i] = max[i];
				ok.start = start;
				ok.end = end;
				return ok;
			}
		}

		Status failed = new Status();
		failed.valid = false;
		return failed;
	}

	private void makeSegmentTrees()
	{
		roots = new Node[nTypes];
		for (int i = 0; i < nTypes; i++)
			roots[i] = makeNode(0, nDroids - 1, i);
	}

	private Node makeNode(int l, int r, int typeIdx)
	{
		// base case
		if (l == r)
		{
			Node leaf = new Node();
			leaf.l = l;
			leaf.r = r;
			leaf.val = type[l][typeIdx];
			return leaf;
		}

		// make left and right
		int mid = (l + r) / 2;
		Node left = makeNode(l, mid, typeIdx);
		Node right = makeNode(mid + 1, r, typeIdx);
		Node node = new Node();
		node.l = l;
		node.r = r;
		node.right = right;
		node.left = left;
		node.val = Math.max(right.val, left.val);
		return node;
	}

	int getMax(int l, int r, Node node)
	{
		if (node.r < l || node.l > r)
			return Integer.MIN_VALUE;
		else if (node.l >= l && node.r <= r)
			return node.val;
		else
			return Math.max(getMax(l, r, node.left), getMax(l, r, node.right));
	}
}

class Node
{
	int l, r;
	Node left, right;
	int val;

}

class Status
{
	boolean valid;
	int[] count;
	int start;
	int end;
}


import java.util.*;

public class D {

	static int[][] deets;
	static SmashQ[] sq;
	static int n, m, k;

	public static void main(String[] args) {

		Scanner scan = new Scanner(System.in);

		n = scan.nextInt();
		m = scan.nextInt();
		k = scan.nextInt();

		deets = new int[n][m];

		for (int i = 0; i<n; i++) {
			for (int j = 0; j<m; j++) {
				deets[i][j] = scan.nextInt();
			}
		}

		sq = new SmashQ[m];
		for (int i = 0; i<m; i++)
			sq[i] = new SmashQ();

		int max = 0;
		int s = 0;
		int e = 0;
		int[] ans = new int[m];

		while (true) {
			if (e == n)
				break;
			if (s == e || addtot(e) <= k) {
				add(e);
				e++;
				if (e-s > max && tot() <= k) {
					max = e-s;
					for (int i = 0; i<m; i++)
						ans[i] = sq[i].val();
				}
			} else {
				remove(s);
				s++;
			}
		}

		for (int i = 0; i<m; i++)
			System.out.print(ans[i] + " ");
		System.out.println();

		scan.close();
	}

	private static void remove(int s) {
		for (int i = 0; i<m; i++)
			sq[i].dq(deets[s][i]);
	}

	private static void add(int e) {
		for (int i = 0; i<m; i++)
			sq[i].add(deets[e][i]);
	}

	private static int tot() {
		int tot = 0;
		for (int i = 0; i<m; i++)
			tot += sq[i].val();
		return tot;
	}

	private static int addtot(int e) {
		int tot = 0;
		for (int i = 0; i<m; i++)
			tot += Math.max(deets[e][i],sq[i].val());
		return tot;
	}
}

class SmashQ {

	Node head;
	Node tail;

	public SmashQ() {

	}

	public int val() {
		if (head == null)
			return 0;
		return head.val;
	}

	public void add(int x) {
		if (head == null) {
			head = new Node(x);
			tail = head;
		} else if (tail.val < x) {
			if (tail.prev == null) {
				head = null;
				add(x);
			} else {
				tail = tail.prev;
				tail.next = null;
				add(x);
			}
		} else {
			Node n = new Node(x);
			n.prev = tail;
			tail.next = n;
			tail = n;
		}
	}

	public void dq(int v) {
		if (v == val()) {
			head = head.next;
			if (head == null)
				tail = null;
			else
				head.prev = null;
		}
	}

	public void print() {
		Node n = head;
		while (n != null) {
			System.out.print(n.val + " ");
			n = n.next;
		}
		System.out.println();
	}
}

class Node {
	int val;
	Node next;
	Node prev;

	public Node(int v) {
		val = v;
	}
}


import java.util.*;

public class D {

	static int[][] deets;
	static SmashQ[] sq;
	static int n, m, k;

	public static void main(String[] args) {

		Scanner scan = new Scanner(System.in);

		n = scan.nextInt();
		m = scan.nextInt();
		k = scan.nextInt();

		deets = new int[n][m];

		for (int i = 0; i<n; i++) {
			for (int j = 0; j<m; j++) {
				deets[i][j] = scan.nextInt();
			}
		}

		sq = new SmashQ[m];
		for (int i = 0; i<m; i++)
			sq[i] = new SmashQ();

		int max = 0;
		int s = 0;
		int e = 0;
		int[] ans = new int[m];

		while (true) {
			if (e == n)
				break;
			if (s == e || addtot(e) <= k) {
				add(e);
				e++;
				if (e-s > max) {
					max = e-s;
					for (int i = 0; i<m; i++)
						ans[i] = sq[i].val();
				}
			} else {
				remove(s);
				s++;
			}
		}

		for (int i = 0; i<m; i++)
			System.out.print(ans[i] + " ");
		System.out.println();

		scan.close();
	}

	private static void remove(int s) {
		for (int i = 0; i<m; i++)
			sq[i].dq(deets[s][i]);
	}

	private static void add(int e) {
		for (int i = 0; i<m; i++)
			sq[i].add(deets[e][i]);
	}

	private static int addtot(int e) {
		int tot = 0;
		for (int i = 0; i<m; i++) {
			tot += Math.max(deets[e][i],sq[i].val());
		}
		return tot;
	}
}

class SmashQ {

	Node head;
	Node tail;

	public SmashQ() {

	}

	public int val() {
		if (head == null)
			return 0;
		return head.val;
	}

	public void add(int x) {
		if (head == null) {
			head = new Node(x);
			tail = head;
		} else if (tail.val < x) {
			if (tail.prev == null) {
				head = null;
				add(x);
			} else {
				tail = tail.prev;
				tail.next = null;
				add(x);
			}
		} else {
			Node n = new Node(x);
			n.prev = tail;
			tail.next = n;
			tail = n;
		}
	}

	public void dq(int v) {
		if (v == val()) {
			head = head.next;
			if (head == null)
				tail = null;
			else
				head.prev = null;
		}
	}

	public void print() {
		Node n = head;
		while (n != null) {
			System.out.print(n.val + " ");
			n = n.next;
		}
		System.out.println();
	}
}

class Node {
	int val;
	Node next;
	Node prev;

	public Node(int v) {
		val = v;
	}
}


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

import static java.lang.Math.*;

public class D extends PrintWriter {

	class Node {
		int f, t;
		Node l, r;
		int max;

		Node(int id, int val) {
			f = t = id;
			max = val;
		}

		Node(Node l, Node r) {
			this.l = l;
			this.r = r;

			f = l.f;
			t = r.t;

			max = Math.max(l.max, r.max);

		}

		int get(int from, int to) {
			if (to < from || t < from || to < f) {
				return 0;
			}

			if (from <= f && t <= to) {
				return max;
			}

			return Math.max(l.get(from, to), r.get(from, to));
		}

	}

	Node build(int[] a) {
		int n = a.length;
		Node[] tree = new Node[n];
		for (int i = 0; i < n; i++) {
			tree[i] = new Node(i, a[i]);
		}

		while (n > 1) {
			int m = 0;
			for (int i = 1; i < n; i += 2) {
				tree[m++] = new Node(tree[i - 1], tree[i]);
			}
			if (n % 2 == 1) {
				tree[m++] = tree[n - 1];
			}
			n = m;
		}

		return tree[0];
	}

	void run() {
		int n = nextInt(), m = nextInt(), k = nextInt();
		int[][] a = new int[m][n];

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

		Node[] t = new Node[m];

		for (int i = 0; i < m; i++) {
			t[i] = build(a[i]);
		}

		int max = 0;
		int[] ans = new int[m];

		int l = 0, r = n;
		while (r - l > 1) {
			int c = (r + l) / 2;

			boolean ok = false;
			for (int i = 0; !ok && (i + c - 1) < n; i++) {
				int sum = 0;
				for (int j = 0; j < m; j++) {
					sum += t[j].get(i, i + c - 1);
				}
				ok |= sum <= k;
			}

			if (ok) {
				l = c;
			} else {
				r = c;
			}
		}

		for (int i = 0; i + l - 1 < n; i++) {
			int sum = 0;
			int cur[] = new int[m];
			for (int j = 0; j < m; j++) {
				cur[j] = t[j].get(i, i + l - 1);
				sum += cur[j];
			}
			if (sum <= k && l > max) {
				ans = cur;
				max = l;
				break;
			}
		}
		for (int i = 0; i + r - 1 < n; i++) {
			int sum = 0;
			int cur[] = new int[m];
			for (int j = 0; j < m; j++) {
				cur[j] = t[j].get(i, i + r - 1);
				sum += cur[j];
			}
			if (sum <= k && r > max) {
				ans = cur;
				max = r;
				break;
			}
		}

		for (int x : ans) {
			print(x + " ");
		}
		println();

	}

	void skip() {
		while (hasNext()) {
			next();
		}
	}

	int[][] nextMatrix(int n, int m) {
		int[][] matrix = new int[n][m];
		for (int i = 0; i < n; i++)
			for (int j = 0; j < m; j++)
				matrix[i][j] = nextInt();
		return matrix;
	}

	String next() {
		while (!tokenizer.hasMoreTokens())
			tokenizer = new StringTokenizer(nextLine());
		return tokenizer.nextToken();
	}

	boolean hasNext() {
		while (!tokenizer.hasMoreTokens()) {
			String line = nextLine();
			if (line == null) {
				return false;
			}
			tokenizer = new StringTokenizer(line);
		}
		return true;
	}

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

	int nextInt() {
		return Integer.parseInt(next());
	}

	long nextLong() {
		return Long.parseLong(next());
	}

	double nextDouble() {
		return Double.parseDouble(next());
	}

	String nextLine() {
		try {
			return reader.readLine();
		} catch (IOException err) {
			return null;
		}
	}

	public D(OutputStream outputStream) {
		super(outputStream);
	}

	static BufferedReader reader;
	static StringTokenizer tokenizer = new StringTokenizer("");
	static Random rnd = new Random();
	static boolean OJ;

	public static void main(String[] args) throws IOException {
		OJ = System.getProperty("ONLINE_JUDGE") != null;
		D solution = new D(System.out);
		if (OJ) {
			reader = new BufferedReader(new InputStreamReader(System.in));
			solution.run();
		} else {
			reader = new BufferedReader(new FileReader(new File(D.class.getName() + ".txt")));
			long timeout = System.currentTimeMillis();
			while (solution.hasNext()) {
				solution.run();
				solution.println();
				solution.println("----------------------------------");
			}
			solution.println("time: " + (System.currentTimeMillis() - timeout));
		}
		solution.close();
		reader.close();
	}
}


import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.io.InputStream;
import java.util.NoSuchElementException;
import java.io.OutputStreamWriter;
import java.math.BigInteger;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.io.IOException;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		OutputWriter out = new OutputWriter(outputStream);
		TaskD solver = new TaskD();
		solver.solve(1, in, out);
		out.close();
	}
}

 class TaskD {
    static class SparseTable {
        int n, lgn;
        int[][] t;

        SparseTable(int[] a) {
            n = a.length;
            lgn = Integer.numberOfTrailingZeros(Integer.highestOneBit(n)) + 1;
            t = new int[lgn][];
            for (int lvl = 0; lvl < lgn; lvl++) {
                t[lvl] = new int[n - (1 << lvl) + 1];
            }
            for (int i = 0; i < n; i++) {
                t[0][i] = a[i];
            }
            for (int lvl = 1; lvl < lgn; lvl++) {
                int length = n - (1 << lvl) + 1;
                for (int i = 0; i < length; i++) {
                    int p = t[lvl - 1][i];
                    int q = t[lvl - 1][i + (1 << (lvl - 1))];
                    t[lvl][i] = Math.max(p, q);
                }
            }
        }

        int getMax(int l, int r) {
            int length = r - l + 1;
            int lvl = Integer.numberOfTrailingZeros(Integer.highestOneBit(length));
            int p = t[lvl][l];
            int q = t[lvl][r - (1 << lvl) + 1];
            return Math.max(p, q);
        }
    }

    public void solve(int testNumber, InputReader in, OutputWriter out) {
        int n = in.readInt();
        int m = in.readInt();
        int k = in.readInt();
        int[][] a = new int[m][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                a[j][i] = in.readInt();
            }
        }
        SparseTable[] tables = new SparseTable[m];
        for (int i = 0; i < m; i++) {
            tables[i] = new SparseTable(a[i]);
        }
        int l = 0, r = n, ans = -1;
        while (l <= r) {
            int length = (l + r) / 2;
            int[] res = f(length, tables, n, m);
            int sum = 0;
            for (int x : res) sum += x;
            if (sum <= k) {
                ans = length;
                l = length + 1;
            } else {
                r = length - 1;
            }
        }
        int[] res = f(ans, tables, n, m);
        out.printLine(res);
    }

    private int[] f(int length, SparseTable[] tables, int n, int m) {
        int minSum = Integer.MAX_VALUE;
        int[] best = new int[m];
        int[] current = new int[m];
        for (int l = 0, r = length - 1; r < n; l++, r++) {
            int sum = 0;
            for (int j = 0; j < m; j++) {
                current[j] = tables[j].getMax(l, r);
                sum += current[j];
            }
            if (sum < minSum) {
                minSum = sum;
                System.arraycopy(current, 0, best, 0, m);
            }
        }
        return best;
    }
}

 class InputReader {

	 private InputStream stream;
	private byte[] buf = new byte[1024];
	private int curChar;
	private int numChars;
	private SpaceCharFilter filter;

	public InputReader(InputStream stream) {
		this.stream = stream;
	}

	public int read() {
		if (numChars == -1)
			throw new InputMismatchException();
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (numChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}

     public int readInt() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

     public boolean isSpaceChar(int c) {
		if (filter != null)
			return filter.isSpaceChar(c);
		return isWhitespace(c);
	}

	public static boolean isWhitespace(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}

     public interface SpaceCharFilter {
		public boolean isSpaceChar(int ch);
	}
}

 class OutputWriter {
	private final PrintWriter writer;

	public OutputWriter(OutputStream outputStream) {
		writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
	}

	public OutputWriter(Writer writer) {
		this.writer = new PrintWriter(writer);
	}

     public void print(int[] array) {
        for (int i = 0; i < array.length; i++) {
            if (i != 0)
                writer.print(' ');
            writer.print(array[i]);
        }
    }

     public void printLine(int[] array) {
        print(array);
        writer.println();
    }

	 public void close() {
		writer.close();
	}

 }


import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.io.InputStream;
import java.util.NoSuchElementException;
import java.io.OutputStreamWriter;
import java.math.BigInteger;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.io.IOException;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		OutputWriter out = new OutputWriter(outputStream);
		TaskD solver = new TaskD();
		solver.solve(1, in, out);
		out.close();
	}
}

 class TaskD {
    static class SparseTable {
        int n, lgn;
        int[][] t;

        SparseTable(int[] a) {
            n = a.length;
            lgn = Integer.numberOfTrailingZeros(Integer.highestOneBit(n)) + 1;
            t = new int[lgn][];
            for (int lvl = 0; lvl < lgn; lvl++) {
                int length = n - (1 << lvl) + 1;
                t[lvl] = new int[length];
            }
            for (int i = 0; i < n; i++) {
                t[0][i] = a[i];
            }
            for (int lvl = 1; lvl < lgn; lvl++) {
                int length = n - (1 << lvl) + 1;
                for (int i = 0; i < length; i++) {
                    int p = t[lvl - 1][i];
                    int q = t[lvl - 1][i + (1 << (lvl - 1))];
                    t[lvl][i] = Math.max(p, q);
                }
            }
        }

        int getMax(int l, int r) {
            int length = r - l + 1;
            int lvl = Integer.numberOfTrailingZeros(Integer.highestOneBit(length));
            int p = t[lvl][l];
            int q = t[lvl][r - (1 << lvl) + 1];
            return Math.max(p, q);
        }
    }

    public void solve(int testNumber, InputReader in, OutputWriter out) {
        int n = in.readInt();
        int m = in.readInt();
        int k = in.readInt();
        int[][] a = new int[m][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                a[j][i] = in.readInt();
            }
        }
        SparseTable[] tables = new SparseTable[m];
        for (int i = 0; i < m; i++) {
            tables[i] = new SparseTable(a[i]);
        }
        int l = 1, r = n, ans = 0;
        while (l <= r) {
            int length = (l + r) / 2;
            int[] res = f(length, tables, n, m);
            int sum = 0;
            for (int x : res) sum += x;
            if (sum <= k) {
                ans = length;
                l = length + 1;
            } else {
                r = length - 1;
            }
        }
        int[] res = f(ans, tables, n, m);
        out.printLine(res);
    }

    private int[] f(int length, SparseTable[] tables, int n, int m) {
        int minSum = Integer.MAX_VALUE;
        int[] best = new int[m];
        int[] current = new int[m];
        for (int l = 0, r = length - 1; r < n; l++, r++) {
            int sum = 0;
            for (int j = 0; j < m; j++) {
                current[j] = tables[j].getMax(l, r);
                sum += current[j];
            }
            if (sum < minSum) {
                minSum = sum;
                System.arraycopy(current, 0, best, 0, m);
            }
        }
        return best;
    }
}

 class InputReader {

	 private InputStream stream;
	private byte[] buf = new byte[1024];
	private int curChar;
	private int numChars;
	private SpaceCharFilter filter;

	public InputReader(InputStream stream) {
		this.stream = stream;
	}

	public int read() {
		if (numChars == -1)
			throw new InputMismatchException();
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (numChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}

     public int readInt() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

     public boolean isSpaceChar(int c) {
		if (filter != null)
			return filter.isSpaceChar(c);
		return isWhitespace(c);
	}

	public static boolean isWhitespace(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}

     public interface SpaceCharFilter {
		public boolean isSpaceChar(int ch);
	}
}

 class OutputWriter {
	private final PrintWriter writer;

	public OutputWriter(OutputStream outputStream) {
		writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
	}

	public OutputWriter(Writer writer) {
		this.writer = new PrintWriter(writer);
	}

     public void print(int[] array) {
        for (int i = 0; i < array.length; i++) {
            if (i != 0)
                writer.print(' ');
            writer.print(array[i]);
        }
    }

     public void printLine(int[] array) {
        print(array);
        writer.println();
    }

	 public void close() {
		writer.close();
	}

 }


import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.io.InputStream;
import java.util.NoSuchElementException;
import java.io.OutputStreamWriter;
import java.math.BigInteger;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.io.IOException;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		OutputWriter out = new OutputWriter(outputStream);
		TaskD solver = new TaskD();
		solver.solve(1, in, out);
		out.close();
	}
}

 class TaskD {
    static class SparseTable {
        int n, lgn;
        int[][] t;

        SparseTable(int[] a) {
            n = a.length;
            lgn = Integer.numberOfTrailingZeros(Integer.highestOneBit(n)) + 1;
            t = new int[lgn][];
            for (int lvl = 0; lvl < lgn; lvl++) {
                int length = n - (1 << lvl) + 1;
                t[lvl] = new int[length];
            }
            for (int i = 0; i < n; i++) {
                t[0][i] = a[i];
            }
            for (int lvl = 1; lvl < lgn; lvl++) {
                int length = n - (1 << lvl) + 1;
                for (int i = 0; i < length; i++) {
                    int p = t[lvl - 1][i];
                    int q = t[lvl - 1][i + (1 << (lvl - 1))];
                    t[lvl][i] = Math.max(p, q);
                }
            }
        }

        int getMax(int l, int r) {
            int length = r - l + 1;
            int lvl = Integer.numberOfTrailingZeros(Integer.highestOneBit(length));
            int p = t[lvl][l];
            int q = t[lvl][r - (1 << lvl) + 1];
            return Math.max(p, q);
        }
    }

    public void solve(int testNumber, InputReader in, OutputWriter out) {
        int n = in.readInt();
        int m = in.readInt();
        int k = in.readInt();
        int[][] a = new int[m][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                a[j][i] = in.readInt();
            }
        }
        SparseTable[] tables = new SparseTable[m];
        for (int i = 0; i < m; i++) {
            tables[i] = new SparseTable(a[i]);
        }
        int l = 0, r = n, ans = -1;
        while (l <= r) {
            int length = (l + r) / 2;
            int[] res = f(length, tables, n, m);
            int sum = 0;
            for (int x : res) sum += x;
            if (sum <= k) {
                ans = length;
                l = length + 1;
            } else {
                r = length - 1;
            }
        }
        int[] res = f(ans, tables, n, m);
        out.printLine(res);
    }

    private int[] f(int length, SparseTable[] tables, int n, int m) {
        int minSum = Integer.MAX_VALUE;
        int[] best = new int[m];
        int[] current = new int[m];
        if (length == 0) {
            return best;
        }
        for (int l = 0, r = length - 1; r < n; l++, r++) {
            int sum = 0;
            for (int j = 0; j < m; j++) {
                current[j] = tables[j].getMax(l, r);
                sum += current[j];
            }
            if (sum < minSum) {
                minSum = sum;
                System.arraycopy(current, 0, best, 0, m);
            }
        }
        return best;
    }
}

 class InputReader {

	 private InputStream stream;
	private byte[] buf = new byte[1024];
	private int curChar;
	private int numChars;
	private SpaceCharFilter filter;

	public InputReader(InputStream stream) {
		this.stream = stream;
	}

	public int read() {
		if (numChars == -1)
			throw new InputMismatchException();
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (numChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}

     public int readInt() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

     public boolean isSpaceChar(int c) {
		if (filter != null)
			return filter.isSpaceChar(c);
		return isWhitespace(c);
	}

	public static boolean isWhitespace(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}

     public interface SpaceCharFilter {
		public boolean isSpaceChar(int ch);
	}
}

 class OutputWriter {
	private final PrintWriter writer;

	public OutputWriter(OutputStream outputStream) {
		writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
	}

	public OutputWriter(Writer writer) {
		this.writer = new PrintWriter(writer);
	}

     public void print(int[] array) {
        for (int i = 0; i < array.length; i++) {
            if (i != 0)
                writer.print(' ');
            writer.print(array[i]);
        }
    }

     public void printLine(int[] array) {
        print(array);
        writer.println();
    }

	 public void close() {
		writer.close();
	}

 }


import java.util.Random;
import java.util.Scanner;
import java.util.Stack;

public class ProblemD {

    static class queue {
        private Stack<Integer> inbox = new Stack<Integer>();
        private Stack<Integer> outbox = new Stack<Integer>();
        private Stack<Integer> maxinbox = new Stack<Integer>();
        private Stack<Integer> maxoutbox = new Stack<Integer>();

        public void queue(Integer item){
            inbox.push(item);
            if(maxinbox.isEmpty())
                maxinbox.push(item);
            else
                maxinbox.push(Math.max(item, maxinbox.peek()));
        }

        public Integer dequeue(){

            if (outbox.isEmpty()) {
                while (!inbox.isEmpty()) {
                   outbox.push(inbox.peek());
                   maxinbox.pop();
                   if(maxoutbox.isEmpty())
                       maxoutbox.push(inbox.peek());
                   else maxoutbox.push(Math.max(maxoutbox.peek(), inbox.peek()));
                   inbox.pop();
                }
            }

            outbox.pop();
            return maxoutbox.pop();
        }

        public Integer peekMax(){
            if(maxinbox.isEmpty())
                return maxoutbox.peek();
            if(maxoutbox.isEmpty())
                return maxinbox.peek();

            return Math.max(maxinbox.peek(), maxoutbox.peek());
        }
        public int size(){
            return inbox.size() + outbox.size();
        }
    }

public static void main(String[] args){

        Scanner scanner = new Scanner(System.in);

         int n = scanner.nextInt(), m = scanner.nextInt(), k = scanner.nextInt();

         queue[] arr = new queue[m];

         for(int i = 0; i  < m; i++)
             arr[i] = new queue();

         int[] rest = new int[m];
         int result = 0;

         for(int i = 0; i < n; i++){

             int sum = 0;

             for(int j = 0; j < m; j++){
                 arr[j].queue(scanner.nextInt());
                 sum += arr[j].peekMax();
             }

             if(sum <= k){
                 if(result < arr[0].size())
                     for(int j = 0; j < m; j++)
                         rest[j] = arr[j].peekMax();
             } else
                 for(int j = 0; j < m; j++)
                     arr[j].dequeue();
         }

         for(int i = 0; i < m; i++)
             System.out.print(rest[i] + " ");

    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Map.Entry;
import java.util.TreeMap;

public class D {
	static InputStreamReader isr = new InputStreamReader(System.in);
	static BufferedReader br = new BufferedReader(isr);

	static int[] readIntArray() throws IOException {
		String[] v = br.readLine().split(" ");
		int[] ans = new int[v.length];

		for (int i = 0; i < ans.length; i++) {
			ans[i] = Integer.valueOf(v[i]);
		}

		return ans;
	}

	static int n, m, k;
	static int[][] droids;
	static TreeMap<Integer, Integer>[] forest;

	public static void main(String[] args) throws IOException {
		int[] l = readIntArray();
		n = l[0];
		m = l[1];
		k = l[2];
		droids = new int[n][];
		for (int i = 0; i < droids.length; i++) {
			droids[i] = readIntArray();
		}
		forest = new TreeMap[m];
		for (int i = 0; i < m; i++) {
			forest[i] = new TreeMap<Integer, Integer>();
		}
		long ans = 0;
		int[] shots = new int[m];
		int end = -1;
		for (int i = 0; i < n; i++) {
			end = Math.max(i - 1, end);
			if (i > 0) {
				for (int j = 0; j < m; j++) {
					if (forest[j].containsKey(droids[i - 1][j])) {
						int cnt = forest[j].get(droids[i - 1][j]);
						if (cnt == 1) {
							forest[j].remove(droids[i - 1][j]);
						} else {
							forest[j].put(droids[i - 1][j], cnt - 1);
						}
					}
				}
			}

			int[] max = new int[m];
			for (; end + 1 < n; end++) {
				max = new int[m];
				for (int k = 0; k < m; k++) {
					Entry<Integer, Integer> ent = forest[k].lastEntry();
					if (ent != null) {
						max[k] = ent.getKey();
					}
					max[k] = Math.max(max[k], droids[end + 1][k]);
				}
				long sum = 0;
				for (int k = 0; k < max.length; k++) {
					sum += max[k];
				}
				if (sum <= k) {
					int cl = end + 1 - i + 1;
					if (cl > ans) {
						ans = cl;
						shots = Arrays.copyOf(max, max.length);
					}

					for (int j = 0; j < m; j++) {
						if (!forest[j].containsKey(droids[end + 1][j])) {
							forest[j].put(droids[end + 1][j], 1);
						} else {
							forest[j].put(droids[end + 1][j], forest[j].get(droids[end + 1][j]) + 1);
						}

					}
				} else {
					break;
				}
			}
		}

		// System.out.println(ans);
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < shots.length; i++) {
			if (sb.length() > 0) {
				sb.append(' ');
			}
			sb.append(shots[i]);
		}
		System.out.println(sb.toString());
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;

public class C {
	static InputStreamReader isr = new InputStreamReader(System.in);
	static BufferedReader br = new BufferedReader(isr);

	static int[] readIntArray() throws IOException {
		String[] v = br.readLine().split(" ");
		int[] ans = new int[v.length];

		for (int i = 0; i < ans.length; i++) {
			ans[i] = Integer.valueOf(v[i]);
		}

		return ans;
	}

	static class S {
		int hash;
		public char[] content;
		int N;

		public S(String s) {
			this.content = s.toCharArray();
			this.N = content.length;
			this.hash = 17;
			for (int i = 0; i < this.content.length; i++) {
				hash *= 31;
				hash += this.content[i];
			}
		}

		public void setChar(int pos, char val) {
			this.hash -= powers[N - pos - 1] * this.content[pos];
			this.hash += powers[N - pos - 1] * val;
			this.content[pos] = val;
		}

		@Override
		public int hashCode() {
			return hash;
		}

		@Override
		public boolean equals(Object obj) {
			if (obj == null)
				return false;
			if (!(obj instanceof C.S))
				return false;
			S other = (S) obj;
			if (this.content.length == other.content.length) {
				for (int i = 0; i < this.content.length; i++) {
					if (this.content[i] != other.content[i])
						return false;
				}
				return true;
			}
			return false;

		}
	}

	static int n, m;
	static HashSet<S> mem = new HashSet<C.S>();
	static char[] possible = new char[] { 'a', 'b', 'c' };
	static int[] powers = new int[700000];

	public static void main(String[] args) throws IOException {
		powers[0] = 1;
		for (int i = 1; i < powers.length; i++) {
			powers[i] = powers[i - 1] * 31;
		}

		// S tmp = new S("aabaa");
		// System.out.println(tmp.hash);
		// System.out.println(new S("aaaaa").hash);
		// tmp.setChar(2, 'b');
		// System.out.println(tmp.hash);
		// tmp.setChar(2, 'a');
		// System.out.println(tmp.hash);
		// tmp.setChar(2, 'b');
		// System.out.println(tmp.hash);
		//
		//
		int[] l = readIntArray();
		n = l[0];
		m = l[1];

		for (int i = 0; i < n; i++) {
			String s = br.readLine();
			S entry = new S(s);
//			System.out.println(new String(entry.content) + " " + entry.hash);
			mem.add(entry);
		}

		for (int i = 0; i < m; i++) {
			boolean found = false;
			String s = br.readLine();
			S q = new S(s);
//			System.out.println(new String(q.content) + " " + q.hash);
			for (int j = 0; j < s.length() && !found; j++) {
				for (int j2 = 0; j2 < possible.length; j2++) {
					if (s.charAt(j) != possible[j2]) {
						q.setChar(j, possible[j2]);
//						System.out.println(new String(q.content) + " " + q.hash);
						if (mem.contains(q)) {
							found = true;
							break;
						}
					}
				}
				q.setChar(j, s.charAt(j));
			}

			System.out.println(found ? "YES" : "NO");
		}
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Map.Entry;
import java.util.TreeMap;

public class D {
	static InputStreamReader isr = new InputStreamReader(System.in);
	static BufferedReader br = new BufferedReader(isr);

	static int[] readIntArray() throws IOException {
		String[] v = br.readLine().split(" ");
		int[] ans = new int[v.length];

		for (int i = 0; i < ans.length; i++) {
			ans[i] = Integer.valueOf(v[i]);
		}

		return ans;
	}

	static int n, m, k;
	static int[][] droids;
	static TreeMap<Integer, Integer>[] forest;

	public static void main(String[] args) throws IOException {
		int[] l = readIntArray();
		n = l[0];
		m = l[1];
		k = l[2];
		droids = new int[n][];
		for (int i = 0; i < droids.length; i++) {
			droids[i] = readIntArray();
		}
		forest = new TreeMap[m];
		for (int i = 0; i < m; i++) {
			forest[i] = new TreeMap<Integer, Integer>();
		}
		long ans = 0;
		int[] shots = new int[m];
		int end = -1;
		for (int i = 0; i < n; i++) {

			if (i > 0) {
				for (int j = 0; j < m; j++) {
					if (forest[j].containsKey(droids[i - 1][j])) {
						int cnt = forest[j].get(droids[i - 1][j]);
						if (cnt == 1) {
							forest[j].remove(droids[i - 1][j]);
						} else {
							forest[j].put(droids[i - 1][j], cnt - 1);
						}
					}
				}
			}

			int[] max = new int[m];
			for (; end + 1 < n; end++) {
				max = new int[m];
				for (int k = 0; k < m; k++) {
					Entry<Integer, Integer> ent = forest[k].lastEntry();
					if (ent != null) {
						max[k] = ent.getKey();
					}
					max[k] = Math.max(max[k], droids[end + 1][k]);
				}
				long sum = 0;
				for (int k = 0; k < max.length; k++) {
					sum += max[k];
				}
				if (sum <= k) {
					int cl = end + 1 - i + 1;
					if (cl > ans) {
						ans = cl;
						shots = Arrays.copyOf(max, max.length);
					}

					for (int j = 0; j < m; j++) {
						if (!forest[j].containsKey(droids[end + 1][j])) {
							forest[j].put(droids[end + 1][j], 1);
						} else {
							forest[j].put(droids[end + 1][j], forest[j].get(droids[end + 1][j]) + 1);
						}

					}
				} else {
					break;
				}
			}
		}

		// System.out.println(ans);
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < shots.length; i++) {
			if (sb.length() > 0) {
				sb.append(' ');
			}
			sb.append(shots[i]);
		}
		System.out.println(sb.toString());
	}
}


#include<bits/stdc++.h>
using namespace std;
multiset<int> ans[7];
int answer,an[6];
int inp[100003][6];
bool can[100003];
int get_max(int i)
{
    multiset<int> ::iterator it = ans[i].end();it--;
    return *it;
}
void del(int x,int i)
{
    multiset<int>::iterator it = ans[i].find(x);
    ans[i].erase(it);
}
int main()
{
    int n,m,k;cin >> n >> m>> k;
    for(int i =0;i<n;i++)
        {
            int sum = 0;
            for(int j = 0;j<m;j++)
                cin >> inp[i][j],sum+=inp[i][j];
            if (sum<=k)can[i] = true;
        }
    int con =0;int kk=0;
    for(int i =0;i<n;i++)
    {
        bool fucked=false;
        if(!can[i])
            for(int i =0;i<m;i++)
                ans[i].clear();
        int kkk=kk;
        for(int j =0;j<m;j++)
        {
            if(!ans[j].empty()&&inp[i][j]>get_max(j))
            {
                if((inp[i][j]-get_max(j))<=(k-kk)){kk+=inp[i][j]-get_max(j);continue;}
                fucked = true;break;
            }
        }
        if(fucked)
        {
        kk=kkk;
        for(int j = 0;j<m;j++)
            del(inp[i-con][j],j);
        con--;i--;continue;}
        else
        {
            for(int j =0;j<m;j++)
                ans[j].insert(inp[i][j]);
            if(ans[0].size()==1)
            {
                kk=0;
                for(int j =0;j<m;j++)
                    kk+=get_max(j);
            }
            con++;
            if(con>answer)
                {answer=con;for(int j=0;j<m;j++)an[j]=get_max(j);}
        }
    }
    for(int i =0;i<m;i++)
        cout << an[i]<<" ";
}


#include<bits/stdc++.h>
using namespace std;
multiset<int> ans[7];
int answer,an[6];
int inp[100003][6];
bool can[100003];
int get_max(int i)
{
    multiset<int> ::iterator it = ans[i].end();it--;
    return *it;
}
void del(int x,int i)
{
    multiset<int>::iterator it = ans[i].find(x);
    ans[i].erase(it);
}
int main()
{
    int n,m,k;cin >> n >> m>> k;
    for(int i =0;i<n;i++)
        {
            int sum = 0;
            for(int j = 0;j<m;j++)
                cin >> inp[i][j],sum+=inp[i][j];
            if (sum<=k)can[i] = true;
        }
    int con =0;int kk=0;
    for(int i =0;i<n;i++)
    {
        bool fucked=false;
        if(!can[i])
            {for(int i =0;i<m;i++)
                ans[i].clear();
            continue;}
        int kkk=kk;
        for(int j =0;j<m;j++)
        {
            if(!ans[j].empty()&&inp[i][j]>get_max(j))
            {
                if((inp[i][j]-get_max(j))<=(k-kk)){kk+=inp[i][j]-get_max(j);continue;}
                fucked = true;break;
            }
        }
        if(fucked)
        {
        kk=kkk;
        for(int j = 0;j<m;j++)
            del(inp[i-con][j],j);
        con--;i--;continue;}
        else
        {
            for(int j =0;j<m;j++)
                ans[j].insert(inp[i][j]);
            if(ans[0].size()==1)
            {
                kk=0;
                for(int j =0;j<m;j++)
                    kk+=get_max(j);
            }
            con++;
            if(con>answer)
                {answer=con;for(int j=0;j<m;j++)an[j]=get_max(j);}
        }
    }
    for(int i =0;i<m;i++)
        cout << an[i]<<" ";
}


#include<bits/stdc++.h>
using namespace std;
multiset<int> ans[7];
int answer,an[6];
int inp[100003][6];
bool can[100003];
int get_max(int i)
{
    multiset<int> ::iterator it = ans[i].end();it--;
    return *it;
}
void del(int x,int i)
{
    multiset<int>::iterator it = ans[i].find(x);
    ans[i].erase(it);
}
int main()
{
    int n,m,k;cin >> n >> m>> k;
    for(int i =0;i<n;i++)
        {
            int sum = 0;
            for(int j = 0;j<m;j++)
                cin >> inp[i][j],sum+=inp[i][j];
            if (sum<=k)can[i] = true;
        }
    int con =0;int kk=0;
    for(int i =0;i<n;i++)
    {
        bool fucked=false;
        if(!can[i])
            {for(int i =0;i<m;i++)
                ans[i].clear();
            continue;}
        int kkk=kk;
        for(int j =0;j<m;j++)
        {
            if(!ans[j].empty()&&inp[i][j]>get_max(j))
            {
                if((inp[i][j]-get_max(j))<=(k-kk)){kk+=inp[i][j]-get_max(j);continue;}
                fucked = true;break;
            }
        }
        if(fucked)
        {
        kk=kkk;
        for(int j = 0;j<m;j++)
            del(inp[i-con][j],j);
        if(ans[0].size()>=1)
            {
                kk=0;
                for(int j =0;j<m;j++)
                    kk+=get_max(j);
            }
        con--;i--;continue;}
        else
        {
            for(int j =0;j<m;j++)
                ans[j].insert(inp[i][j]);
            if(ans[0].size()==1)
            {
                kk=0;
                for(int j =0;j<m;j++)
                    kk+=get_max(j);
            }
            con++;
            if(con>answer)
                {answer=con;for(int j=0;j<m;j++)an[j]=get_max(j);}
        }
    }
    for(int i =0;i<m;i++)
        cout << an[i]<<" ";
}


#include<bits/stdc++.h>
using namespace std;
multiset<int> ans[7];
int answer,an[6];
int inp[100003][6];
bool can[100003];
int get_max(int i)
{
    multiset<int> ::iterator it = ans[i].end();it--;
    return *it;
}
void del(int x,int i)
{
    multiset<int>::iterator it = ans[i].find(x);
    ans[i].erase(it);
}
int main()
{
    int n,m,k;cin >> n >> m>> k;
    for(int i =0;i<n;i++)
        {
            int sum = 0;
            for(int j = 0;j<m;j++)
                cin >> inp[i][j],sum+=inp[i][j];
            if (sum<=k)can[i] = true;
        }
    int con =0;int kk=0;
    for(int i =0;i<n;i++)
    {
        bool fucked=false;
        if(!can[i])
            {for(int i =0;i<m;i++)
                ans[i].clear();
            continue;}
        int kkk=kk;
        for(int j =0;j<m;j++)
        {
            if(!ans[j].empty()&&inp[i][j]>get_max(j))
            {
                if((inp[i][j]-get_max(j))<=(k-kk)){kk+=inp[i][j]-get_max(j);continue;}
                fucked = true;break;
            }
        }
        if(fucked)
        {
        kk=kkk;
        for(int j = 0;j<m;j++)
            del(inp[i-con][j],j);
        kk=0;
        for(int j =0;j<m;j++)
            kk+=get_max(j);
        con--;i--;continue;}
        else
        {
            for(int j =0;j<m;j++)
                ans[j].insert(inp[i][j]);
            if(ans[0].size()==1)
            {
                kk=0;
                for(int j =0;j<m;j++)
                    kk+=get_max(j);
            }
            con++;
            if(con>answer)
                {answer=con;for(int j=0;j<m;j++)an[j]=get_max(j);}
        }
    }
    for(int i =0;i<m;i++)
        cout << an[i]<<" ";
}


#include <bits/stdc++.h>

using namespace std;

const int MAX_N = 100008;

int n, m, k;
int det[MAX_N][8];
multiset<int> s[8];

int main()
{
    int ans[5] = {0};
    int droidsD = 0;

    cin >> n >> m >> k;
    for(int i = 0; i < n; i++)
        for(int j = 0; j < m; j++) cin >> det[i][j];

    int l = 0, r = 0;
    for(int i = 0; i < m; i++) s[i].insert(det[0][i]);

    while(r < n)
    {
        int shots = 0;
        for(int i = 0; i < m; i++) shots += *s[i].end();

        if(shots > k)
        {
            for(int i = 0; i < m; i++) s[i].erase(det[l][i]);
            l++;
        }
        else
        {
            if(droidsD < r - l + 1)
            {
                droidsD = r - l + 1;
                for(int q = 0; q < m; q++) ans[q] = *s[q].end();
            }

            r++;
            for(int i = 0; i < m; i++) s[i].insert(det[r][i]);
        }
    }

    for(int i = 0; i < m; i++) cout << ans[i] << " ";
    cout << endl;
}


#include <bits/stdc++.h>

using namespace std;

const int MAX_N = 100008;

int n, m, k;
int det[MAX_N][8];
multiset<int> s[8];

int main()
{
    int ans[5] = {0};
    int droidsD = 0;

    cin >> n >> m >> k;
    for(int i = 0; i < n; i++)
        for(int j = 0; j < m; j++) cin >> det[i][j];

    int l = 0, r = 0;
    for(int i = 0; i < m; i++) s[i].insert(det[0][i]);

    while(r < n - 1)
    {
        int shots = 0;
        for(int i = 0; i < m; i++)shots += *s[i].rbegin();

        if(shots > k)
        {
            for(int i = 0; i < m; i++) s[i].erase(det[l][i]);
            l++;
        }
        else
        {
            if(droidsD < r - l + 1)
            {
                droidsD = r - l + 1;

                for(int q = 0; q < m; q++) ans[q] = *s[q].rbegin();
            }

            r++;
            for(int i = 0; i < m; i++) s[i].insert(det[r][i]);
        }
    }

    for(int i = 0; i < m; i++) cout << ans[i] << " ";
    cout << endl;
}


#include <bits/stdc++.h>

using namespace std;

const int MAX_N = 100008;

int n, m, k;
int det[MAX_N][5];

int main()
{
    int ans[5] = {0};
    int cur[5] = {0};
    int droidsD = 0;

    cin >> n >> m >> k;
    for(int i = 0; i < n; i++)
        for(int j = 0; j < m; j++) cin >> det[i][j];

    int l = 0, r = 1;

    while(r < n)
    {
        int shots = 0;
        for(int j = 0; j < m; j++)
        {
            int maxx = 0;
            for(int i = l; i < r; i++) maxx = max(maxx, det[i][j]);
            shots += maxx;
            cur[j] = maxx;
        }

        if(shots > k) l++;
        else
        {
            if(droidsD < r - l)
            {
                int droidsD = r - l;
                for(int q = 0; q < m; q++) ans[q] = cur[q];
            }

            r++;
        }
    }

    for(int i = 0; i < m; i++) cout << ans[i] << " ";
    cout << endl;
}


#include <bits/stdc++.h>

using namespace std;

const int MAX_N = 100008;

int n, m, k;
int det[MAX_N][8];
multiset<int> s[8];

int main()
{
    int ans[5] = {0};
    int droidsD = 0;

    cin >> n >> m >> k;
    for(int i = 0; i < n; i++)
        for(int j = 0; j < m; j++) cin >> det[i][j];

    int l = 0, r = 0;
    for(int i = 0; i < m; i++) s[i].insert(det[0][i]);

    while(r < n and l < n - 1)
    {
        int shots = 0;
        for(int i = 0; i < m; i++) shots += *s[i].rbegin();

        if(shots > k)
        {
            for(int i = 0; i < m; i++) s[i].erase(det[l][i]);
            l++;
        }
        else
        {
            if(droidsD < r - l + 1)
            {
                droidsD = r - l + 1;

                for(int q = 0; q < m; q++) ans[q] = *s[q].rbegin();
            }

            r++;
            for(int i = 0; i < m; i++) s[i].insert(det[r][i]);
        }
    }

    for(int i = 0; i < m; i++) cout << ans[i] << " ";
    cout << endl;
}


#include <bits/stdc++.h>

using namespace std;

const int MAX_N = 100008;

int n, m, k;
int det[MAX_N][5];

int main()
{
    int ans[5] = {0};
    int cur[5] = {0};
    int droidsD = 0;

    cin >> n >> m >> k;
    for(int i = 0; i < n; i++)
        for(int j = 0; j < m; j++) cin >> det[i][j];

    int l = 0, r = 1;

    while(r < n)
    {
        int shots = 0;
        for(int j = 0; j < m; j++)
        {
            int maxx = 0;
            for(int i = l; i <= r; i++) maxx = max(maxx, det[i][j]);
            shots += maxx;
            cur[j] = maxx;
        }

        if(shots > k) l++;
        else
        {
            if(droidsD < r - l)
            {
                int droidsD = r - l;
                for(int q = 0; q < m; q++) ans[q] = cur[q];
            }

            r++;
        }
    }

    for(int i = 0; i < m; i++) cout << ans[i] << " ";
    cout << endl;
}


#include <bits/stdc++.h>

using namespace std;

const int MAX_N = 100008;

int n, m, k;
int det[MAX_N][5];

int main()
{
    int ans[5] = {0};
    int cur[5] = {0};
    int droidsD = 0;

    cin >> n >> m >> k;
    for(int i = 0; i < n; i++)
        for(int j = 0; j < m; j++) cin >> det[i][j];

    int l = 0, r = 0;

    while(r < n)
    {
        int shots = 0;
        for(int j = 0; j < m; j++)
        {
            int maxx = 0;
            for(int i = l; i <= r; i++) maxx = max(maxx, det[i][j]);
            shots += maxx;
            cur[j] = maxx;
        }

        if(shots > k) l++;
        else
        {
            if(droidsD < r - l + 1)
            {
                droidsD = r - l + 1;
                for(int q = 0; q < m; q++) ans[q] = cur[q];
            }

            r++;
        }
    }

    for(int i = 0; i < m; i++) cout << ans[i] << " ";
    cout << endl;
}


#include <bits/stdc++.h>

using namespace std;

const int MAX_N = 100008;

int n, m, k;
int det[MAX_N][8];
multiset<int> s[8];

int main()
{
    int ans[5] = {0};
    int droidsD = 0;

    cin >> n >> m >> k;
    for(int i = 0; i < n; i++)
        for(int j = 0; j < m; j++) cin >> det[i][j];

    int l = 0, r = 0;
    for(int i = 0; i < m; i++) s[i].insert(det[0][i]);

    while(r < n)
    {
        int shots = 0;
        for(int i = 0; i < m; i++) if(s[i].size() != 0) shots += *s[i].rbegin();

        if(shots > k)
        {
            for(int i = 0; i < m; i++) s[i].erase(det[l][i]);
            l++;
        }
        else
        {
            if(droidsD < r - l + 1)
            {
                droidsD = r - l + 1;

                for(int q = 0; q < m; q++) ans[q] = *s[q].rbegin();
            }

            r++;
            for(int i = 0; i < m; i++) s[i].insert(det[r][i]);
        }
    }

    for(int i = 0; i < m; i++) cout << ans[i] << " ";
    cout << endl;
}


#include <bits/stdc++.h>

using namespace std;

#define forn(i, x, n) for (int i = int(x); i <= int(n); ++i)
#define for1(i, n, x) for (int i = int(n); i >= int(x); --i)
#define file ""
#define x first
#define y second
#define pb push_back

typedef long long ll;
typedef pair <int, int> PII;
typedef const PII & pnt;

const int N = 3e5;
const int Log = 22;
const int M = 7;
const int INF = 1e9 + 9;

int n, m, k;
int a[M][N];

struct SparseTable {
	int n, t[Log][N], lg[N];

	void init(int _n, int *a) {
		n = _n;
		lg[1] = 0;
		forn(i, 2, n)
			lg[i] = lg[i / 2] + 1;
		forn(i, 1, n)
			t[0][i] = a[i];
		forn(lvl, 1, lg[n])
			forn(i, 1, n)
				t[lvl][i] = max(t[lvl - 1][i], t[lvl - 1][i + (1 << (lvl - 1))]);
	}

	int g_max(int l, int r) {
		int d = (r - l + 1);
		return max(t[lg[d]][l], t[lg[d]][r - (1 << lg[d]) + 1]);
	}
} sp_t[M];

bool can(int x) {
	forn(l, 1, n - x + 1) {
		int r = l + x - 1;
		ll sum = 0;
		forn(i, 1, m)
			sum += sp_t[i].g_max(l, r);
		if (sum <= k) return 1;
	}
	return 0;
}

void restore(int x) {
	if (x == 0) {
		forn(i, 1, m)
			cout << "0 ";
		cout << "\n";
	}
	forn(l, 1, n - x + 1) {
		int r = l + x - 1;
		ll sum = 0;
		forn(i, 1, m)
			sum += sp_t[i].g_max(l, r);
		if (sum > k) continue;
		forn(i, 1, m)
			cout << sp_t[i].g_max(l, r) << " ";
		cout << "\n";
		return 0;
	}
}

int main () {
#ifdef machine42
	freopen (file"in", "r", stdin);
	freopen (file"out", "w", stdout);
#endif
	ios_base :: sync_with_stdio (0);
	cin.tie(0);

	cin >> n >> m >> k;
	forn(i, 1, n)
		forn(j, 1, m)
			cin >> a[j][i];

	forn(i, 1, m)
		sp_t[i].init(n, a[i]);

	int l = 0, r = n, mid = 0;
	while (l < r) {
		mid = (l + r + 1) >> 1;
		if (can(mid)) l = mid;
		else r = mid - 1;
	}

    restore(l);

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define forn(i, x, n) for (int i = int(x); i <= int(n); ++i)
#define for1(i, n, x) for (int i = int(n); i >= int(x); --i)
#define file ""
#define x first
#define y second
#define pb push_back

typedef long long ll;
typedef pair <int, int> PII;
typedef const PII & pnt;

const int N = 3e5;
const int Log = 20;
const int M = 10;
const int INF = 1e9 + 9;

int n, m, k;
int a[M][N];

struct SparseTable {
	int n, t[Log][N], lg[N];

	void init(int _n, int *a) {
		n = _n;
		lg[1] = 0;
		forn(i, 2, n)
			lg[i] = lg[i / 2] + 1;
		forn(i, 1, n)
			t[0][i] = a[i];
		forn(lvl, 1, lg[n])
			forn(i, 1, n)
				t[lvl][i] = max(t[lvl - 1][i], t[lvl - 1][i + (1 << (lvl - 1))]);
	}

	int g_max(int l, int r) {
		int d = (r - l + 1);
		return max(t[lg[d]][l], t[lg[d]][r - (1 << lg[d]) + 1]);
	}
} sp_t[M];

bool can(int x) {
	forn(l, 1, n - x + 1) {
		int r = l + x - 1;
		int sum = 0;
		forn(i, 1, m)
			sum += sp_t[i].g_max(l, r);
		if (sum <= k) return 1;
	}
	return 0;
}

void restore(int x) {
	forn(l, 1, n - x + 1) {
		int r = l + x - 1;
		int sum = 0;
		forn(i, 1, m)
			sum += sp_t[i].g_max(l, r);
		if (sum > k) continue;
		forn(i, 1, m)
			cout << sp_t[i].g_max(l, r) << " ";
	}
	cout << "\n";
}

int main () {
#ifdef machine42
	freopen (file"in", "r", stdin);
	freopen (file"out", "w", stdout);
#endif
	ios_base :: sync_with_stdio (0);
	cin.tie(0);

	cin >> n >> m >> k;
	forn(i, 1, n)
		forn(j, 1, m)
			cin >> a[j][i];

	forn(i, 1, m)
		sp_t[i].init(n, a[i]);

	int l = 0, r = n, mid = 0;
	while (l < r) {
		mid = (l + r + 1) >> 1;
		if (can(mid)) l = mid;
		else r = mid - 1;
	}

    restore(l);

	return 0;
}