#include <iostream>
#define MAX_N 1000
using namespace std;
//adjacent array version
//A의 0 에 사이즈를 저장한 인접배열
int A[MAX_N+1][MAX_N+1];
int maxNode;
int D[MAX_N+1]; // distance
int U[MAX_N+1]; // selected vertex set
int UN=0;
void dijkstra(int s){
U[s] = 1;
cout << (char)(s+'a') <<" ";
UN++;
//0 에서 해당 정점까지의 거리를 초기값으로 입력한다.
for(int i=0;i<=maxNode;i++){
D[i] = A[s][i];
}
while(UN<=maxNode){
//이미 선택되지 않은 정점중 가장 가까운 것을 찾는다.
int min = 1000;
int minIdx ;
for (int i=0;i<=maxNode;i++){
if( i!=s && !U[i] && min > D[i] && D[i]!=-1){
minIdx = i;
min = D[i];
}
}
U[minIdx] = 1;
UN++;
cout << (char)(minIdx + 'a') <<" ";
if(UN>maxNode){ break;} //it is really needed??
for(int i=0;i<=maxNode;i++){
if(A[minIdx][i]!=-1){
//i 로 바로갈까 아니면 다른데 들러서 갈까?
D[i] = (D[i] !=-1 && (D[i] < (D[minIdx] + A[minIdx][i])))?D[i]:(D[minIdx] + A[minIdx][i]);
}
}
}
//for(int i=0;i<=maxNode;i++){
// if(U[i]==0){
// cout << (char)(i + 'a') ;
// }
//}
cout << endl;
}
int main(){
int T, test_case;
int N;
char src,dst;
int weight;
freopen ( "sample_input.txt", "r", stdin );
cin >> T;
for(test_case = 1; test_case <= T; test_case++){
for(int i=0;i<=MAX_N; i++){
for (int j=0;j<=MAX_N;j++){
if(i==j)
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 A[i][j] = 0;
else
A[i][j] =-1; // dijkstra 는 - 값을 다루지 않는다.
}
}
cin >> N;
cout << "Graph" <<endl;
maxNode =0;
for(int i=0;i<N;i++){
cin >> src >> dst >> weight;
A[src-'a'][dst-'a'] = weight;
if (src-'a'> maxNode){
maxNode = src-'a';
}
if (dst-'a'> maxNode){
maxNode = dst -'a';
}
}
for(int i=0;i<=maxNode;i++){
for(int j=0;j<=maxNode;j++)
cout << A[i][j] <<" ";
cout << endl;
}
//Aijkstra
dijkstra(0);
}
return 0;
}