// #pragma GCC optimize("O3,unroll-loops")
// #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#include <bits/allocator.h>
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx,avx2,popcnt,lzcnt")
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define vec vector
#define PB push_back
#define all(x) x.begin(), x.end()
#define F first
#define S second
using pii = pair<int,int>;
int n, k;
// dynamic containers (will be resized after reading n)
vec<vec<pii>> gr;
vec<int> tin;
vec<pii> par;
vec<int> A, B, S;
vec<char> in_cycle;
int tplt = 0, numdfs = 0;
vec<pii> cycle;
void dfs(int u, int p = 0){
tin[u] = ++numdfs;
for (pii &v: gr[u]) if (v.S != p) {
if (!tin[v.F]) {
par[v.F] = {u, v.S};
dfs(v.F, v.S);
} else if (tin[v.F] < tin[u]) {
cycle.clear();
cycle.PB({v.F, v.S});
in_cycle[v.F] = 1;
int t = u;
while (t != v.F) {
in_cycle[t] = 1;
cycle.PB({t, par[t].second});
t = par[t].first;
}
}
}
}
void dfs_tree(int u, int val, int p = 0){
if (u <= n) {
A[tplt] += val;
B[tplt] += val;
}
for (pii v: gr[u]) if (v.F != p && !in_cycle[v.F]) {
dfs_tree(v.F, S[v.S], u);
}
}
void process_cycle(){
for (pii &i : cycle) {
int u = i.F;
for (pii &v : gr[u]) if (!in_cycle[v.F]) dfs_tree(v.F, S[v.S], u);
}
int len = (int)cycle.size();
for (int i = 0; i < len; ++i) {
int val = S[cycle[i].S];
int u = cycle[i].F, v = cycle[(i + 1) % len].F;
if (u <= n) B[tplt] += val;
if (v <= n) A[tplt] += val;
}
}
//
inline void set_bit(vec<uint64_t>& bits, int pos) {
bits[pos >> 6] |= (1ULL << (pos & 63));
}
inline bool test_bit(const vec<uint64_t>& bits, int pos) {
return (bits[pos >> 6] >> (pos & 63)) & 1ULL;
}
void shift_or(vec<uint64_t>& dpbits, int shift, int totbits) {
if (shift == 0) return;
int L = (int)dpbits.size();
int wordShift = shift >> 6;
int bitShift = shift & 63;
vec<uint64_t> orig = dpbits;
if (bitShift == 0) {
for (int i = L - 1; i >= wordShift; --i) {
dpbits[i] |= orig[i - wordShift];
}
} else {
for (int i = L - 1; i >= wordShift; --i) {
uint64_t high = orig[i - wordShift] << bitShift;
uint64_t low = 0;
if (i - wordShift - 1 >= 0) low = orig[i - wordShift - 1] >> (64 - bitShift);
dpbits[i] |= (high | low);
}
}
int excess = (L << 6) - (totbits + 1);
if (excess > 0) {
int last_valid = (totbits) & 63;
dpbits[L - 1] &= ((last_valid == 63) ? ~0ULL : ((1ULL << (last_valid + 1)) - 1ULL));
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> k;
int nodes = 2 * n;
gr.assign(nodes + 5, {});
tin.assign(nodes + 5, 0);
par.assign(nodes + 5, {0, 0});
A.assign(nodes + 5, 0);
B.assign(nodes + 5, 0);
S.assign(nodes + 5, 0);
in_cycle.assign(nodes + 5, 0);
int tot = 0;
for (int i = 1; i <= 2 * n; ++i) {
int u, v; cin >> u >> v >> S[i];
gr[u].PB({n + v, i});
gr[n + v].PB({u, i});
tot += S[i];
}
for (int i = 1; i <= nodes; ++i) if (!tin[i]) {
++tplt;
cycle.clear();
dfs(i);
process_cycle();
}
vector<int> freq(tot + 1, 0);
int base = 0;
for (int i = 1; i <= tplt; ++i) {
base += min(A[i], B[i]);
int diff = abs(A[i] - B[i]);
if (diff <= tot) freq[diff]++;
}
//
int bitsNeeded = tot;
int L = (bitsNeeded + 64) / 64;
vec<uint64_t> dpbits(L, 0ULL);
set_bit(dpbits, 0);
for (int w = 1; w <= tot; ++w) if (freq[w]) {
int cnt = freq[w];
int p = 1;
while (cnt >= p) {
int weight = w * p;
if (weight <= tot) shift_or(dpbits, weight, bitsNeeded);
cnt -= p;
p <<= 1;
}
if (cnt > 0) {
int weight = w * cnt;
if (weight <= tot) shift_or(dpbits, weight, bitsNeeded);
}
}
bool ok = false;
for (int i = base; i <= tot; ++i) {
int pos = i - base;
if (pos <= tot && test_bit(dpbits, pos) && llabs(2LL * i - tot) <= k) {
ok = true; break;
}
}
if (ok) cout << "YES\n";
else cout << "NO\n";
return 0;
}