#include<iostream>#include<string>#include<vector>#include<algorithm>#define INF (~(0x1<<31))
using namespace std;int gra[1100][1100];int n, m, k, ds, mind =0,minnode =-1;double average = INF;
vector<int> distd;inttoint(string str){return str[0]=='G'? n +stoi(str.substr(1, str.length()-1)):stoi(str);}voiddijsktra(int v){
vector<bool>visit(1100);
vector<int>dist(1100, INF);
dist[v]=0;for(int i =0; i < n + m; i++){//执行n+m次int min = INF, u =-1;for(int j =1; j <= n + m; j++){if(!visit[j]&& dist[j]< min){
u = j;
min = dist[j];}}if(u ==-1)break;
visit[u]= true;for(int j =1; j <= n + m; j++){//更新if(!visit[j]&& gra[u][j]!= INF){if(dist[u]+ gra[u][j]< dist[j])
dist[j]= dist[u]+ gra[u][j];}}}int min = INF;double sum =0;for(int i =1; i <= n; i++){//找最小节点if(dist[i]< min){
min = dist[i];
sum +=1.0*dist[i];}if(dist[i]> ds)return;//说明该加油站不能覆盖所有住户}if((min > mind)||(min == mind && sum/n < average)){
mind = min;
minnode = v;
average = sum / n;
distd = dist;}return;}intmain(){scanf("%d %d %d %d",&n,&m,&k,&ds);fill(gra[0], gra[0]+1100*1100, INF);for(int i =0; i < k; i++){
string s1,s2;int d;
cin >> s1 >> s2 >> d;int a =toint(s1);int b =toint(s2);
gra[a][b]= gra[b][a]= d;}for(int i = n +1; i <= n + m; i++)//从G1出发找最短路径dijsktra(i);if(minnode ==-1){
cout <<"No Solution";return0;}
cout <<"G"<< minnode - n << endl;int sum =0;for(int i =1; i <= n; i++)
sum += distd[i];printf("%.1f %.1f",(double)mind,(double)sum/n);return0;}