import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.SortedSet;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 *
 *
 * 3 2 3 5
 * -2 -1 4 -1 2 7 3
 *
 * 10 1 -10617 30886 -7223 -63085 47793 -61665 -14614 60492 16649 -58579 3 8 1
 * 10 4 7 1 7 3 7
 *
 * 22862 -34877
 *
 * @author pttrung
 */
public class D {

    public static long MOD = 1000000007;
    static double dp[][][][];

    public static void main(String[] args) throws FileNotFoundException {
        PrintWriter out;
        Scanner in = new Scanner();
        // out = new PrintWriter(new FileOutputStream(new File("output.txt")));
        out = new PrintWriter(System.out);

        int n = in.nextInt();
        int m = in.nextInt();
        int k = in.nextInt();
        int[][] data = new int[n][m];
        Node[] root = new Node[m];
        for (int i = 0; i < m; i++) {
            root[i] = new Node(0, n - 1, 0);
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                data[i][j] = in.nextInt();
                update(i, i, data[i][j], root[j]);
            }
        }
        int start = 0;
        int end = n;
        int result = 0;
        int index = -1;
        while (start <= end) {
            int mid = (start + end) >> 1;
            int succ = -1;
            for (int i = 0; i < n && succ == -1; i++) {
                if (i - mid + 1 >= 0) {
                    long total = 0;
                    for (int j = 0; j < m; j++) {
                        total += get(i - mid + 1, i, root[j]);
                    }
                    if (total <= k) {
                        succ = i;
                    }
                }
            }
            if (succ != -1) {
                if (result < mid) {
                    result = mid;
                    index = succ;
                }
                start = mid + 1;
            } else {
                end = mid - 1;
            }
        }
        if (result == 0) {
            out.print(k);
            for (int i = 1; i < m; i++) {
                out.print(" " + 0);
            }
        } else {
            for (int i = 0; i < m; i++) {
                out.print(get(index - result + 1, index, root[i]) + " ");
            }
        }
        out.close();
    }

    public static int get(int l, int h, Node node) {
        if (node == null) {
            return 0;
        }
        if (node.l > h || node.h < l) {
            return 0;
        }
        if (l <= node.l && node.h <= h) {
            return node.max;
        }

        int result = Math.max(get(l, h, node.left), get(l, h, node.right));
        return result;
    }

    public static void update(int l, int h, int v, Node node) {
        if (node.l > h || node.h < l) {
            return;
        }
        node.max = Math.max(v, node.max);
        if (l <= node.l && node.h <= h) {
            return;
        }
        int mid = (node.l + node.h) / 2;
        if (node.left == null) {
            node.left = new Node(node.l, mid, 0);
        }
        update(l, h, v, node.left);
        if (node.right == null) {
            node.right = new Node(mid + 1, node.h, 0);
        }
        update(l, h, v, node.right);

    }

    public static class Node {

        int l, h, max;
        Node left, right;

        public Node(int l, int h, int max) {
            this.l = l;
            this.h = h;
            this.max = max;
        }
    }

    public static int[] KMP(String val) {
        int i = 0;
        int j = -1;
        int[] result = new int[val.length() + 1];
        result[0] = -1;
        while (i < val.length()) {
            while (j >= 0 && val.charAt(j) != val.charAt(i)) {
                j = result[j];
            }
            j++;
            i++;
            result[i] = j;
        }
        return result;

    }

    public static boolean nextPer(int[] data) {
        int i = data.length - 1;
        while (i > 0 && data[i] < data[i - 1]) {
            i--;
        }
        if (i == 0) {
            return false;
        }
        int j = data.length - 1;
        while (data[j] < data[i - 1]) {
            j--;
        }
        int temp = data[i - 1];
        data[i - 1] = data[j];
        data[j] = temp;
        Arrays.sort(data, i, data.length);
        return true;
    }

    public static int digit(long n) {
        int result = 0;
        while (n > 0) {
            n /= 10;
            result++;
        }
        return result;
    }

    public static double dist(long a, long b, long x, long y) {
        double val = (b - a) * (b - a) + (x - y) * (x - y);
        val = Math.sqrt(val);
        double other = x * x + a * a;
        other = Math.sqrt(other);
        return val + other;

    }

    public static class Point implements Comparable<Point> {

        int x, y;

        public Point(int start, int end) {
            this.x = start;
            this.y = end;
        }

        @Override
        public int hashCode() {
            int hash = 5;
            hash = 47 * hash + this.x;
            hash = 47 * hash + this.y;
            return hash;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Point other = (Point) obj;
            if (this.x != other.x) {
                return false;
            }
            if (this.y != other.y) {
                return false;
            }
            return true;
        }

        @Override
        public int compareTo(Point o) {
            return x - o.x;
        }
    }

    public static class FT {

        long[] data;

        FT(int n) {
            data = new long[n];
        }

        public void update(int index, long value) {
            while (index < data.length) {
                data[index] += value;
                index += (index & (-index));
            }
        }

        public long get(int index) {
            long result = 0;
            while (index > 0) {
                result += data[index];
                index -= (index & (-index));
            }
            return result;

        }
    }

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

    public static long pow(long a, long b) {
        if (b == 0) {
            return 1;
        }
        if (b == 1) {
            return a;
        }
        long val = pow(a, b / 2);
        if (b % 2 == 0) {
            return val * val % MOD;
        } else {
            return val * (val * a % MOD) % MOD;

        }
    }

    static class Scanner {

        BufferedReader br;
        StringTokenizer st;

        public Scanner() throws FileNotFoundException {
            // System.setOut(new PrintStream(new BufferedOutputStream(System.out), true));
            br = new BufferedReader(new InputStreamReader(System.in));
            //  br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("input.txt"))));
        }

        public String next() {

            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (Exception e) {
                    throw new RuntimeException();
                }
            }
            return st.nextToken();
        }

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

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

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

        public String nextLine() {
            st = null;
            try {
                return br.readLine();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }

        public boolean endLine() {
            try {
                String next = br.readLine();
                while (next != null && next.trim().isEmpty()) {
                    next = br.readLine();
                }
                if (next == null) {
                    return true;
                }
                st = new StringTokenizer(next);
                return st.hasMoreTokens();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }
    }
}


//package codeforces;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

public class D {
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    PrintWriter writer = new PrintWriter(System.out);
    StringTokenizer stringTokenizer;

    String next() throws IOException {
        while (stringTokenizer == null || !stringTokenizer.hasMoreTokens()) {
            stringTokenizer = new StringTokenizer(reader.readLine());
        }
        return stringTokenizer.nextToken();
    }

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

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

    int MOD = 1000 * 1000 * 1000 + 7;

    int sum(int a, int b) {
        a += b;
        return a >= MOD ? a - MOD : a;
    }

    int product(int a, int b) {
        return (int) (1l * a * b % MOD);
    }

    @SuppressWarnings("unchecked")
    void solve() throws IOException {
        final int n = nextInt();
        int m = nextInt();
        int k = nextInt();
        class SegmentTree {
            int q = 1;
            {
                while(q <= n) {
                    q *= 2;
                }
            }
            int[] a = new int[2 * q];

            void update(int i, int x) {
                for(i += q; i > 0; i /= 2) {
                    a[i] = Math.max(a[i], x);
                }
            }

            int getMax(int l, int r) {
                int ret = 0;
                for(l += q, r += q; l < r; l /= 2, r /= 2) {
                    if(l % 2 == 1) {
                        ret = Math.max(ret, a[l++]);
                    }
                    if(r % 2 == 1) {
                        ret = Math.max(ret, a[--r]);
                    }
                }
                return ret;
            }
        }
        SegmentTree[] trees = new SegmentTree[m];
        for(int i = 0; i < m; i++) {
            trees[i] = new SegmentTree();
        }
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                trees[j].update(i, nextInt());
            }
        }
        int bestLen = 0;
        int[] shots = new int[m];
        Random r = new Random();
//        for(int i = 0; i < n; i++) {
        for(int o = 0; o < 10000; o++) {
            int i = r.nextInt(n);
            int lo = i, hi = n + 1;
            while(hi - lo > 1) {
                int med = lo + hi >> 1;
                int s = 0;
                for(int j = 0; j < m; j++) {
                    s += trees[j].getMax(i, med);
                }
                if(s <= k) {
                    lo = med;
                } else {
                    hi = med;
                }
            }
            if(lo - i > bestLen) {
                bestLen = lo - i;
                for(int j = 0; j < m; j++) {
                    shots[j] = trees[j].getMax(i, lo);
                }
            }
        }
        for (int shot : shots) {
            writer.print(shot + " ");
        }
        writer.close();
    }

    public static void main(String[] args) throws IOException {
//        new D().test();
        new D().solve();
    }
}


//package codeforces;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

public class D {
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    PrintWriter writer = new PrintWriter(System.out);
    StringTokenizer stringTokenizer;

    String next() throws IOException {
        while (stringTokenizer == null || !stringTokenizer.hasMoreTokens()) {
            stringTokenizer = new StringTokenizer(reader.readLine());
        }
        return stringTokenizer.nextToken();
    }

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

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

    int MOD = 1000 * 1000 * 1000 + 7;

    int sum(int a, int b) {
        a += b;
        return a >= MOD ? a - MOD : a;
    }

    int product(int a, int b) {
        return (int) (1l * a * b % MOD);
    }

