/*
TASK: tre
LANG: C++
*/
#include <stdio.h>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

struct A
{
       double eff;
       int i, j;
       int price;
       int lastdigged; //or last updated
       A(double a, int b, int c, int d, int e)
       {
            eff = a;
            i = b;
            j = c;
            price = d;
            lastdigged = e;
       }
       bool operator<(A a) const
       {
            return eff < a.eff;
       }
};

priority_queue<A> heap;
vector<int> curr(10004, 0);
vector<int> digged(10004, 0);
vector<int> sucked(10004, 0);

void printlll(long long a)
{
     if (a < 100000000) 
     {
           printf("%d", (int)a);
           return;           
     }
     printlll(a/100000000);
     printf("%08d", (int)(a%100000000));
}

//int TheMatrix[101][10004];

int main()
{
    int N, K, L, D;
    scanf("%d%d%d%d", &N, &K, &L, &D);
    for (int i = 1; i <= D; i++)
     for (int j = 0; j < L; j++)
     {
         int cell;
         scanf("%d", &cell);
         curr[j] += cell;
         heap.push(A( ((double)curr[j])/i, i, j, curr[j], 0 ));
     }
    
    int timeleft = K;
    long long brutenvatreshendohod = 0;
    
    //sort(heap.begin(), heap.end());
    for (int i = 0; i < heap.size(); i++)
    {
        A v = heap.top();
        heap.pop();
        if (digged[v.j] > v.i || v.i - digged[v.j] > timeleft) continue;
        
        if (v.lastdigged != digged[v.j])
        {
             v.lastdigged = digged[v.j];
             v.eff = ((double)(v.price - sucked[v.j]))/(v.i - digged[v.j]);
             heap.push(v);
             continue;
        }
        if (v.eff < 0) break;
        
        timeleft -= v.i - digged[v.j];
        digged[v.j] = v.i;
        brutenvatreshendohod += v.price - sucked[v.j];
        sucked[v.j] = v.price;
    }

    printlll(brutenvatreshendohod);
    printf("\n");
    return 0;
}
