#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w",stdout)
#define fst first
#define snd second
typedef __int64 LL;
typedef pair PII;
const double eps = 1e-10;
const int MAXN = 500 + 5;
const int INF = 0x3f3f3f3f;
const int DIR[][2] = {{ -1, 0}, {1, 0}, {0, -1}, {0, 1}};
int N, M, R1, C1, R2, C2;
int maze[MAXN][MAXN];
char buf[10];
struct Dijstra1 {
struct QNode {
PII pnt;
int dis;
QNode() {}
QNode (PII pnt, int dis) : pnt (pnt), dis (dis) {}
bool operator > (const QNode &e) const {
return dis > e.dis;
}
};
int mincost[MAXN][MAXN];
bool vis[MAXN][MAXN];
QNode tp;
priority_queue, greater > Q;
void init() {
memset (mincost, 0x3f, sizeof (mincost) );
memset (vis, false, sizeof (vis) );
while (!Q.empty() ) Q.pop();
}
void run (int sx, int sy) {
int x, y, nx, ny;
mincost[sx][sy] = maze[sx][sy];
Q.push (QNode (PII (sx, sy), mincost[sx][sy]) );
while (!Q.empty() ) {
tp = Q.top();
Q.pop();
x = tp.pnt.fst;
y = tp.pnt.snd;
if (vis[x][y]) continue;
vis[x][y] = true;
for (int i = 0; i < 4; i ++) {
nx = x + DIR[i][0];
ny = y + DIR[i][1];
if (nx > N || nx < 1 || ny > M || ny < 1) continue;
if (maze[nx][ny] == -1) continue;
if (mincost[nx][ny] > mincost[x][y] + maze[nx][ny]) {
mincost[nx][ny] = mincost[x][y] + maze[nx][ny];
Q.push (QNode (PII (nx, ny), mincost[nx][ny]) );
}
}
}
}
} dij1;
struct Dijstra2 {
struct QNode {
PII pnt;
int dis, dir;
QNode() {}
QNode (PII pnt, int dis) : pnt (pnt), dis (dis) {}
QNode (PII pnt, int dis, int dir) : pnt (pnt), dis (dis), dir (dir) {}
bool operator > (const QNode &e) const {
return dis > e.dis;
}
};
int mincost[MAXN][MAXN][4];
bool vis[MAXN][MAXN][4];
QNode tp;
priority_queue, greater > Q;
void init() {
memset (mincost, 0x3f, sizeof (mincost) );
memset (vis, false, sizeof (vis) );
while (!Q.empty() ) Q.pop();
}
void run (int sx, int sy) {
int x, y, nx, ny;
for (int i = 0; i < 4; i++) {
mincost[sx][sy][i] = maze[sx][sy];
Q.push (QNode (PII (sx, sy), mincost[sx][sy][i], i) );
}
while (!Q.empty() ) {
tp = Q.top();
Q.pop();
x = tp.pnt.fst;
y = tp.pnt.snd;
if (tp.dir != -1 && vis[x][y][tp.dir]) continue;
if (tp.dir != -1) {
vis[x][y][tp.dir] = true;
}
for (int i = 0; i < 4; i ++) {
nx = x + DIR[i][0];
ny = y + DIR[i][1];
if (nx > N || nx < 1 || ny > M || ny < 1) continue;
if (maze[nx][ny] == -1) continue;
if (tp.dir == i) continue;
if (mincost[nx][ny][i] > mincost[x][y][tp.dir] + maze[nx][ny]) {
mincost[nx][ny][i] = mincost[x][y][tp.dir] + maze[nx][ny];
Q.push (QNode (PII (nx, ny), mincost[nx][ny][i], i) );
}
}
}
}
} dij2;
int main() {
#ifndef ONLINE_JUDGE
FIN;
// FOUT;
#endif // ONLINE_JUDGE
int cas = 0;
int res1, res2;
while (~scanf ("%d %d %d %d %d %d", &N, &M, &R1, &C1, &R2, &C2) ) {
for (int i = 1; i <= N; i ++) {
for (int j = 1; j <= M; j++) {
scanf ("%s", buf);
if (buf[0] == '*') {
maze[i][j] = -1;
} else {
maze[i][j] = atoi (buf);
}
}
}
dij1.init();
dij2.init();
dij1.run (R1, C1);
dij2.run (R1, C1);
res1 = dij1.mincost[R2][C2];
res2 = INF;
for (int i = 0; i < 4; i++) {
res2 = min (res2, dij2.mincost[R2][C2][i]);
}
if (res1 == INF) res1 = -1;
if (res2 == INF) res2 = -1;
printf ("Case %d: %d %d\n", ++cas, res1, res2);
}
return 0;
}