    @SuppressWarnings("unchecked")
    void solve() throws IOException {
        final int n = nextInt();
        int m = nextInt();
        int k = nextInt();
        class SegmentTree {
            int q = 1;
            {
                while(q <= n) {
                    q *= 2;
                }
            }
            int[] a = new int[2 * q];

            void update(int i, int x) {
                for(i += q; i > 0; i /= 2) {
                    a[i] = Math.max(a[i], x);
                }
            }

            class CacheEntry {
                int l, r;

                CacheEntry(int l, int r) {
                    this.l = l;
                    this.r = r;
                }

                @Override
                public boolean equals(Object o) {
                    if (this == o) return true;
                    if (o == null || getClass() != o.getClass()) return false;

                    CacheEntry that = (CacheEntry) o;

                    if (l != that.l) return false;
                    if (r != that.r) return false;

                    return true;
                }

                @Override
                public int hashCode() {
                    int result = l;
                    result = 31 * result + r;
                    return result;
                }
            }

            final int cacheCap = 1 << 19;
            LinkedHashMap<CacheEntry, Integer> cache = new LinkedHashMap<>(cacheCap, .75f, true);
            void addToCache(CacheEntry ce, int val) {
                if(cache.size() == cacheCap) {
                    final Iterator<Map.Entry<CacheEntry, Integer>> iterator = cache.entrySet().iterator();
                    iterator.next();
                    iterator.remove();
                }
                cache.put(ce, val);
            }

            int max(int l, int r) {
                if(l >= r) return 0;
                CacheEntry ce = new CacheEntry(l, r);
                if(cache.containsKey(ce)) {
                    return cache.get(ce);
                }
                int ret = 0;
                if(l % 2 == 1) {
                    ret = Math.max(ret, a[l++]);
                }
                if(r % 2 == 1) {
                    ret = Math.max(ret, a[--r]);
                }
                ret = Math.max(ret, max(l / 2, r / 2));
                addToCache(ce, ret);
                return ret;
            }

            int getMax(int l, int r) {
                return max(l + q, r + q);
            }

//            int getMax(int l, int r) {
//                int ret = 0;
//                for(l += q, r += q; l < r; l /= 2, r /= 2) {
//                    if(l % 2 == 1) {
//                        ret = Math.max(ret, a[l++]);
//                    }
//                    if(r % 2 == 1) {
//                        ret = Math.max(ret, a[--r]);
//                    }
//                }
//                return ret;
//            }
        }
        SegmentTree[] trees = new SegmentTree[m];
        for(int i = 0; i < m; i++) {
            trees[i] = new SegmentTree();
        }
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                trees[j].update(i, nextInt());
            }
        }
        int bestLen = 0;
        int[] shots = new int[m];
        for(int i = 0; i < n; i++) {
            int lo = i, hi = n + 1;
            while(hi - lo > 1) {
                int med = lo + hi >> 1;
                int s = 0;
                for(int j = 0; j < m; j++) {
                    s += trees[j].getMax(i, med);
                }
                if(s <= k) {
                    lo = med;
                } else {
                    hi = med;
                }
            }
            if(lo - i > bestLen) {
                bestLen = lo - i;
                for(int j = 0; j < m; j++) {
                    shots[j] = trees[j].getMax(i, lo);
                }
            }
        }
        for (int shot : shots) {
            writer.print(shot + " ");
        }
        writer.close();
    }

    public static void main(String[] args) throws IOException {
//        new D().test();
        new D().solve();
    }
}


//package codeforces;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

public class D {
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    PrintWriter writer = new PrintWriter(System.out);
    StringTokenizer stringTokenizer;

    String next() throws IOException {
        while (stringTokenizer == null || !stringTokenizer.hasMoreTokens()) {
            stringTokenizer = new StringTokenizer(reader.readLine());
        }
        return stringTokenizer.nextToken();
    }

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

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

    int MOD = 1000 * 1000 * 1000 + 7;

    int sum(int a, int b) {
        a += b;
        return a >= MOD ? a - MOD : a;
    }

    int product(int a, int b) {
        return (int) (1l * a * b % MOD);
    }

    @SuppressWarnings("unchecked")
    void solve() throws IOException {
        final int n = nextInt();
        int m = nextInt();
        int k = nextInt();
        class SegmentTree {
            int q = 1;
            {
                while(q <= n) {
                    q *= 2;
                }
            }
            int[] a = new int[2 * q];

            void update(int i, int x) {
                for(i += q; i > 0; i /= 2) {
                    a[i] = Math.max(a[i], x);
                }
            }

            int getMax(int l, int r) {
                int ret = 0;
                for(l += q, r += q; l < r; l /= 2, r /= 2) {
                    if(l % 2 == 1) {
                        ret = Math.max(ret, a[l++]);
                    }
                    if(r % 2 == 1) {
                        ret = Math.max(ret, a[--r]);
                    }
                }
                return ret;
            }
        }
        SegmentTree[] trees = new SegmentTree[m];
        for(int i = 0; i < m; i++) {
            trees[i] = new SegmentTree();
        }
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                trees[j].update(i, nextInt());
            }
        }
        int bestLen = 0;
        int[] shots = new int[m];
        for(int i = 0; i < n; i++) {
            int lo = i, hi = n + 1;
            while(hi - lo > 1) {
                int med = lo + hi >> 1;
                int s = 0;
                for(int j = 0; j < m; j++) {
                    s += trees[j].getMax(i, med);
                }
                if(s <= k) {
                    lo = med;
                } else {
                    hi = med;
                }
            }
            if(lo - i > bestLen) {
                bestLen = lo - i;
                for(int j = 0; j < m; j++) {
                    shots[j] = trees[j].getMax(i, lo);
                }
            }
        }
        for (int shot : shots) {
            writer.print(shot + " ");
        }
        writer.close();
    }

    public static void main(String[] args) throws IOException {
//        new D().test();
        new D().solve();
    }
}


//package codeforces;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

public class D {
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    PrintWriter writer = new PrintWriter(System.out);
    StringTokenizer stringTokenizer;

    String next() throws IOException {
        while (stringTokenizer == null || !stringTokenizer.hasMoreTokens()) {
            stringTokenizer = new StringTokenizer(reader.readLine());
        }
        return stringTokenizer.nextToken();
    }

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

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

    int MOD = 1000 * 1000 * 1000 + 7;

    int sum(int a, int b) {
        a += b;
        return a >= MOD ? a - MOD : a;
    }

    int product(int a, int b) {
        return (int) (1l * a * b % MOD);
    }

    @SuppressWarnings("unchecked")
    void solve() throws IOException {
        final int n = nextInt();
        int m = nextInt();
        int k = nextInt();
        class SegmentTree {
            int q = 1;
            {
                while(q <= n) {
                    q *= 2;
                }
            }
            int[] a = new int[2 * q];

            void update(int i, int x) {
                for(i += q; i > 0; i /= 2) {
                    a[i] = Math.max(a[i], x);
                }
            }

            class CacheEntry {
                int l, r;

                CacheEntry(int l, int r) {
                    this.l = l;
                    this.r = r;
                }

                @Override
                public boolean equals(Object o) {
                    if (this == o) return true;
                    if (o == null || getClass() != o.getClass()) return false;

                    CacheEntry that = (CacheEntry) o;

                    if (l != that.l) return false;
                    if (r != that.r) return false;

                    return true;
                }

                @Override
                public int hashCode() {
                    int result = l;
                    result = 31 * result + r;
                    return result;
                }
            }

            final int cacheCap = 1 << 18;
            LinkedHashMap<CacheEntry, Integer> cache = new LinkedHashMap<>(cacheCap, .75f, true);
            void addToCache(CacheEntry ce, int val) {
                if(cache.size() == cacheCap) {
                    final Iterator<Map.Entry<CacheEntry, Integer>> iterator = cache.entrySet().iterator();
                    iterator.next();
                    iterator.remove();
                }
                cache.put(ce, val);
            }

            int max(int l, int r) {
                if(l >= r) return 0;
                CacheEntry ce = new CacheEntry(l, r);
                if(cache.containsKey(ce)) {
                    return cache.get(ce);
                }
                int ret = 0;
                if(l % 2 == 1) {
                    ret = Math.max(ret, a[l++]);
                }
                if(r % 2 == 1) {
                    ret = Math.max(ret, a[--r]);
                }
                ret = Math.max(ret, max(l / 2, r / 2));
                addToCache(ce, ret);
                return ret;
            }

            int getMax(int l, int r) {
                return max(l + q, r + q);
            }

//            int getMax(int l, int r) {
//                int ret = 0;
//                for(l += q, r += q; l < r; l /= 2, r /= 2) {
//                    if(l % 2 == 1) {
//                        ret = Math.max(ret, a[l++]);
//                    }
//                    if(r % 2 == 1) {
//                        ret = Math.max(ret, a[--r]);
//                    }
//                }
//                return ret;
//            }
        }
        SegmentTree[] trees = new SegmentTree[m];
        for(int i = 0; i < m; i++) {
            trees[i] = new SegmentTree();
        }
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                trees[j].update(i, nextInt());
            }
        }
        int bestLen = 0;
        int[] shots = new int[m];
        for(int i = 0; i < n; i++) {
            int lo = i, hi = n + 1;
            while(hi - lo > 1) {
                int med = lo + hi >> 1;
                int s = 0;
                for(int j = 0; j < m; j++) {
                    s += trees[j].getMax(i, med);
                }
                if(s <= k) {
                    lo = med;
                } else {
                    hi = med;
                }
            }
            if(lo - i > bestLen) {
                bestLen = lo - i;
                for(int j = 0; j < m; j++) {
                    shots[j] = trees[j].getMax(i, lo);
                }
            }
        }
        for (int shot : shots) {
            writer.print(shot + " ");
        }
        writer.close();
    }

    public static void main(String[] args) throws IOException {
//        new D().test();
        new D().solve();
    }
}


//package codeforces;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

public class D {
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    PrintWriter writer = new PrintWriter(System.out);
    StringTokenizer stringTokenizer;

    String next() throws IOException {
        while (stringTokenizer == null || !stringTokenizer.hasMoreTokens()) {
            stringTokenizer = new StringTokenizer(reader.readLine());
        }
        return stringTokenizer.nextToken();
    }

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

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

    int MOD = 1000 * 1000 * 1000 + 7;

    int sum(int a, int b) {
        a += b;
        return a >= MOD ? a - MOD : a;
    }

    int product(int a, int b) {
        return (int) (1l * a * b % MOD);
    }

