for(int u=pre[v]; u!=v; u=pre[u]){
id[u] = MXid;
}
id[v] = MXid++;
}
}
if(MXid==1) break;
for(int i=1; i
for(int i=0; i
E[i].u = id[u];
E[i].v = id[v];
if(id[u] != id[v]) E[i].w -= in[v];
}
n = MXid;
root = id[root];
}
return ans;
}
private:
struct Edge{
int u,v;
Type w;
void set(int _u,int _v,Type _w){
u=_u,v=_v,w=_w;
}
}E[VN*VN/2];
Type ans; // 所求答案
int n; // 结点个数
int size; // 边的数量
int pre[VN]; // 权值最小的前驱边
int id[VN];
int vis[VN]; // 是在环中还是在环外
};
Directed_MST
int X[VN],Y[VN],Z[VN];
int x,y,z;
inline int Price(int i, int j){
if(i==j) return Z[i]*x;
int mht = abs(X[i]-X[j])+abs(Y[i]-Y[j])+abs(Z[i]-Z[j]);
if(Z[i]>=Z[j]) return mht*y;
return mht*y+z;
}
int main(){
int n,m,k,u,v,w;
while(~scanf("%d%d%d%d",&n,&x,&y,&z)&&x+y+z){
G.init(n+1);
for(int i=1; i<=n; ++i){
scanf("%d%d%d",&X[i],&Y[i],&Z[i]);
G.insert(n+1, i, Z[i]*x);
}
for(int u=1; u<=n; ++u){
scanf("%d",&k);
for(int j=1; j<=k; ++j){
scanf("%d",&v);
if(u==v) continue;
G.insert(u,v,Price(u,v));
}
}
int ans = G.directed_mst(n+1);
if(ans<0) puts("poor XiaoA");
else printf("%d\n",ans);
}
return 0;
}