#include <iostream>
#include <fstream>
#define INF 999999;
using namespace std;
int main() {
ifstream ifs("input.txt");
ofstream ofs("output.txt");
//N代表网格总数,K代表汽车装满油后能够够在边上行驶的距离,用边数表示,
//A代表遇到油库点的油费,B代表如果x坐标和y坐标减小时的倒车费,C代表增设油库的钱(需要额外加上A)。
int N,K,A,B,C;
ifs>>N>>K>>A>>B>>C;
int a[N+1][N+1];//N*N的网格,一共有N+1个交点
for(int i=1; i<=N; ++i)
for(int j=1; j<=N; ++j)
ifs>>a[i][j];//0代表么有油库,1代表油库
//设置动态数组,f[x][y][0]代表从起始点(1,1)到x,y坐标的最少费用
//f[x][y][1]代表汽车到达(x,y)坐标时,还能继续行驶的边数
int f[N+1][N+1][3];
for(int i=1; i<=N; ++i) {
for(int j=1; j<=N; ++j) {
f[i][j][0]=INF; //初始化
f[i][j][1]=K;
}
}
//左,上,右,下4个方向,其中,右,下两个方向到当前位置需要加上倒车价格B
int s[4][3]= {{-1,0,0},{0,-1,0},{1,0,B},{0,1,B}};
//起点值初始化
f[1][1][0]=0;
f[1][1][1]=K;
for(int x=1; x<=N; ++x) {
for(int y=1; y<=N; ++y) {
if(x==1&&y==1)
continue;
int minmoney=INF;
int minstep;//minmoney存储(x,y)上个位置的最小花费
int tmpmoney,tmpstep;
for(int i=0; i<=3; ++i) { //遍历上一个位置的4种可能情况,求出4个位置到当前位置的钱
if((x+s[i][0]<1&&i==0)||(x+s[i][0]>N&&i==2)||(y+s[i][1]<1&&i==1)||(y+s[i][1]>N&&i==3))
continue;//(x,y)的上一个位置越界则continue;
tmpmoney=f[x+s[i][0]][y+s[i][1]][0]+s[i][2];//上一个位置到当前所花费的钱
tmpstep = f[x+s[i][0]][y+s[i][1]][1]-1;//每走一个,剩下的步数减1
if(a[x][y]==1) {//(x,y)遇到加油站则加油
tmpmoney+=A;//加上油费,
tmpstep=K;//可以走的边数设为K
}
if(a[x][y]==0 && tmpstep==0 &&(x!=N||y!=N)) {
tmpmoney+=A+C; //没油,且这个地方没有加油站,且没有到终点
tmpstep=K;
}
if(minmoney>tmpmoney) { //更新到当前值的最小值 (上个位置到当前费用费用最少的)
minmoney=tmpmoney;
minstep=tmpstep;
}
}
if(f[x][y][0]>minmoney) { //更新f
f[x][y][0]=minmoney;
f[x][y][1]=minstep;
}
}
}
ofs<<f[N][N][0];
cout<<f[N][N][0];
return 0;
}