//传送门:https://www.patest.cn/submissions/2864084
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
using namespace std;
#define N 1015
#define M 10015
#define INF 0x3f3f3f3f
char s1[6],s2[6];
int head[N];
struct edge
{
int v,dis,next;
}e[M<<1];
struct node
{
float len,average; // len 垃圾箱 距离居名点的最短距离 , average 垃圾箱 距离居名点的平均距离
bool flag; // 垃圾箱 到 居名点的距离 是否有 超过 限制的最长距离
}no[N];
bool has[N]; // spfa中 标记 在队列中
int d[N]; // 居民点 距离 垃圾箱 的长度
int n,m,k,longest;
inline void spfa(int st)
{
memset(has,0,sizeof(has));
memset(d,INF,sizeof(d));
d[st] = 0; // 初始点 的 距离 设为 0
queue<int>que;
que.push(st);
while(!que.empty()){
int w = que.front(); que.pop();
has[w] = 0;
for(int i=head[w];~i;i=e[i].next){
int v = e[i].v;
if(d[v]<=d[w]+e[i].dis) continue; // 根据 每个居民点 距离 第 st - n 个垃圾箱的距离来更新
d[v] = d[w] + e[i].dis;
if(has[v]) continue;
que.push(v);
has[v] = 1;
}
}
long long sum = 0; // 垃圾箱 距离所有居名点的总距离
int minnum = INF; // 垃圾箱 到所有居名点的最短距离
bool flag = 0;
for(int i=1;i<=n;i++){
if(d[i]>longest){ // 超出限制的距离
flag = 1;
break;
}
minnum = min(minnum,d[i]);
sum += d[i];
}
no[st-n].flag = flag;
if(flag) return;
no[st-n].len = minnum*1.;
no[st-n].average = sum*1./n;
}
int main()
{
scanf("%d%d%d%d",&n,&m,&k,&longest);
int tot = 0;
memset(head,-1,sizeof(head));
while(k--){
scanf("%s%s",s1,s2);
int a,b,c;
if(s1[0]=='G'){
if(strlen(s1)==3) a=10+n; // G10 垃圾箱的编号接在第n个居民点之后 Gm 的编号为 n+m
else a=s1[1]-'0'+n;
}
else a=atoi(s1);
if(s2[0]=='G'){
if(strlen(s2)==3) b=10+n;
else b=s2[1]-'0'+n;
}
else b=atoi(s2);
scanf("%d",&c);
e[tot].v = b;
e[tot].dis = c;
e[tot].next = head[a];
head[a] = tot++;
e[tot].v = a;
e[tot].dis = c;
e[tot].next = head[b];
head[b] = tot++;
}
for(int i=1;i<=m;i++){ // 每个垃圾箱 做一次 spfa
spfa(n+i);
}
bool flag = 0;
float a=0,b=INF; // a记录(垃圾箱中)最长的(每个垃圾箱距离居名点的)最短路 ,b 记录 平均距离
//cout<<"*"<<b<<endl;
int ansnum;
for(int i=1;i<=m;i++){ // 遍历 每个 垃圾箱
if(!no[i].flag){ // 如果满足,尝试更新答案
flag = 1; // 更新过,表示有答案
if(no[i].len>a){ // 记录(垃圾箱中)最长的(每个垃圾箱距离居名点的)最短路
a = no[i].len;
b = no[i].average;
ansnum = i;
}else if(no[i].len == a && no[i].average < b){ // 如果 最短路相同,比较平均距离
b = no[i].average;
ansnum = i;
}
}
}
if(flag){
printf("G%d\n",ansnum);
printf("%.1f %.1f",a,b);
}else printf("No Solution");
}