    @SuppressWarnings("unchecked")
    void solve() throws IOException {
        final int n = nextInt();
        int m = nextInt();
        int k = nextInt();
        class SegmentTree {
            int q = 1;
            {
                while(q <= n) {
                    q *= 2;
                }
            }
            int[] a = new int[2 * q];

            void update(int i, int x) {
                for(i += q; i > 0; i /= 2) {
                    a[i] = Math.max(a[i], x);
                }
            }

            int getMax(int l, int r) {
                int ret = 0;
                for(l += q, r += q; l < r; l /= 2, r /= 2) {
                    if(l % 2 == 1) {
                        ret = Math.max(ret, a[l++]);
                    }
                    if(r % 2 == 1) {
                        ret = Math.max(ret, a[--r]);
                    }
                }
                return ret;
            }
        }
        SegmentTree[] trees = new SegmentTree[m];
        for(int i = 0; i < m; i++) {
            trees[i] = new SegmentTree();
        }
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                trees[j].update(i, nextInt());
            }
        }
        int bestLen = 0;
        int[] shots = new int[m];
        for(int i = 0; i < n; i++) {
            int lo = i, hi = n;
            while(hi - lo > 1) {
                int med = lo + hi >> 1;
                int s = 0;
                for(int j = 0; j < m; j++) {
                    s += trees[j].getMax(i, med);
                }
                if(s <= k) {
                    lo = med;
                } else {
                    hi = med;
                }
            }
            if(lo - i > bestLen) {
                bestLen = lo - i;
                for(int j = 0; j < m; j++) {
                    shots[j] = trees[j].getMax(i, lo);
                }
            }
        }
        for (int shot : shots) {
            writer.print(shot + " ");
        }
        writer.close();
    }

    public static void main(String[] args) throws IOException {
//        new D().test();
        new D().solve();
    }
}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.StringTokenizer;

/*
public class _514D {

}

 */

public class _514D {

	class node
	{
		public int num;
		public int ind;

		public node(int num, int ind)
		{
			super();
			this.num = num;
			this.ind = ind;
		}
	}

	public void solve() throws FileNotFoundException {
		InputStream inputStream = System.in;

		InputHelper inputHelper = new InputHelper(inputStream);

		PrintStream out = System.out;

		//actual solution
		int n = inputHelper.readInteger();
		int m = inputHelper.readInteger();
		int k = inputHelper.readInteger();

		int[][] a = new int[n][m];

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

		int[] mm = new int[m];
		int ck = 0;
		LinkedList[] mll = new LinkedList[m];
		int[] ans = new int[m];
		int ml;

		for(int i = 0; i < m; i++)
		{
			mm[i] = a[0][i];
			ck += a[0][i];
			mll[i] = new LinkedList<node>();
			mll[i].add(new node(mm[i], 0));
		}

		if(ck <= k)
		{
			ml = 1;
			for(int i = 0; i < m; i++)
			{
				ans[i] = mm[i];
			}
		}
		else
		{
			ml = 0;
		}

		for(int i = 0, j = 0; i < n;)
		{
			if((ck <= k || i == j) && j < n - 1)
			{
				j++;

				for(int l = 0; l < m; l++)
				{
					while(mll[l].size() > 0 && ((node)mll[l].getLast()).num <= a[j][l])
					{
						mll[l].removeLast();
					}

					mll[l].addLast(new node(a[j][l], j));
				}
			}
			else
			{
				i++;

				if(i < n)
				{
					for(int l = 0; l < m; l++)
					{
						while(mll[l].size() > 0 && ((node)mll[l].getFirst()).ind < i)
						{
							mll[l].removeFirst();
						}
					}
				}
				else
					continue;
			}

			int ckt = 0;
			for(int l = 0; l < m; l++)
			{
				ckt += ((node)mll[l].getFirst()).num;
			}

			ck = ckt;

			if(ck <= k && ml < (j - i + 1))
			{
				for(int l = 0; l < m; l++)
				{
					ans[l] = ((node)mll[l].getFirst()).num;
				}
				ml = j - i + 1;
			}
		}

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

		System.out.println();
		//end here
	}

	public static void main(String[] args) throws FileNotFoundException {
		(new _514D()).solve();
	}

	class InputHelper {
		StringTokenizer tokenizer = null;
		private BufferedReader bufferedReader;

		public InputHelper(InputStream inputStream) {
			InputStreamReader inputStreamReader = new InputStreamReader(
					inputStream);
			bufferedReader = new BufferedReader(inputStreamReader, 16384);
		}

		public String read() {
			while (tokenizer == null || !tokenizer.hasMoreTokens()) {
				try {
					String line = bufferedReader.readLine();
					if (line == null) {
						return null;
					}
					tokenizer = new StringTokenizer(line);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			return tokenizer.nextToken();
		}

		public Integer readInteger() {
			return Integer.parseInt(read());
		}

		public Long readLong() {
			return Long.parseLong(read());
		}
	}
}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.StringTokenizer;

/*
public class _514D {

}

 */

public class _514D {

	class node
	{
		public int num;
		public int ind;

		public node(int num, int ind)
		{
			super();
			this.num = num;
			this.ind = ind;
		}
	}

	public void solve() throws FileNotFoundException {
		InputStream inputStream = System.in;

		InputHelper inputHelper = new InputHelper(inputStream);

		PrintStream out = System.out;

		//actual solution
		int n = inputHelper.readInteger();
		int m = inputHelper.readInteger();
		int k = inputHelper.readInteger();

		int[][] a = new int[n][m];

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

		int[] mm = new int[m];
		int ck = 0;
		LinkedList[] mll = new LinkedList[m];

		for(int i = 0; i < m; i++)
		{
			mm[i] = a[0][i];
			ck += a[0][i];
			mll[i] = new LinkedList<node>();
			mll[i].add(new node(mm[i], 0));
		}

		int[] ans = new int[m];
		int ml;

		if(ck <= k)
		{
			ml = 1;
		}
		else
		{
			ml = 0;
		}

		for(int i = 0, j = 0; i < n;)
		{
			if((ck <= k || i == j) && j < n - 1)
			{
				j++;

				for(int l = 0; l < m; l++)
				{
					while(mll[l].size() > 0 && ((node)mll[l].getLast()).num <= a[j][l])
					{
						mll[l].removeLast();
					}

					mll[l].addLast(new node(a[j][l], j));
				}
			}
			else
			{
				i++;

				if(i < n)
				{
					for(int l = 0; l < m; l++)
					{
						while(mll[l].size() > 0 && ((node)mll[l].getFirst()).ind < i)
						{
							mll[l].removeFirst();
						}
					}
				}
			}

			int ckt = 0;
			for(int l = 0; l < m; l++)
			{
				ckt += ((node)mll[l].getFirst()).num;
			}

			ck = ckt;

			if(ck <= k && ml < (j - i + 1))
			{
				for(int l = 0; l < m; l++)
				{
					ans[l] = ((node)mll[l].getFirst()).num;
				}
				ml = j - i + 1;
			}
		}

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

		System.out.println();
		//end here
	}

	public static void main(String[] args) throws FileNotFoundException {
		(new _514D()).solve();
	}

	class InputHelper {
		StringTokenizer tokenizer = null;
		private BufferedReader bufferedReader;

		public InputHelper(InputStream inputStream) {
			InputStreamReader inputStreamReader = new InputStreamReader(
					inputStream);
			bufferedReader = new BufferedReader(inputStreamReader, 16384);
		}

		public String read() {
			while (tokenizer == null || !tokenizer.hasMoreTokens()) {
				try {
					String line = bufferedReader.readLine();
					if (line == null) {
						return null;
					}
					tokenizer = new StringTokenizer(line);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			return tokenizer.nextToken();
		}

		public Integer readInteger() {
			return Integer.parseInt(read());
		}

		public Long readLong() {
			return Long.parseLong(read());
		}
	}
}


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

public class Main{
    final boolean isFileIO =  false;
    BufferedReader in;
    PrintWriter out;
    StringTokenizer st = new StringTokenizer("");
    String delim = " ";

    public static void main(String[] args) throws IOException {
        Main m = new Main();
        m.initIO();
        m.solve();
        m.in.close();
        m.out.close();
    }

    public void initIO() throws IOException {
        if(!isFileIO) {
            in = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out);
        } else {
            in = new BufferedReader(new FileReader("input.txt"));
            out = new PrintWriter("output.txt");
        }
    }

