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++11 (judge verdict: Wrong Answer)

#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <map>
#include <set>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iterator>
#include <bitset>
//#include <utility>
//#include <memory>
//#include <functional>
//#include <deque>
//#include <cctype>
//#include <ctime>
//#include <numeric>
//#include <list>
//#include <iomanip>

//#if __cplusplus >= 201103L
//#include <array>
//#include <tuple>
//#include <initializer_list>
//#include <unordered_set>
//#include <unordered_map>
//#include <forward_list>
//
//#define cauto const auto&
//#else

//#endif

using namespace std;


namespace{
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

typedef vector<int> vint;
typedef vector<vector<int> > vvint;
typedef vector<long long> vll, vLL;
typedef vector<vector<long long> > vvll, vvLL;

#define VV(T) vector<vector< T > >

template <class T>
void initvv(vector<vector<T> > &v, int a, int b, const T &t = T()){
    v.assign(a, vector<T>(b, t));
}

template <class F, class T>
void convert(const F &f, T &t){
    stringstream ss;
    ss << f;
    ss >> t;
}


#define reep(i,a,b) for(int i=(a);i<(b);++i)
#define rep(i,n) reep((i),0,(n))
#define ALL(v) (v).begin(),(v).end()
#define PB push_back
#define F first
#define S second
#define mkp make_pair
#define RALL(v) (v).rbegin(),(v).rend()


#define MOD 1000000007LL
#define EPS 1e-8
static const int INF=1<<24;

void mainmain(){
	int m,n,k,d;
	while(cin>>m>>n>>k>>d,m||n||k||d){
		vvint dp;
		initvv(dp,m+n+2,1<<m,INF);
		VV(pii) vv(m+n+2);
		vint cake(m+1,0);
		rep(i,m){
			cin>>cake[i+1];
		}
		rep(i,d){
			string s1,s2;
			int c;
			cin>>s1>>s2>>c;
			int a,b;
			if(s1[0]=='H'){
				a=0;
			}
			if(s1[0]=='C'){
				a=s1[1]-'0';
			}
			if(s1[0]=='L'){
				a=s1[1]-'0'+m;
			}
			if(s1[0]=='D'){
				a=n+m+1;
			}
			if(s2[0]=='H'){
				b=0;
			}
			if(s2[0]=='C'){
				b=s2[1]-'0';
			}
			if(s2[0]=='L'){
				b=s2[1]-'0'+m;
			}
			if(s2[0]=='D'){
				b=n+m+1;
			}
			vv[a].PB(pii(b,k*c));
			vv[b].PB(pii(a,k*c));
		}
		priority_queue<pair<int,pii>> pq;
		pq.push(mkp(0,pii(0,0)));
		while(!pq.empty()){
			pair<int,pii> top=pq.top();
			pq.pop();
			if(dp[top.S.F][top.S.S]!=INF){
				continue;
			}
			// cout<<top.S.F<<" "<<top.S.S<<" "<<-top.F<<endl;
			dp[top.S.F][top.S.S]=-top.F;
			int now=top.S.F;
			rep(i,vv[now].size()){
				int next=vv[now][i].F;
				if(1<=next&&next<=m&&(top.S.S&(1<<next-1))){
					continue;
				}
				pair<int,pii> t=top;
				if(1<=next&&next<=m){
					t.S.S|=1<<(next-1);
					t.F+=cake[next];
				}
				t.F-=vv[now][i].S;
				t.S.F=next;
				if(dp[t.S.F][t.S.S]==INF){
					pq.push(t);
				}
			}
		}
		int ans=INF;
		rep(i,1<<m){
			ans=min(ans,dp[n+m+1][i]);
		}
		cout<<ans<<endl;
	}
}



}
main() try{
    mainmain();
}
catch(...){
}