#include<stdio.h>
#include<string.h>
#define SIZE 1100
#define TYPE int
struct point
{
int x, y, z;
}node[1010];
struct Edge
{
int f,t;
TYPE cost;
}edge[SIZE*SIZE];
int pre[SIZE],id[SIZE],visit[SIZE];//id用来标记圈的
TYPE in[SIZE];//入弧最小的
#define INF 1000000000
bool flag;
int fabs(int x)
{
if(x < 0) return -x;
return x;
}
int dist(point i, point j)
{
return (fabs(i.x - j.x) + fabs(i.y - j.y) + fabs(i.z - j.z));
}
TYPE DirectedMST(int root,int n,int m)//n表示点数,m表示边数,root表示根
{
int u,v,i;
double re=0;
while(true)
{
for(i=1;i<=n;i++)//点号从1开始
in[i]=INF;
for(i=0;i<m;i++)
{
u=edge[i].f;
v=edge[i].t;
if(edge[i].cost<in[v]&&u!=v)
{
pre[v]=u;//找出每个点的最小入弧\
//if(u==root)
// minRoot=i;
in[v]=edge[i].cost;
}
}
for(i=1;i<=n;i++)
{
if(i==root)
continue;
if(in[i]==INF){
//除根外有个节点无入弧,就返回false
flag=false;
return -1;
}
}
in[root]=0;
int cnt=1;
memset(id,-1,sizeof(id));
memset(visit,-1,sizeof(visit));
for(i=1;i<=n;i++)
{
re+=in[i];//进行缩圈
v=i;
while(visit[v]!=i&&id[v]==-1&&v!=root)
{
visit[v]=i;
v=pre[v];
}
if(v!=root&&id[v]==-1)
{
for(u=pre[v];u!=v;u=pre[u])
id[u]=cnt;
id[v]=cnt++;
}
}
if(cnt==1)
break;
for(i=1;i<=n;i++)
{
if(id[i]==-1)
id[i]=cnt++;
}
for(i=0;i<m;i++)
{
v=edge[i].t;//进行缩点,重新标记。
edge[i].f=id[edge[i].f];
edge[i].t=id[edge[i].t];
if(edge[i].f!=edge[i].t)
edge[i].cost-=in[v];
}
n=cnt-1;
root=id[root];
}
flag=true;
return re;
}
int main()
{
int n, m;
int x, y, z;
while(scanf("%d%d%d%d", &n, &x, &y, &z) != EOF)
{
if(n == 0 && x == 0 && y == 0 && z == 0) break;
for(int i = 1; i <= n; i++)
{
scanf("%d%d%d", &node[i].x, &node[i].y, &node[i].z);
}
//n+1为水源
m = 0;
for(int i = 1; i <= n; i++)
{
edge[m].f = n + 1;
edge[m].t = i ;
edge[m].cost = x * node[i].z;
m++;
}
for(int i = 1; i <= n; i++)
{
int k, zy;
int sum;
scanf("%d", &k);
for(int j = 1; j <= k; j++)
{
scanf("%d", &zy);
if(zy == i) continue;
sum = 0;
if(node[i].z < node[zy].z) sum += z;//y从i引水
//printf("%d\n", sum);
sum += dist(node[i], node[zy]) * y;
if(sum <= edge[zy-1].cost)
{
edge[m].f = i;
edge[m].t = zy;
edge[m].cost = sum;
//printf("sum=%d\n", sum);
m++;
}
}
}
n++;
flag = false;
int re=DirectedMST(n,n,m);
if(!flag) printf("poor XiaoA\n");
else printf("%d\n", re);
}
return 0;
}