    String nt() throws IOException {
        if(!st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken(delim);
    }

    String rl() throws IOException {
        return in.readLine();
    }

    int ni() throws IOException {
        return Integer.parseInt(nt());
    }

    long nl() throws IOException {
        return Long.parseLong(nt());
    }

    double nd() throws IOException {
        return Double.parseDouble(nt());
    }

    class Pair {
        public int x, y;
        public Pair(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

    class SparseTable {

        int[][] a;
        int[] log;
        int height;
        public SparseTable(int[] b) {
            int n = b.length;
            log = new int[n + 1];
            for(int i = 1; i <= n; i++) {
                int pow = 0;
                do {
                    log[i] = pow;
                    ++pow;
                } while((1 << pow) < i);
            }
            this.height = log[n] + 1;
            a = new int[this.height][n];
            for(int i = 0; i < n; i++) {
                a[0][i] = b[i];
            }
            for(int i = 1; i < height; i++) {
                int rem = (1 << i) - 1;
                for(int j = 0; j < n - rem; j++) {
                    a[i][j] = Math.max(a[i - 1][j], a[i - 1][j + 1]);
                }
            }

        }

        public int getMax(int left, int right) {
            int pow = log[(right - left + 1)];
            return Math.max(a[pow][left],
                    a[pow][right - (1 << pow) + 1]);
        }

    }

    class SegmentTree {
        int[] a;
        int size = 0;
        public int leafs;
        public SegmentTree(int[] b) {
            int n = b.length;
            int leafs = 1;
            while(leafs < n) {
                leafs *= 2;
            }
            size = leafs * 2 - 1;
            a = new int[size];
            this.leafs = leafs;
            for(int i = leafs - 1; i < leafs - 1 + n; i++) {
                a[i] = b[i - leafs + 1];
            }
            for(int i = leafs - 1 + n; i < size; i++) {
                a[i] = Integer.MIN_VALUE;
            }
            for(int i = leafs - 2; i >= 0; i--) {
                a[i] = Math.max(a[i * 2 + 1], a[i * 2 + 2]);
            }
        }

        public int getMax(int treeLeft, int treeRight, int queryLeft, int queryRight, int node) {
            if(queryLeft > queryRight) {
                return Integer.MIN_VALUE;
            }
            if(treeLeft == queryLeft && treeRight == queryRight) {
                return a[node];
            }
            int mid = treeLeft + (treeRight - treeLeft) / 2;
            return Math.max(getMax(treeLeft, mid, queryLeft, Math.min(mid, queryRight), node * 2 + 1),
                    getMax(mid + 1, treeRight, Math.max(queryLeft, mid + 1), queryRight, node * 2 + 2));
        }

    }

    public void solve() throws IOException {
        int n, m, k;
        n = ni(); m = ni(); k = ni();
        int[][] a = new int[m][n];
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                a[j][i] = ni();
            }
        }
        SparseTable[] sts = new SparseTable[m];
        for(int i = 0; i < m; i++) {
            sts[i] = new SparseTable(a[i]);
        }
        int left, right, mid, sum;
        left = right = mid = sum = 0;
        int total = 0;
        int[] res = new int[m];
        for(int i = 0; i < n; i++) {
            left = 1;
            right = i + 1;
            mid = 0;
            while(left < right) {
                mid = left + (right - left) / 2;
                sum = 0;
                for(int j = 0; j < m; j++) {
                    sum += sts[j].getMax(i - mid + 1, i);
                }
                if(sum <= k) {
                    left = mid + 1;
                } else {
                    right = mid;
                }
            }
            sum = 0;
            for(int j = 0; j < m; j++) {
                sum += sts[j].getMax(i - left + 1, i);
            }
            if(sum > k) {
                left--;
            }
            if(left == 0) {
                continue;
            }
            sum = 0;
            for(int j = 0; j < m; j++) {
                sum += sts[j].getMax(i - left + 1, i);
            }
            if(left > total && sum <= k) {
                for(int j = 0; j < m; j++) {
                    res[j] = sts[j].getMax(i - left + 1, i);
                }
                total = left;
            }
        }
        for(int i = 0; i < m; i++) {
            out.print(res[i] + " ");
        }

    }
}

class Utils {

    public static long binpow(long a, long exp, long mod) {
        if(exp == 0) {
            return 1;
        }
        if(exp % 2 == 0) {
            long temp = binpow(a, exp / 2, mod);
            return (temp * temp) % mod;
        } else {
            return (binpow(a, exp - 1, mod) * a) % mod;
        }
    }

    public static long inv(long a, long mod) {
        return binpow(a, mod - 2, mod);
    }

    public static long addmod(long a, long b, long mod) {
        return ((a + b) % mod + mod) % mod;
    }

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

    //mul must be < 10^18
    public static long mulmod(long a, long b, long mod) {
        return (a * b + (((a * b) / mod) + 1) * mod) % mod;
    }
}


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

public class Main{
    final boolean isFileIO =  false;
    BufferedReader in;
    PrintWriter out;
    StringTokenizer st = new StringTokenizer("");
    String delim = " ";

    public static void main(String[] args) throws IOException {
        Main m = new Main();
        m.initIO();
        m.solve();
        m.in.close();
        m.out.close();
    }

    public void initIO() throws IOException {
        if(!isFileIO) {
            in = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out);
        } else {
            in = new BufferedReader(new FileReader("input.txt"));
            out = new PrintWriter("output.txt");
        }
    }

    String nt() throws IOException {
        if(!st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken(delim);
    }

    String rl() throws IOException {
        return in.readLine();
    }

    int ni() throws IOException {
        return Integer.parseInt(nt());
    }

    long nl() throws IOException {
        return Long.parseLong(nt());
    }

    double nd() throws IOException {
        return Double.parseDouble(nt());
    }

    class Pair {
        public int x, y;
        public Pair(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

    class SegmentTree {
        int[] a;
        int size = 0;
        public SegmentTree(int[] b) {
            int n = b.length;
            int leafs = 1;
            while(leafs < n) {
                leafs *= 2;
            }
            size = leafs * 2 - 1;
            a = new int[size];
            for(int i = leafs - 1; i < leafs - 1 + n; i++) {
                a[i] = b[i - leafs + 1];
            }
            for(int i = leafs - 1 + n; i < size; i++) {
                a[i] = Integer.MIN_VALUE;
            }
            for(int i = leafs - 2; i >= 0; i--) {
                a[i] = Math.max(a[i * 2 + 1], a[i * 2 + 2]);
            }
        }

        public int getMax(int treeLeft, int treeRight, int queryLeft, int queryRight, int node) {
            if(queryLeft > queryRight) {
                return Integer.MIN_VALUE;
            }
            if(treeLeft == queryLeft && treeRight == queryRight) {
                return a[node];
            }
            int mid = treeLeft + (treeRight - treeLeft) / 2;
            return Math.max(getMax(treeLeft, mid, queryLeft, Math.min(mid, queryRight), node * 2 + 1),
                    getMax(mid + 1, treeRight, Math.max(queryLeft, mid + 1), queryRight, node * 2 + 2));
        }

    }

    public void solve() throws IOException {
        int n, m, k;
        n = ni(); m = ni(); k = ni();
        int[][] a = new int[m][n];
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                a[j][i] = ni();
            }
        }
        SegmentTree[] sts = new SegmentTree[m];
        for(int i = 0; i < m; i++) {
            sts[i] = new SegmentTree(a[i]);
        }
        int left, right, mid, sum;
        left = right = mid = sum = 0;
        int total = 0;
        int[] res = new int[m];
        for(int i = 0; i < n; i++) {
            left = 1;
            right = i + 1;
            mid = 0;
            while(left < right) {
                mid = left + (right - left) / 2;
                sum = 0;
                for(int j = 0; j < m; j++) {
                    sum += sts[j].getMax(0, n - 1, i - mid + 1, i, 0);
                }
                if(sum <= k) {
                    left = mid + 1;
                } else {
                    right = mid;
                }
            }
            sum = 0;
            for(int j = 0; j < m; j++) {
                sum += sts[j].getMax(0, n - 1, i - left + 1, i, 0);
            }
            if(sum > k) {
                left--;
            }
            sum = 0;
            for(int j = 0; j < m; j++) {
                sum += sts[j].getMax(0, n - 1, i - left + 1, i, 0);
            }
            if(left > total && sum <= k) {
                for(int j = 0; j < m; j++) {
                    res[j] = sts[j].getMax(0, n - 1, i - left + 1, i, 0);
                }
                total = left;
            }
        }
        for(int i = 0; i < m; i++) {
            out.print(res[i] + " ");
        }

    }
}

class Utils {

    public static long binpow(long a, long exp, long mod) {
        if(exp == 0) {
            return 1;
        }
        if(exp % 2 == 0) {
            long temp = binpow(a, exp / 2, mod);
            return (temp * temp) % mod;
        } else {
            return (binpow(a, exp - 1, mod) * a) % mod;
        }
    }

    public static long inv(long a, long mod) {
        return binpow(a, mod - 2, mod);
    }

    public static long addmod(long a, long b, long mod) {
        return ((a + b) % mod + mod) % mod;
    }

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

    //mul must be < 10^18
    public static long mulmod(long a, long b, long mod) {
        return (a * b + (((a * b) / mod) + 1) * mod) % mod;
    }
}


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

public class Main{
    final boolean isFileIO =  false;
    BufferedReader in;
    PrintWriter out;
    StringTokenizer st = new StringTokenizer("");
    String delim = " ";

    public static void main(String[] args) throws IOException {
        Main m = new Main();
        m.initIO();
        m.solve();
        m.in.close();
        m.out.close();
    }

    public void initIO() throws IOException {
        if(!isFileIO) {
            in = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out);
        } else {
            in = new BufferedReader(new FileReader("input.txt"));
            out = new PrintWriter("output.txt");
        }
    }

    String nt() throws IOException {
        if(!st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken(delim);
    }

    String rl() throws IOException {
        return in.readLine();
    }

    int ni() throws IOException {
        return Integer.parseInt(nt());
    }

    long nl() throws IOException {
        return Long.parseLong(nt());
    }

    double nd() throws IOException {
        return Double.parseDouble(nt());
    }

    class Pair {
        public int x, y;
        public Pair(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

    class SparseTable {

        int[][] a;
        int[] log;
        int height;
        public SparseTable(int[] b) {
            int n = b.length;
            log = new int[n + 1];
            for(int i = 1; i <= n; i++) {
                for(int j = 0; j < 20; j++) {
                    if((1 << j) <= i) {
                        log[i] = j;
                    }
                }
            }
            this.height = log[n] + 1;
            a = new int[this.height][n];
            for(int i = 0; i < n; i++) {
                a[0][i] = b[i];
            }
            for(int i = 1; i < height; i++) {
                int rem = (1 << i) - 1;
                for(int j = 0; j < n - rem; j++) {
                    a[i][j] = Math.max(a[i - 1][j], a[i - 1][j + 1]);
                }
            }

        }

        public int getMax(int left, int right) {
            int pow = log[(right - left + 1)];
            return Math.max(a[pow][left],
                    a[pow][right - (1 << pow) + 1]);
        }

    }

    class SegmentTree {
        int[] a;
        int size = 0;
        public int leafs;
        public SegmentTree(int[] b) {
            int n = b.length;
            int leafs = 1;
            while(leafs < n) {
                leafs *= 2;
            }
            size = leafs * 2 - 1;
            a = new int[size];
            this.leafs = leafs;
            for(int i = leafs - 1; i < leafs - 1 + n; i++) {
                a[i] = b[i - leafs + 1];
            }
            for(int i = leafs - 1 + n; i < size; i++) {
                a[i] = Integer.MIN_VALUE;
            }
            for(int i = leafs - 2; i >= 0; i--) {
                a[i] = Math.max(a[i * 2 + 1], a[i * 2 + 2]);
            }
        }

        public int getMax(int treeLeft, int treeRight, int queryLeft, int queryRight, int node) {
            if(queryLeft > queryRight) {
                return Integer.MIN_VALUE;
            }
            if(treeLeft == queryLeft && treeRight == queryRight) {
                return a[node];
            }
            int mid = treeLeft + (treeRight - treeLeft) / 2;
            return Math.max(getMax(treeLeft, mid, queryLeft, Math.min(mid, queryRight), node * 2 + 1),
                    getMax(mid + 1, treeRight, Math.max(queryLeft, mid + 1), queryRight, node * 2 + 2));
        }

    }

    public void solve() throws IOException {
        int n, m, k;
        n = ni(); m = ni(); k = ni();
        int[][] a = new int[m][n];
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                a[j][i] = ni();
            }
        }
        SparseTable[] sts = new SparseTable[m];
        for(int i = 0; i < m; i++) {
            sts[i] = new SparseTable(a[i]);
        }
        int left, right, mid, sum;
        left = right = mid = sum = 0;
        int total = 0;
        int[] res = new int[m];
        for(int i = 0; i < n; i++) {
            left = 1;
            right = i + 1;
            mid = 0;
            while(left < right) {
                mid = left + (right - left) / 2;
                sum = 0;
                for(int j = 0; j < m; j++) {
                    sum += sts[j].getMax(i - mid + 1, i);
                }
                if(sum <= k) {
                    left = mid + 1;
                } else {
                    right = mid;
                }
            }
            sum = 0;
            for(int j = 0; j < m; j++) {
                sum += sts[j].getMax(i - left + 1, i);
            }
            if(sum > k) {
                left--;
            }
            if(left == 0) {
                continue;
            }
            sum = 0;
            for(int j = 0; j < m; j++) {
                sum += sts[j].getMax(i - left + 1, i);
            }
            if(left > total && sum <= k) {
                for(int j = 0; j < m; j++) {
                    res[j] = sts[j].getMax(i - left + 1, i);
                }
                total = left;
            }
        }
        for(int i = 0; i < m; i++) {
            out.print(res[i] + " ");
        }

    }
}

class Utils {

