// ROOT : DRAGON3012009 : WA in Real Life
#include <bits/stdc++.h>
#define FOR(i,l,r) for(int i = l ; i <= r ; i ++)
#define FORD(i,r,l) for(int i = r ; i >= l ; i --)
#define REP(i, a ) for(int i = 0 ; i < a ; i ++ )
#define compare(v) sort((v).begin(), (v).end()); (v).erase(unique((v).begin(), (v).end()), (v).end());
#define ll long long
#define el "\n"
#define fi first
#define se second
#define _ROOT_ int main()
#define M 1000000007
#define MAXN 1111
#define Bit(i) (1LL << i )
#define INF (1ll<<60)
#define NAME "file"
#define debug(a) cout << #a << " = " << a << endl;
using namespace std;

ll n, m, q, k, type ;
ll a[MAXN] ;
ll d[MAXN / 10 ][1 << 10 ] ;
ll lab[MAXN ] ;
vector<pair<ll,ll>> adj[MAXN ] ;
vector<ll> spec ;


struct Edge {
    ll u, v, w ;
    bool operator < (const Edge & other ) const {
        return w < other.w ;
    }
} edge[MAXN ] ;

ll find_set(ll a ) {
    return lab[a] < 0 ? a : lab[a] = find_set(lab[a]) ;
}

struct Data {
    ll u, mask, w ;
    bool operator < (const Data & other )const {
        return w > other.w ;
    }
};

bool union_set(ll a, ll b ) {
    a = find_set(a) ;
    b = find_set(b) ;
    if(a == b ) return false ;
    if(lab[a] > lab[b]) swap(a, b ) ;
    lab[a] += lab[b] ;
    lab[b] = a ;
    return true ;
}

void init() {
    cin >> n >> k >> m >> type  ;
    FOR(i, 1, k ) {
        ll x ;
        cin >> x ;
        spec.push_back(x) ;
    }
    FOR(i, 1, m ) {
        ll x, y, w ;
        cin >> x >> y >> w ;
        edge[i] = {x, y, w } ;
        adj[x].push_back({y, w }) ;
        adj[y].push_back({x, w }) ;
    }
}

void solve() {
    sort(edge + 1, edge + m + 1 ) ;
    memset(lab, -1, sizeof lab ) ;
    ll ans = INF ;
    if(k == n && type == 1 ) {
        ll mst = 0 ;
        FOR(i, 1, m ) {
            if(union_set(edge[i].u, edge[i].v )) mst += edge[i].w ;
        }
        cout << mst << el ;
        return ;
    }
    if(type == 1 ) {
        FOR(i, 0, n ) REP(mask, 1 << k ) d[i][mask] = INF ;
        REP(i, k ) d[spec[i]][1 << i ] = 0 ;
        REP(mask, 1 << k ) {
            if(mask == 0 ) continue ;

            FOR(i, 1, n  ) {
                for(ll sub_mask = mask ; sub_mask ; sub_mask = mask & (sub_mask - 1 )) d[i][mask] = min(d[i][mask], d[i][sub_mask] + d[i][sub_mask ^ mask ]) ;
            }

            priority_queue<Data > pq ;
            FOR(i, 1, n ) if(d[i][mask] != INF ) pq.push({i, mask, d[i][mask] }) ;
            while(!pq.empty() ) {
                Data u = pq.top() ;
                pq.pop() ;
                if(d[u.u][u.mask ] < u.w ) continue ;
                for(pair<ll,ll> v : adj[u.u] ) if(d[v.fi][u.mask] > u.w + v.se ) pq.push({v.fi, u.mask, d[v.fi][u.mask] = u.w + v.se }) ;
            }
        }
        FOR(i, 1, n ) ans = min(ans, d[i][(1 << k ) - 1 ]) ;
        cout << ans << el ;
    } else {
        vector<ll> in_mst(n + 10, 1 ) ;
        ll cnt_active = n ;
        for(ll v : spec ) in_mst[v] = false, cnt_active --  ;
        REP(mask, 1 << k ) {
            REP(i, k ) if(mask >> i & 1 ) in_mst[spec[i]] = true, cnt_active ++  ;
            FOR(i, 1, n ) lab[i] = -1 ;
            ll cc = 0, mst = 0 ;
            FOR(i, 1, m ) if(in_mst[edge[i].u] && in_mst[edge[i].v] && union_set(edge[i].u, edge[i].v ) ) {
                cc ++ ;
                mst += edge[i].w ;
            }
            if(cnt_active - 1 == cc ) ans = min(ans, mst ) ;

            REP(i, k ) if(mask >> i & 1 ) in_mst[spec[i]] = false, cnt_active -- ;
        }
        cout << ans << el ;
    }
}


_ROOT_ {
//    freopen(NAME".inp", "r", stdin);
//    freopen(NAME".out", "w", stdout) ;
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t = 1; // cin >> t ;
    while(t--) {
        init();
        solve();
    }
    return (0&0);
}
