/*
p个位置用来组队(有序)
k个观众(无序)
要求收益最大化,dp[i][S]表示前i个人的组队状态是S时的最大收益
先对a进行排序
第i个人加入后有三种选择:
找个位置组队: 挑一个S中为0的位置
不组队,去当观众/有可能当不成:如果i-cnt(S)>=k,那么当不成观众
*/
#include<bits/stdc++.h>
using namespace std;
#define N 200005
#define ll long long
struct Node{
ll a,s[7];
}b[N];
int cmp(Node &a,Node &b){return a.a>b.a;}
ll n,p,k,dp[N][1<<7],cnt[1<<7];
void prework(){
for(int i=0;i<(1<<7);i++){
int res=0;
for(int j=0;j<7;j++)
if(i>>j & 1)res++;
cnt[i]=res;
}
}
int main(){
prework();
cin>>n>>p>>k;
for(int i=1;i<=n;i++)scanf("%lld",&b[i].a);
for(int i=1;i<=n;i++)
for(int j=0;j<p;j++)scanf("%lld",&b[i].s[j]);
sort(b+1,b+1+n,cmp);
memset(dp,-1,sizeof dp);
dp[0][0]=0;
for(int i=0;i<n;i++){
for(int S=(1<<p)-1;S>=0;S--)if(dp[i][S]!=-1){
//不组队
if(i-cnt[S]>=k)dp[i+1][S]=max(dp[i+1][S],dp[i][S]);
else dp[i+1][S]=max(dp[i+1][S],dp[i][S]+b[i+1].a);
//组队
for(int j=0;j<p;j++)if(!(S>>j & 1))
dp[i+1][S|(1<<j)]=max(dp[i+1][S|(1<<j)],dp[i][S]+b[i+1].s[j]);
}
}
cout<<dp[n][(1<<p)-1]<<'\n';
}