#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<algorithm>
#include<string>
#include<cmath>
#include<cstdio>
using namespace std;
#define maxn 10005
struct node
{
int x, y, w;
}e[maxn];
int n, m;
int pre[1000];
int find(int x)//查找根节点
{
int r = x;
while (pre[r]!=r)//返回根节点r
{
r = pre[r];
}
int i=x, j;
while (pre[i] != r)//路径压缩
{
j = pre[i];
pre[i] = r;
i = j;
}
return r;
}
void join(int x, int y)//判断x与y是否连通。如果不连通,就把它们所在的连通分支合并起来
{
int fx = find(x), fy = find(y);
if (fx != fy)
{
pre[fx] = fy;
}
}
int kruskal()
{
int res = 0, j = 0;
//int k=1;while(k<n && j<m)n-1条边{}if(k!=n) res=-1;return res;
while (j < n*n)
{
int m1 = e[j].x, m2 = e[j].y;
int sn1 = find(m1), sn2 = find(m2);
if (sn1 != sn2)
{
res += e[j].w;
join(sn1, sn2);
}
j++;
}
return res;
}
bool cmp(node a, node b)
{
return a.w < b.w;
}
int t[1001];
int main()
{
int x, y;
while (scanf("%d", &n) != EOF && n)
{
for (int i = 1; i <= n; i++)
{
pre[i] = i;
}
scanf("%d", &m);
while (m--)
{
scanf("%d", &x);
pre[x] = -1;
}
int cost;
int l = 0;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
scanf("%d", &cost);
e[l].x = i;
e[l].y = j;
e[l].w = cost;
l++;
}
}
int sum = n*n;
sort(e, e + sum, cmp);
printf("%d\n", kruskal());
}
return 0;
}