import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.PriorityQueue;
public class Main {
static int computerCnt, sumLength = 0;
static PriorityQueue<Edge> edgeList = new PriorityQueue<>();
static int[] parent;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
computerCnt = Integer.parseInt(br.readLine());
parent = new int[computerCnt];
for (int i = 0; i < computerCnt; i++) {
parent[i] = i;
}
for (int i = 0; i < computerCnt; i++) {
char[] tmpArr = br.readLine().toCharArray();
for (int j = 0; j < computerCnt; j++) {
int tmp = 0;
if (tmpArr[j] >= 'a' && tmpArr[j] <= 'z')
tmp = tmpArr[j] - 'a' + 1;
else if (tmpArr[j] >= 'A' && tmpArr[j] <= 'Z')
tmp = tmpArr[j] - 'A' + 27;
sumLength += tmp;
if (i != j && tmp != 0)
edgeList.add(new Edge(i, j, tmp));
}
}
int useEdgeCnt = 0;
int MSTResult = 0;
while (!edgeList.isEmpty()) {
Edge now = edgeList.poll();
int s = now.s;
int e = now.e;
int v = now.v;
if (find(s) != find(e)) {
union(s, e);
useEdgeCnt++;
MSTResult += v;
}
}
if (useEdgeCnt == computerCnt - 1)
System.out.println(sumLength - MSTResult);
else
System.out.println(-1);
}
private static void union(int s, int e) {
int root_s = find(s);
int root_e = find(e);
if (root_s != root_e)
parent[root_s] = root_e;
}
private static int find(int index) {
if (index == parent[index])
return index;
else
return parent[index] = find(parent[index]);
}
}
class Edge implements Comparable<Edge> {
int s;
int e;
int v;
public Edge(int s, int e, int v) {
this.s = s;
this.e = e;
this.v = v;
}
@Override
public int compareTo(Edge e) {
return this.v - e.v;
}
}