#include <iostream>
#include <string.h>
#include <vector>
using namespace std;
struct node
{
int next, dis;
};
int n;
int getindex(char s[])
{
int index = 0, i, begin = 0, len = strlen(s);
char ch = s[0];
if(ch == 'G')
{
begin = 1;
}
for(i = begin; i < len; i++)
{
index = index * 10 + s[i] - '0';
}
if(ch == 'G')
{
index += n;
}
return index;
}
int main()
{
int m, k, ds;
scanf("%d%d%d%d", &n, &m, &k, &ds);
int i, index[2], j;
char ch[2][5];
node nod;
vector<node> v[1020];
for(i = 1; i <= k; i++)
{
getchar();
scanf("%s%s%d", ch[0], ch[1], &nod.dis);
for(j = 0; j <= 1; j++)
{
index[j] = getindex(ch[j]);
}
nod.next = index[1];
v[index[0]].push_back(nod);
nod.next = index[0];
v[index[1]].push_back(nod);
}
int dis[1020], mark[1020], p, size, q, next, nextdis, min, flag, resindex = -1, resmindis = -1, curmindis;
double resdisavg = 100000000, curdisavg;
for(i = n + 1; i <= n + m; i++)
{
memset(dis, -1, sizeof(dis));
memset(mark, 0, sizeof(mark));
p = i;
dis[p] = 0;
mark[p] = 1;
curdisavg = 0;
curmindis = 100000000;
flag = 1;
for(j = 1; j < n + m; j++)
{
size = v[p].size();
for(q = 0; q < size; q++)
{
next = v[p][q].next;
if(mark[next] == 0)
{
nextdis = dis[p] + v[p][q].dis;
if(dis[next] == -1 || dis[next] > nextdis)
{
dis[next] = nextdis;
}
}
}
min = 100000000;
for(q = 1; q <= n + m; q++)
{
if(mark[q] == 1 || dis[q] == -1)
{
continue;
}
if(dis[q] < min)
{
min = dis[q];
p = q;
}
}
if(p <= n)
{
if(min > ds)
{
flag = 0;
break;
}
if(min < curmindis)
{
curmindis = min;
}
curdisavg += min;
}
mark[p] = 1;
}
if(flag == 0)
{
continue;
}
flag = 0;
curdisavg /= n;
if(curmindis > resmindis)
{
flag = 1;
}
else if(curmindis == resmindis && curdisavg < resdisavg)
{
flag = 1;
}
if(flag == 1)
{
resindex = i;
resmindis = curmindis;
resdisavg = curdisavg;
}
}
if(resindex == -1)
{
printf("No Solution\n");
}
else
{
printf("G%d\n%.1lf %.1lf\n", resindex - n, resmindis * 1.0, resdisavg);
}
system("pause");
return 0;
}