    public static long binpow(long a, long exp, long mod) {
        if(exp == 0) {
            return 1;
        }
        if(exp % 2 == 0) {
            long temp = binpow(a, exp / 2, mod);
            return (temp * temp) % mod;
        } else {
            return (binpow(a, exp - 1, mod) * a) % mod;
        }
    }

    public static long inv(long a, long mod) {
        return binpow(a, mod - 2, mod);
    }

    public static long addmod(long a, long b, long mod) {
        return ((a + b) % mod + mod) % mod;
    }

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

    //mul must be < 10^18
    public static long mulmod(long a, long b, long mod) {
        return (a * b + (((a * b) / mod) + 1) * mod) % mod;
    }
}


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

public class Main{
    final boolean isFileIO =  false;
    BufferedReader in;
    PrintWriter out;
    StringTokenizer st = new StringTokenizer("");
    String delim = " ";

    public static void main(String[] args) throws IOException {
        Main m = new Main();
        m.initIO();
        m.solve();
        m.in.close();
        m.out.close();
    }

    public void initIO() throws IOException {
        if(!isFileIO) {
            in = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out);
        } else {
            in = new BufferedReader(new FileReader("input.txt"));
            out = new PrintWriter("output.txt");
        }
    }

    String nt() throws IOException {
        if(!st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken(delim);
    }

    String rl() throws IOException {
        return in.readLine();
    }

    int ni() throws IOException {
        return Integer.parseInt(nt());
    }

    long nl() throws IOException {
        return Long.parseLong(nt());
    }

    double nd() throws IOException {
        return Double.parseDouble(nt());
    }

    class Pair {
        public int x, y;
        public Pair(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

    class SegmentTree {
        int[] a;
        int size = 0;
        public int leafs;
        public SegmentTree(int[] b) {
            int n = b.length;
            int leafs = 1;
            while(leafs < n) {
                leafs *= 2;
            }
            size = leafs * 2 - 1;
            a = new int[size];
            this.leafs = leafs;
            for(int i = leafs - 1; i < leafs - 1 + n; i++) {
                a[i] = b[i - leafs + 1];
            }
            for(int i = leafs - 1 + n; i < size; i++) {
                a[i] = Integer.MIN_VALUE;
            }
            for(int i = leafs - 2; i >= 0; i--) {
                a[i] = Math.max(a[i * 2 + 1], a[i * 2 + 2]);
            }
        }

        public int getMax(int treeLeft, int treeRight, int queryLeft, int queryRight, int node) {
            if(queryLeft > queryRight) {
                return Integer.MIN_VALUE;
            }
            if(treeLeft == queryLeft && treeRight == queryRight) {
                return a[node];
            }
            int mid = treeLeft + (treeRight - treeLeft) / 2;
            return Math.max(getMax(treeLeft, mid, queryLeft, Math.min(mid, queryRight), node * 2 + 1),
                    getMax(mid + 1, treeRight, Math.max(queryLeft, mid + 1), queryRight, node * 2 + 2));
        }

    }

    public void solve() throws IOException {
        int n, m, k;
        n = ni(); m = ni(); k = ni();
        int[][] a = new int[m][n];
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                a[j][i] = ni();
            }
        }
        SegmentTree[] sts = new SegmentTree[m];
        for(int i = 0; i < m; i++) {
            sts[i] = new SegmentTree(a[i]);
        }
        int left, right, mid, sum;
        left = right = mid = sum = 0;
        int total = 0;
        int[] res = new int[m];
        for(int i = 0; i < n; i++) {
            out.println("i" + i);
            left = 1;
            right = i + 1;
            mid = 0;
            while(left < right) {
                mid = left + (right - left) / 2;
                sum = 0;
                for(int j = 0; j < m; j++) {
                    sum += sts[j].getMax(0, sts[j].leafs - 1, i - mid + 1, i, 0);
                }
                out.println(mid + " " + sum);
                if(sum <= k) {
                    left = mid + 1;
                } else {
                    right = mid;
                }
            }
            sum = 0;
            for(int j = 0; j < m; j++) {
                sum += sts[j].getMax(0, sts[j].leafs - 1, i - left + 1, i, 0);
            }
            if(sum > k) {
                left--;
            }
            sum = 0;
            for(int j = 0; j < m; j++) {
                sum += sts[j].getMax(0, sts[j].leafs - 1, i - left + 1, i, 0);
            }
            if(left > total && sum <= k) {
                for(int j = 0; j < m; j++) {
                    res[j] = sts[j].getMax(0, sts[j].leafs - 1, i - left + 1, i, 0);
                }
                total = left;
            }
        }
        for(int i = 0; i < m; i++) {
            out.print(res[i] + " ");
        }

    }
}

class Utils {

    public static long binpow(long a, long exp, long mod) {
        if(exp == 0) {
            return 1;
        }
        if(exp % 2 == 0) {
            long temp = binpow(a, exp / 2, mod);
            return (temp * temp) % mod;
        } else {
            return (binpow(a, exp - 1, mod) * a) % mod;
        }
    }

    public static long inv(long a, long mod) {
        return binpow(a, mod - 2, mod);
    }

    public static long addmod(long a, long b, long mod) {
        return ((a + b) % mod + mod) % mod;
    }

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

    //mul must be < 10^18
    public static long mulmod(long a, long b, long mod) {
        return (a * b + (((a * b) / mod) + 1) * mod) % mod;
    }
}


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

public class Main{
    final boolean isFileIO =  false;
    BufferedReader in;
    PrintWriter out;
    StringTokenizer st = new StringTokenizer("");
    String delim = " ";

    public static void main(String[] args) throws IOException {
        Main m = new Main();
        m.initIO();
        m.solve();
        m.in.close();
        m.out.close();
    }

    public void initIO() throws IOException {
        if(!isFileIO) {
            in = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out);
        } else {
            in = new BufferedReader(new FileReader("input.txt"));
            out = new PrintWriter("output.txt");
        }
    }

    String nt() throws IOException {
        if(!st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken(delim);
    }

    String rl() throws IOException {
        return in.readLine();
    }

    int ni() throws IOException {
        return Integer.parseInt(nt());
    }

    long nl() throws IOException {
        return Long.parseLong(nt());
    }

    double nd() throws IOException {
        return Double.parseDouble(nt());
    }

    class Pair {
        public int x, y;
        public Pair(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

    class SegmentTree {
        int[] a;
        int size = 0;
        public SegmentTree(int[] b) {
            int n = b.length;
            int leafs = 1;
            while(leafs < n) {
                leafs *= 2;
            }
            size = leafs * 2 - 1;
            a = new int[size];
            for(int i = leafs - 1; i < leafs - 1 + n; i++) {
                a[i] = b[i - leafs + 1];
            }
            for(int i = leafs - 1 + n; i < size; i++) {
                a[i] = Integer.MIN_VALUE;
            }
            for(int i = leafs - 2; i >= 0; i--) {
                a[i] = Math.max(a[i * 2 + 1], a[i * 2 + 2]);
            }
        }

        public int getMax(int treeLeft, int treeRight, int queryLeft, int queryRight, int node) {
            if(queryLeft > queryRight) {
                return Integer.MIN_VALUE;
            }
            if(treeLeft == queryLeft && treeRight == queryRight) {
                return a[node];
            }
            int mid = treeLeft + (treeRight - treeLeft) / 2;
            return Math.max(getMax(treeLeft, mid, queryLeft, Math.min(mid, queryRight), node * 2 + 1),
                    getMax(mid + 1, treeRight, Math.max(queryLeft, mid + 1), queryRight, node * 2 + 2));
        }

    }

    public void solve() throws IOException {
        int n, m, k;
        n = ni(); m = ni(); k = ni();
        int[][] a = new int[m][n];
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                a[j][i] = ni();
            }
        }
        SegmentTree[] sts = new SegmentTree[m];
        for(int i = 0; i < m; i++) {
            sts[i] = new SegmentTree(a[i]);
        }
        int left, right, mid, sum;
        left = right = mid = sum = 0;
        int total = 0;
        int[] res = new int[m];
        for(int i = 0; i < n; i++) {
            left = 1;
            right = i + 1;
            mid = 0;
            while(left < right) {
                mid = left + (right - left) / 2;
                sum = 0;
                for(int j = 0; j < m; j++) {
                    sum += sts[j].getMax(0, n - 1, i - mid + 1, i, 0);
                }
                if(sum <= k) {
                    left = mid + 1;
                } else {
                    right = mid;
                }
            }
            sum = 0;
            for(int j = 0; j < m; j++) {
                sum += sts[j].getMax(0, n - 1, i - left + 1, i, 0);
            }
            if(sum > k) {
                left--;
            }
            if(left > total) {
                for(int j = 0; j < m; j++) {
                    res[j] = sts[j].getMax(0, n - 1, i - left + 1, i, 0);
                }
                total = left;
            }
        }
        for(int i = 0; i < m; i++) {
            out.print(res[i] + " ");
        }

    }
}

class Utils {

