//带边权与点权的最短路,Floyd
//注意查询时两点可能是同一点
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int INF=0xfffffff;
int n, a[1005][1005], next[1005][1005], c[1005];
void init(){
int i, j;
for(i=0; i<n; i++)
for(j=0; j<n; j++){
scanf("%d", &a[i][j]);
next[i][j]=j;
if(a[i][j]==-1)a[i][j]=INF;
}
for(i=0; i<n; i++)
scanf("%d", &c[i]);
}
void floyd(){
int i, j, k;
for(k=0; k<n; k++)
for(i=0; i<n; i++)
for(j=0; j<n; j++){
if(a[i][j]>a[i][k]+a[k][j]+c[k]){
a[i][j]=a[i][k]+a[k][j]+c[k];
next[i][j]=next[i][k];
}
else if(a[i][j]==a[i][k]+a[k][j]+c[k]&&next[i][j]>next[i][k]&&next[i][k]!=i)
next[i][j]=next[i][k];
}
}
int main(){
//freopen("1.txt", "r", stdin);
int x, y, i, j;
while(scanf("%d", &n)&&n){
init();
floyd();
while(scanf("%d%d", &x, &y)&&x>0){
printf("From %d to %d :\nPath: %d", x, y, x);
i=x-1;j=y-1;
while(i!=j){
i=next[i][j];
printf("-->%d", i+1);
}
printf("\nTotal cost : %d\n\n", a[x-1][y-1]);
}
}
return 0;
}