#include <bits/stdc++.h>
using namespace std;
template<typename Weight>
struct Dinic {
struct Edge {
int src, dst, rev;
Weight weight;
Edge(int f, int t, Weight cap, int rev = 0) :
src(f), dst(t), rev(rev), weight(cap) {}
};
int n;
vector<vector<Edge>> adj;
static const Weight INF = numeric_limits<Weight>::max();
Dinic(int _n) : n(_n), adj(n) {}
void add_edge(const int src, const int dst, const Weight cap = INF) {
adj[src].emplace_back(Edge(src, dst, cap, adj[dst].size()));
adj[dst].emplace_back(Edge(dst, src, 0, adj[src].size() - 1));
}
Weight MaximumFlow(const int s, const int t) {
Weight flow = 0;
while(true) {
vector<int> level(n, -1), iter(n);
Bfs(s, level);
if(level[t] == -1) break;
for (Weight f = 0; (f = Dfs(s, t, INF, level, iter)) > 0; )
flow += f;
}
return flow;
}
void Bfs(const int s, vector<int> &level){
queue<int> que;
for (level[s] = 0, que.push(s); !que.empty(); ) {
const int v = que.front(); que.pop();
for (auto &e : adj[v])
if(0 < e.weight && level[e.dst] == -1){
level[e.dst] = level[v] + 1;
que.push(e.dst);
}
}
}
Weight Dfs(int v, int t, Weight flow, vector<int> &level, vector<int> &iter) {
if(v == t) return flow;
for ( ; iter[v] < (int)adj[v].size(); ++iter[v]) {
Edge &e = adj[v][iter[v]];
if(0 < e.weight && level[v] < level[e.dst]){
Weight d = Dfs(e.dst, t, min(flow, e.weight), level, iter);
if(0 < d){
e.weight -= d;
adj[e.dst][e.rev].weight += d;
return d;
}
}
}
return 0;
}
};
int main() {
cin.tie(0); ios::sync_with_stdio(false);
int n, m, p, g;
cin >> n >> m >> p >> g;
const int s = m, t = 0;
Dinic<int> graph(m + 1);
for (int i = 0, l; i < g; ++i) {
cin >> l;
graph.add_edge(s, l);
}
for (int i = 0; i < n; ++i) {
int from, to, cap;
cin >> from >> to >> cap;
graph.add_edge(from, to, cap);
}
cout << (p <= graph.MaximumFlow(s, t) ? "Yes" : "No") << endl;
return 0;
}