    public static long binpow(long a, long exp, long mod) {
        if(exp == 0) {
            return 1;
        }
        if(exp % 2 == 0) {
            long temp = binpow(a, exp / 2, mod);
            return (temp * temp) % mod;
        } else {
            return (binpow(a, exp - 1, mod) * a) % mod;
        }
    }

    public static long inv(long a, long mod) {
        return binpow(a, mod - 2, mod);
    }

    public static long addmod(long a, long b, long mod) {
        return ((a + b) % mod + mod) % mod;
    }

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

    //mul must be < 10^18
    public static long mulmod(long a, long b, long mod) {
        return (a * b + (((a * b) / mod) + 1) * mod) % mod;
    }
}


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

public class Main{
    final boolean isFileIO =  false;
    BufferedReader in;
    PrintWriter out;
    StringTokenizer st = new StringTokenizer("");
    String delim = " ";

    public static void main(String[] args) throws IOException {
        Main m = new Main();
        m.initIO();
        m.solve();
        m.in.close();
        m.out.close();
    }

    public void initIO() throws IOException {
        if(!isFileIO) {
            in = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out);
        } else {
            in = new BufferedReader(new FileReader("input.txt"));
            out = new PrintWriter("output.txt");
        }
    }

    String nt() throws IOException {
        if(!st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken(delim);
    }

    String rl() throws IOException {
        return in.readLine();
    }

    int ni() throws IOException {
        return Integer.parseInt(nt());
    }

    long nl() throws IOException {
        return Long.parseLong(nt());
    }

    double nd() throws IOException {
        return Double.parseDouble(nt());
    }

    class Pair {
        public int x, y;
        public Pair(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

    class SparseTable {

        int[][] a;
        int[] log;
        int height;
        public SparseTable(int[] b) {
            int n = b.length;
            log = new int[n + 1];
            for(int i = 1; i <= n; i++) {
                for(int j = 0; j < 20; j++) {
                    if((1 << j) <= i) {
                        log[i] = j;
                    }
                }
            }
            this.height = log[n] + 1;
            a = new int[this.height][n];
            for(int i = 0; i < n; i++) {
                a[0][i] = b[i];
            }
            for(int i = 1; i < height; i++) {
                int rem = (1 << i) - 1;
                for(int j = 0; j < n - rem; j++) {
                    a[i][j] = Math.max(a[i - 1][j], a[i - 1][j + (1 << (i - 1))]);
                }
            }

        }

        public int getMax(int left, int right) {
            int pow = log[(right - left + 1)];
            return Math.max(a[pow][left],
                    a[pow][right - (1 << pow) + 1]);
        }

    }

    class SegmentTree {
        int[] a;
        int size = 0;
        public int leafs;
        public SegmentTree(int[] b) {
            int n = b.length;
            int leafs = 1;
            while(leafs < n) {
                leafs *= 2;
            }
            size = leafs * 2 - 1;
            a = new int[size];
            this.leafs = leafs;
            for(int i = leafs - 1; i < leafs - 1 + n; i++) {
                a[i] = b[i - leafs + 1];
            }
            for(int i = leafs - 1 + n; i < size; i++) {
                a[i] = Integer.MIN_VALUE;
            }
            for(int i = leafs - 2; i >= 0; i--) {
                a[i] = Math.max(a[i * 2 + 1], a[i * 2 + 2]);
            }
        }

        public int getMax(int treeLeft, int treeRight, int queryLeft, int queryRight, int node) {
            if(queryLeft > queryRight) {
                return Integer.MIN_VALUE;
            }
            if(treeLeft == queryLeft && treeRight == queryRight) {
                return a[node];
            }
            int mid = treeLeft + (treeRight - treeLeft) / 2;
            return Math.max(getMax(treeLeft, mid, queryLeft, Math.min(mid, queryRight), node * 2 + 1),
                    getMax(mid + 1, treeRight, Math.max(queryLeft, mid + 1), queryRight, node * 2 + 2));
        }

    }

    public void solve() throws IOException {
        int n, m, k;
        n = ni(); m = ni(); k = ni();
        int[][] a = new int[m][n];
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                a[j][i] = ni();
            }
        }
        SparseTable[] sts = new SparseTable[m];
        for(int i = 0; i < m; i++) {
            sts[i] = new SparseTable(a[i]);
        }
        int left, right, mid, sum;
        left = right = mid = sum = 0;
        int total = 0;
        int[] res = new int[m];
        for(int i = 0; i < n; i++) {
            left = 1;
            right = i + 1;
            mid = 0;
            while(left < right) {
                mid = left + (right - left) / 2;
                sum = 0;
                for(int j = 0; j < m; j++) {
                    sum += sts[j].getMax(i - mid + 1, i);
                }
                if(sum <= k) {
                    left = mid + 1;
                } else {
                    right = mid;
                }
            }
            sum = 0;
            for(int j = 0; j < m; j++) {
                sum += sts[j].getMax(i - left + 1, i);
            }
            if(sum > k) {
                left--;
            }
            if(left == 0) {
                continue;
            }
            sum = 0;
            for(int j = 0; j < m; j++) {
                sum += sts[j].getMax(i - left + 1, i);
            }
            if(left > total && sum <= k) {
                for(int j = 0; j < m; j++) {
                    res[j] = sts[j].getMax(i - left + 1, i);
                }
                total = left;
            }
        }
        for(int i = 0; i < m; i++) {
            out.print(res[i] + " ");
        }

    }
}

class Utils {

    public static long binpow(long a, long exp, long mod) {
        if(exp == 0) {
            return 1;
        }
        if(exp % 2 == 0) {
            long temp = binpow(a, exp / 2, mod);
            return (temp * temp) % mod;
        } else {
            return (binpow(a, exp - 1, mod) * a) % mod;
        }
    }

    public static long inv(long a, long mod) {
        return binpow(a, mod - 2, mod);
    }

    public static long addmod(long a, long b, long mod) {
        return ((a + b) % mod + mod) % mod;
    }

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

    //mul must be < 10^18
    public static long mulmod(long a, long b, long mod) {
        return (a * b + (((a * b) / mod) + 1) * mod) % mod;
    }
}


//package round291;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class D {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni(), m = ni(), K = ni();
		int[][] co = new int[n][];
		int o = 100000000;
		for(int i =0;i < n;i++){
			co[i] = na(m);
		}

		int[][][] sps = new int[m][][];
		int[] b = new int[n];
		for(int i = 0;i < m;i++){
			for(int j = 0;j < n;j++){
				b[j] = o-co[j][i];
			}
			sps[i] = build(b);
		}

		int maxlen = 0;
		long[] ns = new long[m];
		for(int i = 0;i < n;i++){
			int low = i-1, high = n;
			while(high - low > 1){
				int h = high+low>>>1;
				long need = 0;
				for(int j = 0;j < m;j++){
					need += o-rmq(sps[j], i, h+1);
				}
				if(need <= K){
					low = h;
				}else{
					high = h;
				}
			}
			if(low-i+1 > maxlen){
				maxlen = low-i+1;
				for(int j = 0;j < m;j++){
					ns[j] = o-rmq(sps[j], i, low+1);
				}
			}
		}
		for(long x : ns){
			out.print(x + " ");
		}
		out.println();
	}

	/// start

	public static int[][] build(int[] a)
	{
		int n = a.length;
		int b = 32-Integer.numberOfLeadingZeros(n);
		int[][] ret = new int[b][];
		for(int i = 0, l = 1;i < b;i++, l*=2) {
			if(i == 0) {
				ret[i] = Arrays.copyOf(a, a.length);
			}else {
				ret[i] = new int[n-l+1];
				for(int j = 0;j < n-l+1;j++) {
					ret[i][j] = Math.min(ret[i-1][j], ret[i-1][j+l/2]);
				}
			}
		}
		return ret;
	}

	public static int rmq(int[][] or, int a, int b)
	{
		// 1:0, 2:1, 3:1, 4:2, 5:2, 6:2, 7:2, 8:3
		int t = 31-Integer.numberOfLeadingZeros(b-a);
		return Math.min(or[t][a], or[t][b-(1<<t)]);
	}

	/// end

