#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
int getlen(int *a){
for(int i = 99;i>=1;--i){
if(a[i]!=0) return i;
}
return 1;
}
int* add(int*a,int *b){
int* ans;ans =(int*)malloc(100*sizeof(int));
for(int i = 0;i<100;++i) ans[i] = 0;
int len = fmax(getlen(a),getlen(b));
for(int i = 1;i<=len;++i){
ans[i] = a[i]+b[i];
}
for(int i = 1;i<=len;++i){
ans[i+1] += (ans[i]/10);
ans[i]%=10;
}
return ans;
}
int* get(int a){
int* ans;ans = (int*)malloc(100*sizeof(int));
for(int i = 0;i<100;++i) ans[i] = 0;
int i = 1;
while(a){
ans[i++] = a%10;
a/=10;
}
return ans;
}
int* pow2(int *a,int n){
int* ans;ans = (int*)malloc(100*sizeof(int));
for(int i = 0;i<100;++i) ans[i] = a[i];
if(n==0) return ans;
while(n--){
int len = getlen(ans);
for(int i = 1;i<=len;++i){
ans[i] *=2;;
}
for(int i = 1;i<=len;++i){
ans[i+1] += (ans[i]/10);
ans[i]%=10;
}
}
return ans;
}
int* max(int*a,int*b){
if(getlen(a)>getlen(b)) return a;
else if(getlen(a)<getlen(b)) return b;
else {
for(int i = getlen(a);i>=1;--i){
if(a[i]>b[i]) return a;
else if(a[i]<b[i]) return b;
}
}
return a;
}
int f[85][85][100];
int a[85][85];
void init(int n,int m){
for(int i = 1;i<=n;++i) for(int j = 1;j<=m;++j) scanf("%d",&a[i][j]);
}
int main(){
int n,m;scanf("%d %d",&n,&m);
init(n,m);
int ans[100]; memset(ans,0,sizeof(ans));
while(n--){
memset(f,0,sizeof(f));
for (int i = 1; i <= m; i++){
for (int j = m; j >= i; j--) {
memcpy(f[i][j],max(f[i][j], add(f[i-1][j] , pow2(get(a[n+1][i-1]),m-j+i-1))),sizeof(f[i][j]));
memcpy(f[i][j],max(f[i][j], add(f[i][j+1] , pow2(get(a[n+1][j+1]),m-j+i-1))),sizeof(f[i][j]));
}
}
int mm[100] ; memset(mm,0,sizeof(mm));
for(int i = 1;i<=m;++i) memcpy(mm,max(mm,add(f[i][i],pow2(get(a[n+1][i]),m))),sizeof(mm));
memcpy(ans,add(ans,mm),sizeof(ans));
}
int anslen = getlen(ans);
for(int i = anslen;i>=1;--i) printf("%d",ans[i]);
}