#include <bits/stdc++.h>
using namespace std;
const int NR = 2005;
const int MR = 2e6 + 10;
const int INF = 0x3f3f3f3f;
void Min(int& x, int y) { x = min(x, y); }
void Max(int& x, int y) { x = max(x, y); }
int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = (x << 3) + (x << 1) + (ch ^ 48);
    ch = getchar();
  }
  return x * f;
}
int n, m, k, t, mx, S, T;
int cnt[NR];
int to[MR], nxt[MR], val[MR], head[NR], tot = 1;
void add(int x, int y, int z) {
  to[tot] = y, val[tot] = z, nxt[tot] = head[x], head[x] = tot++;
}
int a[NR];
int dis[NR][NR];
struct Nd {
  int x, d;
  bool operator<(const Nd& A) const { return d > A.d; }
};
Nd md(int x, int d) {
  Nd tmp;
  tmp.x = x, tmp.d = d;
  return tmp;
}
bool vis[NR];
void dijkstra(int s) {
  memset(vis, 0, sizeof(vis));
  memset(dis[s], 0x3f, sizeof(dis[s]));
  priority_queue<Nd> q;
  q.push(md(s, 0));
  dis[s][s] = 0;
  while (!q.empty()) {
    int x = q.top().x;
    q.pop();
    if (vis[x]) continue;
    vis[x] = 1;
    for (int i = head[x]; i; i = nxt[i]) {
      int y = to[i];
      if (dis[s][y] > dis[s][x] + val[i]) {
        dis[s][y] = dis[s][x] + val[i];
        q.push(md(y, dis[s][y]));
      }
    }
  }
}
void rebuild(int len) {
  memset(head, 0, sizeof(head));
  tot = 1;
  S = 0, T = n * 2 + 1;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++)
      if (dis[i][j] <= len) add(i, j + n, INF), add(j + n, i, 0);
  for (int i = 1; i <= n; i++)
    if (cnt[i]) add(S, i, cnt[i]), add(i, S, 0);
  for (int i = 1; i <= n; i++) add(i + n, T, 1), add(T, i + n, 0);
}
int dep[NR], now[NR];
bool bfs() {
  memset(dep, 0, sizeof(dep));
  dep[S] = 1;
  queue<int> q;
  q.push(S);
  now[S] = head[S];
  while (!q.empty()) {
    int x = q.front();
    q.pop();
    for (int i = head[x]; i; i = nxt[i]) {
      int y = to[i];
      if (val[i] && !dep[y]) {
        dep[y] = dep[x] + 1;
        now[y] = head[y];
        q.push(y);
        if (y == T) return 1;
      }
    }
  }
  return 0;
}
int dinic(int x, int flow) {
  if (x == T) return flow;
  int mxflow = 0;
  for (int i = head[x]; i; i = nxt[i]) {
    int y = to[i];
    now[x] = i;
    if (flow == mxflow) return flow;
    if (dep[y] == dep[x] + 1 && val[i]) {
      int num = dinic(y, min(val[i], flow - mxflow));
      val[i] -= num;
      val[i * 2 - (i ^ 1)] += num;
      mxflow += num;
      if (!num) dep[y] = -1;
    }
  }
  return mxflow;
}
bool check(int len) {
  rebuild(len);
  int res = 0;
  while (bfs()) res += dinic(S, INF);
  return res >= t;
}
int main() {
  n = read(), m = read(), k = read(), t = read();
  for (int i = 1; i <= k; i++) a[i] = read(), cnt[a[i]]++;
  for (int i = 1, x, y, z; i <= m; i++) {
    x = read(), y = read(), z = read(), add(x, y, z), add(y, x, z);
  }
  for (int i = 1; i <= n; i++) dijkstra(i);
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++) Max(mx, dis[i][j]);
  int l = 0, r = mx, ans = -1;
  while (l <= r) {
    int mid = (l + r) / 2;
    if (check(mid))
      ans = mid, r = mid - 1;
    else
      l = mid + 1;
  }
  if (ans == INF) ans = -1;
  printf("%d\n", ans);
  return 0;
}