	void run() throws Exception
	{
//		int n = 1, m = 1;
//		Random gen = new Random();
//		StringBuilder sb = new StringBuilder();
//		sb.append(n + " ");
//		sb.append(m + " ");
//		sb.append(1000000000+ " ");
//		for (int i = 0; i < n*m; i++) {
//			sb.append(gen.nextInt(100000000) + " ");
//		}
//		INPUT = sb.toString();

		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

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

	private byte[] inbuf = new byte[1024];
	private int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


import java.io.*;
import java.util.*;
public class CF_514D {
    static int log2down(int n){
        int res=0;
        while (n>1){
            res++;
            n/=2;
        }
        return res;
    }
    static int[][][] getRMQ(int [][]a){
        int[][][] max=new int[a[0].length][a.length][log2down(a.length)+1];
        for (int i=0;i<a.length;i++)
            for (int j=0;j<a[0].length;j++)
                max[j][i][0]=a[i][j];
        for (int pow2=0;pow2+1<max[0][0].length;pow2++)
            for (int d=0;d<max.length;d++)
                for (int i=0;i+(1<<pow2) < max[0].length;i++)
                    max[d][i][pow2+1]=Math.max(max[d][i][pow2], max[d][i+(1<<pow2)][pow2]);
        return max;
    }
    static int[] getMax(int[][][]max, int a, int b){//b exclusive
        if (b<=a) return null;
        int[] res=new int[max.length+1];
        for (int d=0;d<res.length-1;d++){
            int pow2=log2down(b-a);
            res[d]=Math.max(max[d][a][pow2], max[d][b-(1<<pow2)][pow2]);
        }
        for (int i=0;i<res.length-1;i++)
            res[res.length-1]+=res[i];
        return res;

    }
    static int[] isGood(int[][][] max, int len, int numShots){
        if (len==0) return new int[max.length+1];
        for (int i=0;i+len<=max[0].length;i++){
            int[] ans=getMax(max, i, i+len);
            if (ans[ans.length-1]<=numShots) return ans;
        }
        return null;
    }
    static int[] getLongest(int[][][]max, int numShots){
        int[] temp=isGood(max, max[0].length, numShots);
        if (temp!=null) return temp;
        int bad=max[0].length;
        int good=0;
        while (bad-good>1){
            int m=(good+bad)/2;
            temp=isGood(max,m,numShots);
            if (temp==null) bad=m;
            else good=m;
        }
        //System.out.println(good);
        return isGood(max, good, numShots);
    }

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

        InputStream in = System.in;
        PrintStream out = System.out;

//        in = new FileInputStream("in.txt");
//        out = new PrintStream("out.txt");

        Scanner sc=new Scanner(in);
        int n=sc.nextInt(), m=sc.nextInt(), k=sc.nextInt();
        int[][] a=new int[n][m];
        for (int i=0;i<n;i++)
            for (int j=0;j<m;j++)
                a[i][j]=sc.nextInt();
        int[][][] max=getRMQ(a);
        int[] res=getLongest(max, k);
        for (int i=0;i<res.length-1;i++)
            out.print(res[i]+" ");

    }
}


import java.io.*;
import java.util.*;
public class CF_514D {
    static int log2down(int n){
        int res=0;
        while (n>1){
            res++;
            n/=2;
        }
        return res;
    }
    static int[][][] getRMQ(int [][]a){
        int[][][] max=new int[a[0].length][a.length][log2down(a.length)+1];
        for (int i=0;i<a.length;i++)
            for (int j=0;j<a[0].length;j++)
                max[j][i][0]=a[i][j];
        for (int pow2=0;pow2+1<max[0][0].length;pow2++)
            for (int d=0;d<max.length;d++)
                for (int i=0;i+(1<<pow2) < max[0].length;i++)
                    max[d][i][pow2+1]=Math.max(max[d][i][pow2], max[d][i+(1<<pow2)][pow2]);
        return max;
    }
    static int[] getMax(int[][][]max, int a, int b){//b exclusive
        if (b<=a) return null;
        int[] res=new int[max.length+1];
        for (int d=0;d<res.length-1;d++){
            int pow2=log2down(b-a);
            res[d]=Math.max(max[d][a][pow2], max[d][b-(1<<pow2)][pow2]);
        }
        for (int i=0;i<res.length-1;i++)
            res[res.length-1]+=res[i];
        return res;

    }
    static int[] isGood(int[][][] max, int len, int numShots){
        for (int i=0;i+len<=max[0].length;i++){
            int[] ans=getMax(max, i, i+len);
            if (ans[ans.length-1]<=numShots) return ans;
        }
        return null;
    }
    static int[] getLongest(int[][][]max, int numShots){
        int[] temp=isGood(max, max[0].length, numShots);
        if (temp!=null) return temp;
        int bad=max[0].length;
        if (isGood(max, 0, numShots)==null) return new int[max.length+1];
        int good=0;
        while (bad-good>1){
            int m=(good+bad)/2;
            temp=isGood(max,m,numShots);
            if (temp==null) bad=m;
            else good=m;
        }
        //System.out.println(good);
        return isGood(max, good, numShots);
    }

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

        InputStream in = System.in;
        PrintStream out = System.out;

//        in = new FileInputStream("in.txt");
//        out = new PrintStream("out.txt");

        Scanner sc=new Scanner(in);
        int n=sc.nextInt(), m=sc.nextInt(), k=sc.nextInt();
        int[][] a=new int[n][m];
        for (int i=0;i<n;i++)
            for (int j=0;j<m;j++)
                a[i][j]=sc.nextInt();
        int[][][] max=getRMQ(a);
        int[] res=getLongest(max, k);
        for (int i=0;i<res.length-1;i++)
            out.print(res[i]+" ");

    }
}


import java.io.*;
import java.util.*;
public class CF_514D {
    static int log2down(int n){
        int res=0;
        while (n>1){
            res++;
            n/=2;
        }
        return res;
    }
    static int[][][] getRMQ(int [][]a){
        int[][][] max=new int[a[0].length][a.length][log2down(a.length)+1];
        for (int i=0;i<a.length;i++)
            for (int j=0;j<a[0].length;j++)
                max[j][i][0]=a[i][j];
        for (int pow2=0;pow2+1<max[0][0].length;pow2++)
            for (int d=0;d<max.length;d++)
                for (int i=0;i+(1<<pow2) < max[0].length;i++)
                    max[d][i][pow2+1]=Math.max(max[d][i][pow2], max[d][i+(1<<pow2)][pow2]);
        return max;
    }
    static int[] getMax(int[][][]max, int a, int b){//b exclusive
        if (b<=a) return null;
        int[] res=new int[max.length+1];
        for (int d=0;d<res.length-1;d++){
            int pow2=log2down(b-a);
            res[d]=Math.max(max[d][a][pow2], max[d][b-(1<<pow2)][pow2]);
        }
        for (int i=0;i<res.length-1;i++)
            res[res.length-1]+=res[i];
        return res;

    }
    static int[] isGood(int[][][] max, int len, int numShots){
        for (int i=0;i+len<=max[0].length;i++){
            int[] ans=getMax(max, i, i+len);
            if (ans[ans.length-1]<=numShots) return ans;
        }
        return null;
    }
    static int[] getLongest(int[][][]max, int numShots){
        int[] temp=isGood(max, max[0].length, numShots);
        if (temp!=null) return temp;
        int bad=max[0].length;
        int good=0;
        while (bad-good>1){
            int m=(good+bad)/2;
            temp=isGood(max,m,numShots);
            if (temp==null) bad=m;
            else good=m;
        }
        //System.out.println(good);
        return isGood(max, good, numShots);
    }

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

        InputStream in = System.in;
        PrintStream out = System.out;

//        in = new FileInputStream("in.txt");
//        out = new PrintStream("out.txt");

        Scanner sc=new Scanner(in);
        int n=sc.nextInt(), m=sc.nextInt(), k=sc.nextInt();
        int[][] a=new int[n][m];
        for (int i=0;i<n;i++)
            for (int j=0;j<m;j++)
                a[i][j]=sc.nextInt();
        int[][][] max=getRMQ(a);
        int[] res=getLongest(max, k);
        for (int i=0;i<res.length-1;i++)
            out.print(res[i]+" ");

    }
}


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

public class r2d2droid {
  private static InputReader in;
  private static PrintWriter out;

  public static int MAXN = 100010;
  static class MaxStack {
    public int[] stack;
    public int[] items;
    public int idx;
    public MaxStack() {
      stack = new int[MAXN];
      items = new int[MAXN];
      idx = 0;
    }

    public void push(int item) {
      items[idx] = item;
      if (idx == 0) {
        stack[idx++] = item;
      } else {
        stack[idx] = Math.max(stack[idx-1], item);
        idx++;
      }
    }

    public int pop() {
      return items[--idx];
    }

    public int query() {
      if (idx == 0) return -Integer.MAX_VALUE;
      return stack[idx-1];
    }

    public boolean empty() {
      return idx == 0;
    }
  }

  static class MaxQueue {
    public MaxStack f,b;
    public MaxQueue() {
      f = new MaxStack();
      b = new MaxStack();
    }

    public void push(int item) {
      f.push(item);
    }

    public void pop() {
      if (b.empty()) {
        while (!f.empty()) b.push(f.pop());
      }
      b.pop();
    }

    public void popFront() {
      f.pop();
    }

    public int query() {
      return Math.max(f.query(), b.query());
    }
  }

  public static void main(String[] args) throws IOException {
    in = new InputReader(System.in);
    out = new PrintWriter(System.out, true);
    int N = in.nextInt();
    int M = in.nextInt();
    int K = in.nextInt();
    int[][] arr = new int[N][M];
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < M; j++)
        arr[i][j] = in.nextInt();
    }

    long[] ret = new long[M];
    int maxSeen = 0;
    int back = 0;
    MaxQueue[] mqs = new MaxQueue[M];
    for (int i = 0; i < M; i++) mqs[i] = new MaxQueue();
    for (int front = 0; front < N; front++) {
      if (back < front) back = front;
      while (back < N) {
        for (int j = 0; j < M; j++) mqs[j].push(arr[back][j]);
        int cost = 0;
        for (int j = 0; j < M; j++) cost += mqs[j].query();
        if (cost > K) {
          back--;
          for (int j = 0; j < M; j++) mqs[j].popFront();
          break;
        }
        back++;
      }
      if (back < front) continue;
      if (back - front + 1 > maxSeen) {
        maxSeen = back - front + 1;
        for (int j = 0; j < M; j++) ret[j] = mqs[j].query();
      }
      for (int j = 0; j < M; j++) mqs[j].pop();
    }

    out.print(ret[0]);
    for (int i = 1; i < M; i++) out.print(" "+ret[i]);
    out.println();
    out.close();
    System.exit(0);
  }

  static class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
      reader = new BufferedReader(new InputStreamReader(stream), 32768);
      tokenizer = null;
    }

    public String next() {
      while (tokenizer == null || !tokenizer.hasMoreTokens()) {
        try {
          tokenizer = new StringTokenizer(reader.readLine());
        } catch (IOException e) {
          throw new RuntimeException(e);
        }
      }
      return tokenizer.nextToken();
    }

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

}


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

