#include <cstdio>
#include <queue>
#include <algorithm>
FILE* in=fopen("politie.in","r");
FILE* out=fopen("politie.out","w");
int n,m,d,p;
struct drum
{
int a,b;
int cat,per;
};
const int Q=250007;
int lst[Q],nxt[4*Q],nrp;
drum val[4*Q];
bool viz[Q];
std::priority_queue<drum> h;
bool operator <(const drum &a, const drum &b)
{
if(a.cat!=b.cat)
return a.cat>b.cat;
return a.per>b.per;
}
int luate[Q];
void disk()
{
viz[1]=1;
for(int p=lst[1]; p; p=nxt[p])
{
h.push(val[p]);
}
drum act;
while(h.size())
{
act=h.top();
h.pop();
if(viz[act.b])
continue;
luate[++luate[0]]=act.per;
viz[act.b]=1;
for(int p=lst[act.b]; p; p=nxt[p])
{
if(viz[val[p].b]==0)
{
h.push(val[p]);
}
}
}
}
void add(int a, int b, int cate, int peri)
{
nrp++;
val[nrp].b=b;
val[nrp].a=a;
val[nrp].cat=cate;
val[nrp].per=peri;
nxt[nrp]=lst[a];
lst[a]=nrp;
}
bool cmp(const int &a, const int &b)
{
return a>b;
}
int main()
{
fscanf(in,"%d%d%d%d",&n,&m,&d,&p);
int a,b,cat,per;
for(int i=1; i<=m; i++)
{
fscanf(in,"%d%d%d%d",&a,&b,&cat,&per);
add(a,b,cat,per);
add(b,a,cat,per);
}
disk();
std::sort(luate+1, luate+n, cmp);
int afis=0;
for(int i=1; i<=n; i++)
{
if(luate[i]!=luate[i-1])
{
afis++;
fprintf(out,"%d\n",luate[i]);
if(afis==p)
return 0;
}
}
return 0;
}