#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int MAX_N = 1e4+5;
const int MAX_MASK = 1030;
const int inf = 1e9;
struct Edge {
int to;
vector<int> swords;
};
int n, m, d, k;
vector<Edge> G[MAX_N];
int dist[MAX_N][MAX_MASK];
int ans[15];
/*int get_new_mask(int mask_length, int mask, Edge e) {
int new_mask = mask;
for (int bit = 0; bit < mask_length; bit++) {
if (new_mask & (1 << bit)) {
continue;
}
if (e.swords[bit] >= ans[bit]) {
new_mask |= (1 << bit);
}
}
return new_mask;
}*/
vector<int> get_new_mask_list(int mask_length, int mask, Edge e) {
vector<int> bits_to_improve;
for (int bit = 0; bit < mask_length; bit++) {
if (mask & (1 << bit)) {
continue;
}
if (e.swords[bit] >= ans[bit]) {
bits_to_improve.push_back(bit);
}
}
vector<int> new_mask_list;
int len = (int)bits_to_improve.size();
for (int tmp_mask = 0; tmp_mask < (1 << len); tmp_mask++) {
int new_mask = mask;
for (int i = 0; i < len; i++) {
if (tmp_mask & (1 << i)) {
new_mask |= (1 << bits_to_improve[i]);
}
}
new_mask_list.push_back(new_mask);
}
return new_mask_list;
}
bool check(int index) {
int mask_length = index + 1;
for (int i = 1; i <= n; i++) {
for (int mask = 0; mask < (1 << mask_length); mask++) {
dist[i][mask] = inf;
}
}
dist[1][0] = 0;
queue<PII> Q;
Q.push(make_pair(1, 0));
while (!Q.empty()) {
PII tmp = Q.front();
Q.pop();
int v = tmp.first;
int mask = tmp.second;
for (Edge e: G[v]) {
int to = e.to;
//int new_mask = get_new_mask(mask_length, mask, e);
vector<int> new_mask_list = get_new_mask_list(mask_length, mask, e);
for (int new_mask: new_mask_list) {
if (dist[to][new_mask] > dist[v][mask] + 1) {
dist[to][new_mask] = dist[v][mask] + 1;
Q.push(make_pair(to, new_mask));
}
}
}
}
int full_mask = 0;
for (int bit = 0; bit < mask_length; bit++) {
full_mask |= (1 << bit);
}
return dist[n][full_mask] <= d;
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> n >> m >> d >> k;
for (int i = 0; i < n; i++) {
int u, v;
cin >> u >> v;
Edge e1, e2;
e1.to = u;
e2.to = v;
for (int j = 0; j < k; j++) {
int s;
cin >> s;
e1.swords.push_back(s);
e2.swords.push_back(s);
}
G[u].push_back(e2);
G[v].push_back(e1);
}
for (int i = 0; i < k; i++) {
int l = 0;
int r = inf;
while (l < r) {
int mid = (l + r + 1) / 2;
ans[i] = mid;
if (check(i)) {
l = mid;
} else {
r = mid - 1;
}
}
ans[i] = l;
}
for (int i = 0; i < k; i++) {
cout << ans[i] << ' ';
}
return 0;
}