public class r2d2droid {
  private static InputReader in;
  private static PrintWriter out;

  public static int MAXN = 100010;
  static class MaxStack {
    public int[] stack;
    public int[] items;
    public int idx;
    public MaxStack() {
      stack = new int[MAXN];
      items = new int[MAXN];
      idx = 0;
    }

    public void push(int item) {
      items[idx] = item;
      if (idx == 0) {
        stack[idx++] = item;
      } else {
        stack[idx] = Math.max(stack[idx-1], item);
        idx++;
      }
    }

    public int pop() {
      return items[--idx];
    }

    public int query() {
      if (idx == 0) return -Integer.MAX_VALUE;
      return stack[idx-1];
    }

    public boolean empty() {
      return idx == 0;
    }
  }

  static class MaxQueue {
    public MaxStack f,b;
    public MaxQueue() {
      f = new MaxStack();
      b = new MaxStack();
    }

    public void push(int item) {
      f.push(item);
    }

    public void pop() {
      if (b.empty()) {
        while (!f.empty()) b.push(f.pop());
      }
      b.pop();
    }

    public void popFront() {
      f.pop();
    }

    public int query() {
      return Math.max(f.query(), b.query());
    }
  }

  public static void main(String[] args) throws IOException {
    in = new InputReader(System.in);
    out = new PrintWriter(System.out, true);
    int N = in.nextInt();
    int M = in.nextInt();
    int K = in.nextInt();
    int[][] arr = new int[N][M];
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < M; j++)
        arr[i][j] = in.nextInt();
    }

    long[] ret = new long[M];
    int maxSeen = 0;
    int back = 0;
    MaxQueue[] mqs = new MaxQueue[M];
    for (int i = 0; i < M; i++) mqs[i] = new MaxQueue();
    for (int front = 0; front < N; front++) {
      if (back < front) back = front;
      while (back < N) {
        for (int j = 0; j < M; j++) mqs[j].push(arr[back][j]);
        int cost = 0;
        for (int j = 0; j < M; j++) cost += mqs[j].query();
        if (cost > K) {
          for (int j = 0; j < M; j++) mqs[j].popFront();
          break;
        }
        back++;
      }
      if (back - front > maxSeen) {
        maxSeen = back - front;
        for (int j = 0; j < M; j++) ret[j] = mqs[j].query();
      }
      for (int j = 0; j < M; j++) mqs[j].pop();
    }

    out.print(ret[0]);
    for (int i = 1; i < M; i++) out.print(" "+ret[i]);
    out.println();
    out.close();
    System.exit(0);
  }

  static class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
      reader = new BufferedReader(new InputStreamReader(stream), 32768);
      tokenizer = null;
    }

    public String next() {
      while (tokenizer == null || !tokenizer.hasMoreTokens()) {
        try {
          tokenizer = new StringTokenizer(reader.readLine());
        } catch (IOException e) {
          throw new RuntimeException(e);
        }
      }
      return tokenizer.nextToken();
    }

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

}


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

public class r2d2droid {
  private static InputReader in;
  private static PrintWriter out;

  public static int MAXN = 100010;
  static class MaxStack {
    public int[] stack;
    public int[] items;
    public int idx;
    public MaxStack() {
      stack = new int[MAXN];
      items = new int[MAXN];
      idx = 0;
    }

    public void push(int item) {
      items[idx] = item;
      if (idx == 0) {
        stack[idx++] = item;
      } else {
        stack[idx] = Math.max(stack[idx-1], item);
        idx++;
      }
    }

    public int pop() {
      return items[--idx];
    }

    public int query() {
      if (idx == 0) return -Integer.MAX_VALUE;
      return stack[idx-1];
    }

    public boolean empty() {
      return idx == 0;
    }
  }

  static class MaxQueue {
    public MaxStack f,b;
    public MaxQueue() {
      f = new MaxStack();
      b = new MaxStack();
    }

    public void push(int item) {
      f.push(item);
    }

    public void pop() {
      if (b.empty()) {
        while (!f.empty()) b.push(f.pop());
      }
      b.pop();
    }

    public void popFront() {
      f.pop();
    }

    public int query() {
      return Math.max(f.query(), b.query());
    }
  }

  public static void main(String[] args) throws IOException {
    in = new InputReader(System.in);
    out = new PrintWriter(System.out, true);
    int N = in.nextInt();
    int M = in.nextInt();
    int K = in.nextInt();
    int[][] arr = new int[N][M];
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < M; j++)
        arr[i][j] = in.nextInt();
    }

    long[] ret = new long[M];
    int maxSeen = 0;
    int back = 0;
    MaxQueue[] mqs = new MaxQueue[M];
    for (int i = 0; i < M; i++) mqs[i] = new MaxQueue();
    for (int front = 0; front < N; front++) {
      if (back < front) back = front;
      while (back < N) {
        for (int j = 0; j < M; j++) mqs[j].push(arr[back][j]);
        int cost = 0;
        for (int j = 0; j < M; j++) cost += mqs[j].query();
        if (cost > K) {
          back--;
          for (int j = 0; j < M; j++) mqs[j].popFront();
          break;
        }
        back++;
      }
      if (back == N) back--;
      if (back < front) continue;
      if (back - front + 1 > maxSeen) {
        maxSeen = back - front + 1;
        for (int j = 0; j < M; j++) ret[j] = mqs[j].query();
      }
      for (int j = 0; j < M; j++) mqs[j].pop();
    }

    out.print(ret[0]);
    for (int i = 1; i < M; i++) out.print(" "+ret[i]);
    out.println();
    out.close();
    System.exit(0);
  }

  static class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
      reader = new BufferedReader(new InputStreamReader(stream), 32768);
      tokenizer = null;
    }

    public String next() {
      while (tokenizer == null || !tokenizer.hasMoreTokens()) {
        try {
          tokenizer = new StringTokenizer(reader.readLine());
        } catch (IOException e) {
          throw new RuntimeException(e);
        }
      }
      return tokenizer.nextToken();
    }

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

}


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

public class r2d2droid {
  private static InputReader in;
  private static PrintWriter out;

  public static int MAXN = 100010;
  static class MaxStack {
    public int[] stack;
    public int[] items;
    public int idx;
    public MaxStack() {
      stack = new int[MAXN];
      items = new int[MAXN];
      idx = 0;
    }

    public void push(int item) {
      items[idx] = item;
      if (idx == 0) {
        stack[idx++] = item;
      } else {
        stack[idx] = Math.max(stack[idx-1], item);
        idx++;
      }
    }

    public int pop() {
      return items[--idx];
    }

    public int query() {
      if (idx == 0) return -Integer.MAX_VALUE;
      return stack[idx-1];
    }

    public boolean empty() {
      return idx == 0;
    }
  }

  static class MaxQueue {
    public MaxStack f,b;
    public MaxQueue() {
      f = new MaxStack();
      b = new MaxStack();
    }

    public void push(int item) {
      f.push(item);
    }

    public void pop() {
      if (b.empty()) {
        while (!f.empty()) b.push(f.pop());
      }
      b.pop();
    }

    public void popFront() {
      f.pop();
    }

    public int query() {
      return Math.max(f.query(), b.query());
    }
  }

  public static void main(String[] args) throws IOException {
    in = new InputReader(System.in);
    out = new PrintWriter(System.out, true);
    int N = in.nextInt();
    int M = in.nextInt();
    int K = in.nextInt();
    int[][] arr = new int[N][M];
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < M; j++)
        arr[i][j] = in.nextInt();
    }

    long[] ret = new long[M];
    int maxSeen = 0;
    int back = 0;
    MaxQueue[] mqs = new MaxQueue[M];
    for (int i = 0; i < M; i++) mqs[i] = new MaxQueue();
    for (int front = 0; front < N; front++) {
      if (back < front) back = front;
      while (back < N) {
        for (int j = 0; j < M; j++) mqs[j].push(arr[back][j]);
        int cost = 0;
        for (int j = 0; j < M; j++) cost += mqs[j].query();
        if (cost > K) {
          for (int j = 0; j < M; j++) mqs[j].popFront();
          break;
        }
        back++;
      }
      if (back - front > maxSeen) {
        maxSeen = back - front;
        for (int j = 0; j < M; j++) ret[j] = mqs[j].query();
      }
      if (back > front) for (int j = 0; j < M; j++) mqs[j].pop();
    }

    out.print(ret[0]);
    for (int i = 1; i < M; i++) out.print(" "+ret[i]);
    out.println();
    out.close();
    System.exit(0);
  }

  static class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
      reader = new BufferedReader(new InputStreamReader(stream), 32768);
      tokenizer = null;
    }

    public String next() {
      while (tokenizer == null || !tokenizer.hasMoreTokens()) {
        try {
          tokenizer = new StringTokenizer(reader.readLine());
        } catch (IOException e) {
          throw new RuntimeException(e);
        }
      }
      return tokenizer.nextToken();
    }

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

}


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

/*

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;

	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;

		while(end < numDroids)
		{
			//System.out.println(start +" " + end +" " +maxLen);

			int[] numShots = getNumShots(start, end);
			if(numShots == null)
			{
				++start;
				if(end < start)
					end = start;
			}
			else
			{
				if(end - start + 1 > maxLen)
				{
					maxLen = end - start +1;
					bestShots = numShots;
				}
				++end;
			}
		}

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

	static int[] getNumShots(int start, int end)
	{
		int[] numShots = new int[numDetails];
		for(int curr = start; curr <= end; ++curr)
		{
			int sum = 0;
			for(int currDetail = 0; currDetail < numDetails; ++currDetail)
			{
				numShots[currDetail] = Math.max(droids[curr][currDetail], numShots[currDetail]);
				sum += numShots[currDetail];

				if(sum > maxShots)
					return null;
			}
		}

		return numShots;
	}

	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();
		   }
		}
}