/*************************
题意:
给出一个图
里面有居民区1-N,也有加油站G1-GN
选择一个加油站
要求该加油站 到居民区的最小距离 最大,并且各距离都在ds范围内
如果最小距离相同, 则要求 到各居民区的平均距离 最小
还相等,则要求序号最小
************************/

/***********************
简单的Dijkstra
以每个加油站做起点,做一次dijkstra
然后检查上述的4个条件去选择一个最合适的加油站
写的时候要谨慎,因为dijstra这种非常容易写错。

注意点:
1. 注意居民区序号是1-N, 加油站序号是G1-GM
2. 故我们可以把加油站的序号设为 N+i,i是Gi中的i,即可以少开一些数组
*************************/
/***********************
笔记:
*********************/
#include<iostream>
#include<stdio.h>
#include<string>
#include<vector>
#include<queue>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
#include<stack>
#include<map>
#include<set>
#include<unordered_map>
using namespace std;
#define M 1200
#define INF 0x7ffffff


struct Ans{
int index;
int mindis;
double avgdis;
};

bool cmp(Ans a,Ans b){
if(a.mindis > b.mindis)
return true;
else if(a.mindis == b.mindis){
if(a.avgdis < b.avgdis)
return true;
else if(a.avgdis == b.avgdis)
return a.index <b.index;
else return false;
}
else return false;
}

vector<Ans> ans;


int dis[M][M];
int n,m,k,ds;
void dijk(int s){
int d[M], v[M], i, j;
for(i = 1; i <=n + m;i++){
d[i] = INF;
v[i] = 0;
}
d[s] = 0;

int dismin,select;
for(i = 1;i <= n + m;i++){
dismin = INF;
for(j = 1; j <= n + m; j++){
if(!v[j] && d[j] < dismin){
dismin = d[j];
select = j;
}
}
if(dismin == INF )
break;
v[select] = 1;
for(j = 1;j <= n + m; j++){
if(!v[j] && d[select] + dis[select][j] < d[j]){
d[j] = d[select] + dis[select][j];
}
}
}

dismin = INF;
int sum=0;
for(i = 1;i <= n; i++){
if(d[i] > ds)
break;
if(d[i]<dismin){
dismin = d[i];
}
sum += d[i];
}
Ans a;
if(i == n+1){
a.avgdis = double(sum)/double(n);
a.index = s-n;
a.mindis = dismin;
ans.push_back(a);
}
}

int main(){
int i;
string strs,stre;
int s,e,d,j;
scanf("%d%d%d%d",&n,&m,&k,&ds);

for(i=1;i<=n+m;i++)
for(j=1;j<=n+m;j++){
if(i != j)
dis[i][j] = INF;
else dis[i][j] = 0;
}

for(i=0;i<k;i++){
cin>>strs>>stre>>d;
if(strs[0] == 'G'){
s = n + atoi(strs.substr(1).c_str());
}
else s = atoi(strs.c_str());
if(stre[0] == 'G'){
e = n + atoi(stre.substr(1).c_str());
}
else e = atoi(stre.c_str());
if(d < dis[s][e]){
dis[s][e] = d;
dis[e][s] = d;
}
}

for(i = n + 1; i <= n + m;i++){
s = i;
dijk(s);
}

if(ans.size() == 0){
cout<<"No Solution"<<endl;
}
else{
sort(ans.begin(),ans.end(),cmp);
printf("G%d\n%.1lf %.1lf\n",ans[0].index,double(ans[0].mindis),ans[0].avgdis);
}
return 0;
}