#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define N 100
int n,m;
struct node{
int g[1005];
void init(int k)
{
memset(g,0,sizeof(g));
g[0]=1;
g[1]=k;
}
node operator *(const node y)
{
node t;
t.init(0);
int k;
for(int i=1;i<=g[0];i++)
{
for(int j=1;j<=y.g[0];j++)
{
k=i+j-1;
t.g[k]+=g[i]*y.g[j];
t.g[k+1]+=t.g[k]/10;
t.g[k]%=10;
}
}
k++;
while(t.g[k]==0&&k>1) k--;
t.g[0]=k;
return t;
}
node operator + (const node y){
node t;t.init(0);
int l=max(g[0],y.g[0]);
for(int i=1;i<=l;i++)
{
t.g[i]+=g[i]+y.g[i];
t.g[i+1]+=t.g[i]/10;
t.g[i]%=10;
}
l++;
while(t.g[l]==0&&l>1) l--;
t.g[0]=l;
return t;
}
};
node two;
node twos[N];
void pre()
{
two.init(2);
twos[1].init(2);
for(int i=2;i<=m;i++)
{
twos[i]=twos[i-1]*two;
}
}
node maxn(node x,node y)
{
if(x.g[0]>y.g[0]) return x;
else if(x.g[0]<y.g[0]) return y;
else{
for(int i=x.g[0];i>0;i--)
{
if(x.g[i]>y.g[i]) return x;
else if(x.g[i]<y.g[i]) return y;
else continue;
}
}
}
node f[N][N];
node a[N],ans;
node read()
{
node x;
char s[10];
cin>>s;
int l=strlen(s);
for(int i=0;i<l;i++)
{
x.g[l-i]=s[i]-'0';
}
x.g[0]=l;
return x;
}
void write(node x)
{
for(int i=x.g[0];i>0;i--)
{
printf("%d",x.g[i]);
}
putchar('\n');
}
int main()
{
scanf("%d%d",&n,&m);
pre();
ans.init(0);
for(int i=1;i<=n;i++)
{
for(int o=1;o<=m;o++)
{
for(int j=o+1;j<=m;j++)
{
f[o][j].init(0);
}
}
for(int j=1;j<=m;j++)
{
a[j]=read();
f[j][j]=twos[m]*a[j];
}
for(int l=2;l<=m;l++)
{
for(int i=1;i+l-1<=m;i++)
{
int j=i+l-1;
f[i][j]=maxn(f[i+1][j]+a[i]*twos[m-j+i],f[i][j-1]+a[j]*twos[m-j+i]);
}
}
ans=ans+f[1][m];
}
write(ans);
return 0;
}