/********************************************************************************
模板题。。。问题是比赛的时候一直没看出来,以为最小费用流,Racebug用邻接矩阵敲的,
结果杯具TLE,要是用邻接表再稍微优化下的,就过了~
********************************************************************************/
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <utility>
#include <cstdio>
#include <memory>
#include <string>
#include <vector>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef map<int, int>::iterator MI;
typedef vector<int>::iterator VI;
typedef set<int>::iterator SI;
const int INF_INT = 0x3f3f3f3f;
const double oo = 10e9;
const double eps = 10e-7;
const double PI = acos(-1.0);
const int MAXV = 1004;
const int MAXE = MAXV * MAXV;
struct Point
{
int x, y, z;
}pnt[MAXV];
struct Edges
{
int beg, end;
int cost;
int next;
}edges[MAXE];
int ecnt, head[MAXV];
int n, X, Y, Z;
int in[MAXV], pre[MAXV], id[MAXV], vis[MAXV];
const int src = 0;
inline int manhattan_dist(const Point &pa, const Point &pb)
{
return abs(pa.x - pb.x) + abs(pa.y - pb.y) + abs(pa.z - pb.z);
}
inline void add_edge(int u, int v, int c)
{
edges[ecnt].beg = u;
edges[ecnt].end = v;
edges[ecnt].cost = c;
edges[ecnt].next = head[u];
head[u] = ecnt++;
return ;
}
int directed_mst(int root, int vcnt)
{
int res = 0;
while (true)
{
fill(in, in + vcnt, INF_INT);
for (int i = 0; i < ecnt; ++i)
{
int u = edges[i].beg;
int v = edges[i].end;
if (edges[i].cost < in[v] && u != v)
{
pre[v] = u;
in[v] = edges[i].cost;
}
}
for (int i = 0; i < vcnt; ++i)
{
if (root == i)
{
continue ;
}
if (INF_INT == in[i])
{
return -1;
}
}
int ncnt = 0;
fill(id, id + vcnt, -1);
fill(vis, vis + vcnt, -1);
in[root] = 0;
for (int i = 0; i < vcnt; ++i)
{
res += in[i];
int v = i;
while (vis[v] != i && -1 == id[v] && v != root)
{
vis[v] = i;
v = pre[v];
}
if (v != root && -1 == id[v])
{
for (int u = pre[v]; u != v; u = pre[u])
{
id[u] = ncnt;
}
id[v] = ncnt++;
}
}
if (0 == ncnt)
{
break ;
}
for (int i = 0; i < vcnt; ++i)
{
if (-1 == id[i])
{
id[i] = ncnt++;
}
}
for (int i = 0; i < ecnt; ++i)
{
int v = edges[i].end;
edges[i].beg = id[ edges[i].beg ];
edges[i].end = id[ edges[i].end ];
if (edges[i].beg != edges[i].end)
{
edges[i].cost -= in[v];
}
}
vcnt = ncnt;
root = id[root];
}
return res;
}
void ace()
{
int k, u, v;
int ans, buf;
while (scanf("%d %d %d %d", &n, &X, &Y, &Z), n || X || Y || Z)
{
++n;
ecnt = 0;
memset(head, -1, sizeof(head));
for (int i = 1; i < n; ++i)
{
scanf("%d %d %d", &pnt[i].x, &pnt[i].y, &pnt[i].z);
}
for (u = 1; u < n; ++u)
{
add_edge(src, u, pnt[u].z * X);
}
for (u = 1; u < n; ++u)
{
scanf("%d", &k);
while (k--)
{
scanf("%d", &v);
if (v == u)
{
continue ;
}
buf = manhattan_dist(pnt[u], pnt[v]) * Y;
if (pnt[u].z < pnt[v].z)
{
buf += Z;
}
add_edge(u, v, buf);
}
}
ans = directed_mst(src, n);
if (-1 == ans)
{
puts("poor XiaoA");
}
else
{
printf("%d\n", ans);
}
}
return ;
}
int main()
{
ace();
return 0;
}