Problem:
自転車でダイエット

A さんは甘いものが大好きですが、最近は奥さんからダイエットするように言われています。ある日、A さんが自宅から市役所に出かけるとき、奥さんは自転車で行くことを勧めました。そこでA さんはしぶしぶ自転車に乗って出かけましたが、甘い物の好きな A さんは、途中にあるケーキ屋さんに立ち寄りケーキの食べ歩きをしようと思いつきました。

自転車をこげば走行距離に応じてカロリーが消費されますが、ケーキを食べればその分カロリーが摂取されます。正味の消費カロリーは、自転車をこいで消費したカロリーからケーキを食べて摂取したカロリーを引いた値になります。したがって、正味の消費カロリーが 0 より小さくなることもあります。

ケーキ屋さんでケーキを買ったら、 Aさんはその場でケーキを全部食べてしまいます。 Aさんがすべてのケーキ屋さんに立ち寄るとは限りませんが、ケーキ屋さんが存在する地点を通るときには、必ず立ち寄ってケーキを 1 つ買って食べるものとします。ただし、同じケーキ屋さんの前を何度も通るのはさすがに気がひけるので、各ケーキ屋さんに訪れられるのは 1 回だけとします。また、目的地の市役所をいったん通り過ぎてからケーキ屋さんに立ち寄り、その後で市役所に戻って用を済ませてもよいものとし、ケーキ屋さん以外は何度訪れても良いものとします。

A さんの自宅から市役所までの地図情報と、その途中にあるケーキ屋さんで食べられるケーキのカロリーの一覧、単位距離の走行による消費カロリーを入力とし、自宅を出発してから市役所に入るまでの正味の消費カロリーの最小値を出力するプログラムを作成してください。

地図には、A さんの自宅と市役所、ケーキ屋さんとランドマーク(目印)になる建物が書かれています。地図を表す入力データは、A さんの自宅、市役所、ケーキ屋さんとランドマークの各地点の間をつなぐ道があるとき、2 つの地点を表す記号とその間の距離からなる行を含みます。たとえば、5 番目のケーキ屋さんと 3 番目のランドマークの間の距離が 10 なら、入力データは以下のような行を含みます。

C5 L3 10

このようにケーキ屋さんには C、ランドマークには L を番号の前につけて表します。また、A さんの自宅は H、市役所は D で表します。入力データに 2 つの地点とその間の距離が与えられているなら、2 地点の間をどちら向きにも進めます。たとえば、上の例ではケーキ屋さんからランドマークへも、その逆向きへも進むことができます。また、自宅から市役所までは必ずたどり着けるものとします。それ以外に与えられる入力データは、ケーキ屋さんの数 m、ランドマークの数 n、単位距離あたりの消費カロリー k、 1 番目のケーキ屋さんから m 番目のケーキ屋さんまでのそれぞれで買えるケーキのカロリーを表す m 個のデータ、距離のデータの総数 d です。

Input

複数のデータセットの並びが入力として与えられます。入力の終わりは四つの 0 の行で示されます。
各データセットは以下の形式で与えられます。

m n k d
c1 c2 ... cm
s1 t1 e1
s2 t2 e2
:
sd td ed

1 行目にケーキ屋さんの数 m (1 ≤ m ≤ 6)、 ランドマークの数 n (1 ≤ n ≤ 100) 、単位距離あたりの消費カロリー k (1 ≤ k ≤ 5)、距離のデータの総数 d (5 ≤ d ≤ 256) が与えられます。

2 行目に各ケーキ屋で買うケーキのカロリー ci (1 ≤ ci ≤ 100) が与えられます。

続く d 行に i 番目の 2 つの地点間の距離データ si, ti, ei (1 ≤ ei ≤ 20) が与えられます。

データセットの数は 100 を超えません。

Output

入力データセットごとに、全体の消費カロリーの最小値を１行に出力します。

Sample Input

1 1 2 5
35
H L1 5
C1 D 6
C1 H 12
L1 D 10
C1 L1 20
2 1 4 6
100 70
H L1 5
C1 L1 12
C1 D 11
C2 L1 7
C2 D 15
L1 D 8
0 0 0 0

Output for the Sample Input

1
-2

Solution in C (judge verdict: WA: Presentation Error)

cn,cake[6];//P[L®îñ
wn,wg[108][108];//SÌOt
ln,lg[8][8];//ÀèOt
getid(){
	char s[9];
	int r;
	scanf("%s",s);
	if(*s=='C')
		r=atoi(s+1)-1;
	else if(*s=='H')
		r=cn;
	else if(*s=='D')
		r=cn+1;
	else 
		r=cn+1+atoi(s+1);
	return r;
}
dijkstra(s){
	int cost[108],d[108]={0},c,n,i,t;
	//printf("dijkstra(%d)\n",s);
	memset(cost,1,sizeof(cost));
	c=s;
	cost[c]=0;
	for(;c>=0;){
		d[c]=1;
		n=-1;
		for(i=0;i<wn;i++){
			if(!d[i]){
				if(c>=cn||c==s){//n_ÈOÌP[L®Í­
					t=cost[c]+wg[c][i];
					if(t<cost[i])
						cost[i]=t;
				}
				if(n<0||cost[i]<cost[n])
					n=i;
			}
		}
		c=n;
	}
	for(i=0;i<ln;i++){
		//printf("(%d->%d)=%d\n",s,i,cost[i]);
		lg[s][i]=cost[i];
	}
}
solve(){
	int dp[1<<8][8],home=cn,dest=cn+1,b,i,j,nb,t,ans;
	memset(dp,1,sizeof(dp));
	dp[1<<home][home]=0;
	//printf("dp[0x%02x][%d]=0\n",1<<home,home);
	for(b=0;b<1<<ln;b++)
		for(i=0;i<ln;i++)
			if(b&1<<i)
				for(j=0;j<ln;j++)
					if(~b&1<<j){
						nb=b|1<<j;
						t=dp[b][i]+lg[i][j];
						if(t<dp[nb][j])
							//printf("dp[0x%02x][%d]=%d\n",nb,j,t),
							dp[nb][j]=t;
					}
	ans=1e8;
	for(b=1<<home|1<<dest;b<1<<ln;b++){
		t=dp[b][dest];
		for(i=0;i<cn;i++)
			if(b&1<<i)
				t-=cake[i];
		if(t<ans)
			ans=t;
	}
	return ans;
}
main(){
	int k,d;
	int i;
	for(;scanf("%d%d%d%d",&cn,&wn,&k,&d),cn;){
		ln=cn+2;
		wn+=ln;
		for(i=0;i<cn;i++)
			scanf("%d",cake+i);
		memset(wg,1,sizeof(wg));
		for(;d--;){
			int a,b,c;
			a=getid(),b=getid();
			scanf("%d",&c);
			wg[a][b]=wg[b][a]=c*k;
			//printf("(%d->%d)=%d*%d\n",a,b,c,k);
		}
		for(i=0;i<ln;i++)
			dijkstra(i);
		printf("%d \n",solve());
	}
	exit(0);
}