#include <bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;
const int N = 1210, M = 15;
int n, m, k, ds;
unordered_map<string, int> var;
unordered_map<int, string> local;
vector<pair<int, int>> g[N];
int dist[N];
bool st[N];
struct Z{
int d;
double aver;
int var;
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
for (int i = 1; i <= 10; i++) {
string v = "G" + to_string(i);
var[v] = i + 1000;
local[i + 1000] = v;
}
cin >> n >> m >> k >> ds;
for (int i = 0; i < k; i++) {
string a, b;
int w;
cin >> a >> b >> w;
int aa, bb;
if (a[0] == 'G') {
aa = var[a];
} else aa = stoi(a);
if (b[0] == 'G') {
bb = var[b];
} else bb = stoi(b);
g[aa].push_back({bb, w});
g[bb].push_back({aa, w});
}
int res1 = -1;
double resmindist = -1, resaver = 1e9;
for (int i = 1; i <= m; i++) {
int ljvar = i + 1000;
// cout << local[ljvar] << "\n";
memset(dist, 0x3f, sizeof dist);
memset(st, false, sizeof st);
priority_queue<pii, vector<pii>, greater<pii>> heap;
dist[ljvar] = 0;
heap.push({dist[ljvar], ljvar});
while (heap.size()) {
auto t = heap.top();
heap.pop();
int u = t.second;
if (st[u]) continue;
st[u] = true;
for (auto itr : g[u]) {
int v = itr.first, w = itr.second;
if (dist[v] > dist[u] + w) {
dist[v] = dist[u] + w;
heap.push({dist[v], v});
}
}
}
//1. 所有居民点最短距离最长 输出
//2. 平均距离最短 输出
//3. 编号最小 输出
int d = 0;
bool ok = 1;
int mindist = 1e9;
for (int j = 1; j <= n; j++) {
if (dist[j] == 0x3f3f3f3f || dist[j] > ds) { //未到达 或者距离不满足
ok = 0;
continue;
}
d += dist[j];
mindist = min(mindist, dist[j]);
}
//cout << "d == " << d << " mindist = " << mindist << " resaver = " << resaver << "\n";
double av = 1.0 * d / (1.0 * n);
if (!ok) continue;
if (resmindist < mindist) {
resmindist = mindist;
res1 = ljvar;
resaver = av;
} else if (resmindist == mindist) {
if (resaver > av) {
res1 = ljvar;
resaver = av;
}
}
}
if (res1 == -1) cout << "No Solution";
else {
cout << local[res1] << "\n";
cout << fixed << setprecision(1) << resmindist << " " << resaver;
}
cout << "\n";
return 0;
}