Exploration plan

The competitors of Bubble Cup X gathered after the competition and discussed what is the best way to get to know the host country and its cities.

After exploring the map of Serbia for a while, the competitors came up with the following facts: the country has V cities which are indexed with numbers from 1 to V, and there are E bi-directional roads that connect the cites. Each road has a weight (the time needed to cross that road). There are N teams at the Bubble Cup and the competitors came up with the following plan: each of the N teams will start their journey in one of the V cities, and some of the teams share the starting position.

They want to find the shortest time T, such that every team can move in these T minutes, and the number of different cities they end up in is at least K (because they will only get to know the cities they end up in). A team doesn’t have to be on the move all the time, if they like it in a particular city, they can stay there and wait for the time to pass.

Please help the competitors to determine the shortest time T so it’s possible for them to end up in at least K different cities or print -1 if that is impossible no matter how they move.

Note that there can exist multiple roads between some cities.

Input

The first line contains four integers: VEN and K (1 ≤  V  ≤  600,  1  ≤  E  ≤  20000,  1  ≤  N  ≤  min(V, 200),  1  ≤  K  ≤  N), number of cities, number of roads, number of teams and the smallest number of different cities they need to end up in, respectively.

The second line contains N integers, the cities where the teams start their journey.

Next E lines contain information about the roads in following format: A i B i T i (1 ≤ A i, B i ≤ V,  1 ≤ T i ≤ 10000), which means that there is a road connecting cities A i and B i, and you need T i minutes to cross that road.

Output

Output a single integer that represents the minimal time the teams can move for, such that they end up in at least K different cities or output -1 if there is no solution.

If the solution exists, result will be no greater than 1731311.

Example

input

6 7 5 4
5 5 2 2 5
1 3 3
1 5 2
1 6 5
2 5 4
2 6 7
3 4 11
3 5 3

output

3

Note

Three teams start from city 5, and two teams start from city 2. If they agree to move for 3 minutes, one possible situation would be the following: Two teams in city 2, one team in city 5, one team in city 3 , and one team in city 1. And we see that there are four different cities the teams end their journey at.

#include <bits/stdc++.h>

using namespace std;

template <class T> class flow_graph {
public:
static constexpr T eps = (T) 1e-9;

struct edge {
int to;
T c;
T f;
int rev;
};

vector < vector <edge> > g;
vector <int> ptr;
vector <int> d;
int n;
int st, fin;
bool modified;

flow_graph(int n, int st, int fin) : n (n), st (st), fin (fin) {
modified = true;
assert(0 <= st && st < n && 0 <= fin && fin < n && st != fin);
    g.resize(n);
    ptr.resize(n);
    d.resize(n);
  }

  void clear_flow() {
    modified = true;
    for (int i = 0; i < n; i++) {
      for (edge &e : g[i]) {
        e.f = 0;
      }
    }
  }

  void add(int from, int to, T forward_cap, T backward_cap) {
    modified = true;
    assert(0 <= from && from < n && 0 <= to && to < n);
    int from_size = g[from].size();
    int to_size = g[to].size();
    g[from].push_back({to, forward_cap, 0, to_size});
    g[to].push_back({from, backward_cap, 0, from_size});
  }

  bool expath() {
    queue <int> q({st});
fill(d.begin(), d.end(), -1);
d[st] = 0;
while (!q.empty()) {
int i = q.front();
q.pop();
for (edge &e : g[i]) {
if (e.c > e.f + eps && d[e.to] == -1) {
d[e.to] = d[i] + 1;
if (e.to == fin) {
return true;
}
q.push(e.to);
}
}
}
return false;
}

T dfs(int v, T w) {
if (v == fin) {
return w;
}
T r = 0;
int j = ptr[v];
while (j > 0) {
j--;
edge &e = g[v][j];
if (e.c > e.f + eps && d[e.to] == d[v] + 1) {
T ww = e.c - e.f;
if (v != st) {
ww = min(ww, w - r);
}
T t = dfs(e.to, ww);
if (t > 0) {
e.f += t;
g[e.to][e.rev].f -= t;
r += t;
if (v != st && r >= w - eps) {
return r;
}
}
}
ptr[v]--;
}
return r;
}

T flow;

T max_flow() {
if (!modified) {
return flow;
}
modified = false;
T ans = 0;
while (expath()) {
for (int i = 0; i < n; i++) {
        ptr[i] = g[i].size();
      }
      T add = dfs(st, -1);
      if (add <= eps) {
        break;
      }
      ans += add;
    }
    return flow = ans;
  }

  vector <bool> min_cut() {
max_flow();
vector <bool> ret(n);
for (int i = 0; i < n; i++) {
      ret[i] = (d[i] != -1);
    }
    return ret;
  }
};

const int N = 1234;

int city[N];
int g[N][N];

int main() {
  int v, e, n, k;
  scanf("%d %d %d %d", &v, &e, &n, &k);
  for (int i = 0; i < n; i++) {
    scanf("%d", city + i);
    city[i]--;
  }
  for (int i = 0; i < v; i++) {
    for (int j = 0; j < v; j++) {
      g[i][j] = (i == j ? 0 : (int) 1e9);
    }
  }
  for (int i = 0; i < e; i++) {
    int x, y, z;
    scanf("%d %d %d", &x, &y, &z);
    x--; y--;
    g[x][y] = min(g[x][y], z);
    g[y][x] = min(g[y][x], z);
  }
  for (int k = 0; k < v; k++) {
    for (int i = 0; i < v; i++) {
      for (int j = 0; j < v; j++) {
        g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
      }
    }
  }
  const int inf = (int) 2e6;
  int low = 0, high = inf;
  while (low < high) {
    int mid = (low + high) >> 1;
flow_graph <int> gr(n + v + 2, n + v, n + v + 1);
for (int i = 0; i < n; i++) {
      gr.add(n + v, i, 1, 0);
    }
    for (int j = 0; j < v; j++) {
      gr.add(n + j, n + v + 1, 1, 0);
    }
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < v; j++) {
        if (g[city[i]][j] <= mid) {
          gr.add(i, n + j, 1, 0);
        }
      }
    }
    if (gr.max_flow() >= k) {
high = mid;
} else {
low = mid + 1;
}
}
printf("%d\n", low == inf ? -1 : low);
return 0;
}