#include <iostream>
#include <cstdio>
#include <queue>
#include <vector>
using namespace std;
const int MAXN = 101;
struct TreeNode {
int weight;
vector<int> children;
} tree[MAXN];
struct Path {
vector<int> p;
Path() {}
Path(int x) {
p.push_back(x);
}
void Print() const { // 结构体内部函数,要加上一个const声明
int len = p.size(),flag=0;
for(int i=0; i<len; i++) {
if(flag==0)
flag=1;
else
printf(" ");
printf("%d",p[i]);
}
printf("\n");
}
bool operator< (const Path& y) const { // 比较两个路径的 "大小"
int len1 = p.size(),len2=y.p.size(),i=0,j=0;
while(i<len1&&j<len2) {
if(p[i]!=y.p[j])
return p[i] < y.p[j];
i++;
j++;
}
return true;
}
};
int N,M,S;
// 若result队列的元素是string类型,在判断10与9的大小关系上会出错,所以还是用一个专门的结构体Path来存储路径
priority_queue<Path> result; // 实现对结果的排序输出
void DFS(int root,Path path,int pathWeight) {
if(pathWeight>S)
return;
else if(tree[root].children.empty() && pathWeight==S) { // 到达叶结点
result.push(path);
} else {
int len = tree[root].children.size();
for(int i=0; i<len; i++) {
int elem = tree[root].children[i];
Path temp = path;
temp.p.push_back(tree[elem].weight);
DFS(elem,temp,pathWeight+tree[elem].weight);
}
}
}
int main() {
scanf("%d%d%d",&N,&M,&S);
for(int i=0; i<N; i++) {
scanf("%d",&tree[i].weight);
}
for(int i=0; i<M; i++) {
int elem,num,child;
scanf("%d%d",&elem,&num);
for(int j=0; j<num; j++) {
scanf("%d",&child);
tree[elem].children.push_back(child);
}
}
DFS(0,Path(tree[0].weight),tree[0].weight);
while(!result.empty()) {
result.top().Print();
result.pop();
}
return 0;
}