import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Scanner;
public class Solution15A {
public static int[][] dirs = {{-1,0}, {1,0}, {0,-1}, {0,1}};
public static int key(int x, int y) {
return (y<<16)|x;
}
public static class Node implements Comparable<Node> {
public int x;
public int y;
public int w;
public int c;
public int compareTo(Node n) {
return this.c-n.c;
}
}
public static void main(String[] args) {
PriorityQueue<Node> q = new PriorityQueue<>();
Map<Integer, Node> m = new HashMap<>();
int x = 0, y = 0;
try {
File myObj = new File(args[0]);
Scanner myReader = new Scanner(myObj);
while (myReader.hasNextLine()) {
String data = myReader.nextLine();
for (x = 0; x < data.length(); x++) {
Node n = new Node();
n.x = x;
n.y = y;
n.w = data.charAt(x)-'0';
n.c = Integer.MAX_VALUE;
m.put(key(x, y), n);
q.offer(n);
}
y++;
}
myReader.close();
} catch (FileNotFoundException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
Node start = m.get(key(0, 0));
Node end = m.get(key(x-1, y-1));
q.remove(start);
start.c = 0;
q.offer(start);
if (q.peek() != start) System.out.println("An error occurred.");
while (!q.isEmpty()) {
Node n = q.poll();
if (n == end) break;
m.remove(n);
for (int[] dir : dirs) {
Node o = m.get(key(n.x+dir[0], n.y+dir[1]));
if (o != null && o.c > n.w+n.c) {
q.remove(o);
o.c = n.w+n.c;
q.offer(o);
}
}
}
System.out.println(end.c);
}
}