/*
TASK:tre
LANG:C++
*/
#include<stdio.h>
#include<vector>
#include<algorithm>
typedef struct treasure
{
 int price;
 int time;
};
using namespace std;
bool cmp(treasure a1,treasure a2);
int main()
{
 int map[5][10004]={0},i,j,k,l,d,n,tmp,time=0,f,max=0;
 treasure otg[10002];
 scanf("%d%d%d%d",&n,&k,&l,&d);
 for(i=1,f=1;i<=d;i++,f*=-1)
 {
  for(j=0;j<l;j++)
  {
   scanf("%d",&tmp);
   if(f==1)map[3][j]=tmp+map[4][j];
   else map[4][j]=tmp+map[3][j];
   if(map[3][j]>map[0][j]&&f==1){map[0][j]=map[3][j];map[1][j]=i;}
   else if(map[4][j]>map[0][j]&&f==-1){map[0][j]=map[4][j];map[1][j]=i;}
  }
 }
 for(i=0,n=0,f=0;i+f<l;i++)
 {
  if(!map[1][i+f]||!map[0][i+f]){i--;f++;}
  else
  {
   n++;
   otg[i].price=map[0][i+f];
   otg[i].time=map[1][i+f];
  }
 }
 sort(otg,otg+n,cmp);
 for(i=0;i<n;i++)
 {
  printf("%d %d\n",otg[i].price,otg[i].time);
 }
 for(max=0,i=0;i<n;i++)
 {
  for(j=i,tmp=0,time=0;j<n;j++)
  {
   if(time+otg[j].time<=k){tmp+=otg[i].price;time+=otg[i].time;}
  }
  if(tmp>max)max=tmp;
 }
 printf("%d\n",max);
 return 0;
}
bool cmp(treasure a1,treasure a2)
{
 if(a1.time<a2.time)return true;
 else if(a1.time==a2.time&&a1.price>a2.price)return true;
 else return false;
}
