#include<cstdio>
#include<vector>
#include<queue>
#include<climits>
using namespace std;
#define int long long
int ans=0;
int n,m,now,now1;
struct Edge{
int v,w;
};
vector<Edge> g[105];
int a[10005];
int vis[105];
int dis[105][105];
struct node{
int dis,u;
bool operator>(const node &a) const{
return a.dis<dis;
}
};
priority_queue<node,vector<node>,greater<node>> q;
void dijkstra(int u){
dis[now][now]=0;
q.push((node){0,u});
while (!q.empty()){
int u=q.top().u;
q.pop();
if (u==now1) break ;
if (vis[u]) continue;
vis[u]=1;
for (Edge ed:g[u]){
int v=ed.v,w=ed.w;
if (dis[now][v]>dis[now][u]+w){
dis[now][v]=dis[now][u]+w;
q.push((node){dis[now][v],v});
}
}
}
}
signed main(){
scanf("%lld%lld",&n,&m);
for (int i=1;i<=m;i++) scanf("%lld",&a[i]);
for (int i=1;i<=n;i++){
for (int j=1;j<=n;j++){
int w;
scanf("%lld",&w);
if (i==j) continue;
g[i].push_back((Edge){j,w});
}
}
for (int j=1;j<=n;j++) vis[j]=0;
for (int j=1;j<=n;j++) dis[1][j]=INT_MAX-1;
now=1;
now1=a[1];
dijkstra(1);
ans+=dis[1][now1];
for (int i=2;i<=m;i++){
for (int j=1;j<=n;j++) vis[j]=0;
now=a[i-1];
now1=a[i];
for (int j=1;j<=n;j++) dis[now][j]=INT_MAX-1;
if (dis[now][now1]!=INT_MAX-1){
ans+=dis[now][now1];
continue;
}
else{
dijkstra(now);
ans+=dis[now][now1];
}
}
printf("%lld",ans);
return 0;
}