#include <bits/stdc++.h>
using namespace std;

// Problem: Array of n bits (0 or 1), initially unknown
// Given m queries: XOR of bits in range [l, r] equals v
// Check if queries are consistent (valid assignment exists)

// DSU with parity/XOR tracking between nodes
struct ParityDSU {
    vector<int> p;    // parent
    vector<int> rk;   // rank for union by rank
    vector<int> xr;   // XOR relationship to parent
    
    ParityDSU(int sz = 0) {
        init(sz);
    }
    
    void init(int sz) {
        p.resize(sz);
        rk.assign(sz, 0);
        xr.assign(sz, 0);
        iota(p.begin(), p.end(), 0);
    }
    
    // Returns {root, xor_value_from_u_to_root}
    // Maintains invariant: value[u] XOR xr[u] = value[parent[u]]
    pair<int, int> find(int u) {
        if (p[u] == u) {
            return {u, 0};
        }
        
        // Path compression: update XOR value along path
        auto [rt, x] = find(p[u]);
        xr[u] ^= x;  // Update XOR to root
        p[u] = rt;
        
        return {p[u], xr[u]};
    }
    
    // Add constraint: value[a] XOR value[b] = val
    bool add(int a, int b, int val) {
        auto [ra, xa] = find(a);  // xa = value[a] XOR value[ra]
        auto [rb, xb] = find(b);  // xb = value[b] XOR value[rb]
        
        // Already in same component - check consistency
        if (ra == rb) {
            // value[a] XOR value[b] = (value[a] XOR value[ra]) XOR (value[ra] XOR value[b])
            //                       = xa XOR xb
            return (xa ^ xb) == val;
        }
        
        // Merge two components with union by rank
        if (rk[ra] < rk[rb]) {
            swap(ra, rb);
            swap(xa, xb);
        }
        
        // Make rb point to ra
        p[rb] = ra;
        // value[rb] XOR xr[rb] should equal value[ra]
        // We know: value[a] = value[ra] XOR xa, value[b] = value[rb] XOR xb
        // Given: value[a] XOR value[b] = val
        // So: (value[ra] XOR xa) XOR (value[rb] XOR xb) = val
        // Therefore: value[rb] XOR value[ra] = xa XOR xb XOR val
        xr[rb] = xa ^ xb ^ val;
        
        if (rk[ra] == rk[rb]) {
            rk[ra]++;
        }
        
        return true;
    }
};

class Solution {
public:
    // Check if parity queries are consistent
    bool check(long long n, vector<array<long long, 3>>& qs) {
        // Key idea: XOR of range [l, r] = prefix[r+1] XOR prefix[l]
        // where prefix[i] = XOR of bits [0, i-1]
        // So query [l, r] = v means: prefix[l] XOR prefix[r+1] = v
        
        // Collect all relevant prefix positions
        vector<long long> pts;
        pts.push_back(0);  // Always include prefix[0]
        
        for (auto& q : qs) {
            pts.push_back(q[0]);      // left endpoint
            pts.push_back(q[1] + 1);  // right endpoint + 1
        }
        
        // Coordinate compression (positions can be up to 10^9)
        sort(pts.begin(), pts.end());
        pts.erase(unique(pts.begin(), pts.end()), pts.end());
        
        auto get = [&](long long v) {
            return (int)(lower_bound(pts.begin(), pts.end(), v) - pts.begin());
        };
        
        ParityDSU dsu(pts.size());
        
        // Process each query as constraint: prefix[l] XOR prefix[r+1] = v
        for (auto& q : qs) {
            int l = get(q[0]);
            int r = get(q[1] + 1);
            int v = (int)q[2];
            
            // Add constraint between prefix positions
            if (!dsu.add(l, r, v)) {
                return false;  // Contradiction found
            }
        }
        
        return true;  // All constraints consistent
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    long long n;
    int m;
    cin >> n >> m;
    
    // Each query: [l, r, v] means XOR of range [l, r] equals v
    vector<array<long long, 3>> qs(m);
    for (int i = 0; i < m; i++) {
        cin >> qs[i][0] >> qs[i][1] >> qs[i][2];
    }
    
    Solution sol;
    bool ans = sol.check(n, qs);
    
    cout << (ans ? "YES" : "NO") << "\n";
    
    return 0;
}