#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<string>
#include<algorithm>
#include<stdio.h>
using namespace std;
#define maxn 100
#define INF 100000000
int Edge[maxn][maxn];
int dist[maxn];
int path[maxn];
int s[maxn];
int n;
int sum;
struct node
{
int org;
int dest;
int time;
}a[100];
int cmp(node a, node b)
{
return a.time < b.time;
}
void dijkstra(int v0)
{
int i, j, k, u;
for (i = 0; i<n; i++)
{
dist[i] = Edge[v0][i];
s[i] = 0;
if (i != v0)
path[i] = v0;
else
path[i] = -1;
}
dist[v0] = 0;
s[v0] = 1;
for (i = 0; i<n - 1; i++)
{
int min1 = INF;
u = v0;
for (j = 0; j<n; j++)
{
if (!s[j] && dist[j]<min1)
{
u = j;
min1 = dist[j];
}
}
s[u] = 1;
for (k = 0; k<n; k++)
{
if (!s[k] && Edge[u][k]<INF && dist[u] + Edge[u][k]<dist[k])
{
dist[k] = dist[u] + Edge[u][k];
path[k] = u;
}
}
}
}
int main()
{
int i, j;
int t;
int v, node1;
sum = 0;
scanf("%d", &n);
memset(Edge, INF, sizeof(Edge));
for (i = 0; i<n; i++)
{
for (j = 0; j<n; j++)
{
scanf("%d", &Edge[j][i]);
if (Edge[j][i] == -1)
Edge[j][i] = INF;
}
}
scanf("%d", &v);
v--;
dijkstra(v);
int cnt = 0;
while (scanf("%d", &node1) != EOF && node1!=101 )
{
node1--;
a[cnt].org = node1;
a[cnt].dest = v;
a[cnt++].time = dist[node1];
}
printf("Org Dest Time Path\n");
int shortest[100];
sort(a, a + cnt, cmp);
for (i = 0; i < cnt; i++)
{
printf("%d %d %d", a[i].org + 1, a[i].dest + 1, a[i].time);
memset(shortest, 0, sizeof(shortest));
int k = 0;
shortest[k] = a[i].org;
while (path[shortest[k]] != -1)
{
k++;
shortest[k] = path[shortest[k - 1]];
}
k++;
shortest[k] = v;
for (j = 0; j < k; j++)
{
printf(" %d", shortest[j] + 1);
}
printf("\n");
}
return 0;
}