// I/O
#include <iostream>
#include <iomanip>

// data structures
#include <queue>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>

// manipulations
#include <algorithm>

// others
#include <cassert>

#define rep(i,n) for(int (i)=0;(i)< (n);++(i))
#define REP(i,n) for(int (i)=1;(i)<=(n);++(i))
#define for_lowercase(c) for(char (c)='a';(c)<='z';++(c))
#define for_uppercase(c) for(char (c)='A';(c)<='Z';++(c))
#define ALL(a) (a).begin(),(a).end()
using LLI = long long int;
LLI GCD(LLI a,LLI b){ if(a<b) return GCD(b,a); else if(a%b==0) return b; else return GCD(b,a%b); }
LLI LCM(LLI a,LLI b){ return (a/GCD(a,b))*b; }
using VI  = std::vector<LLI>;
using PII  = std::pair<LLI,LLI>;
using VVI = std::vector<VI>;
using VPII = std::vector<PII>;
template<class T> bool is_odd (T x){ return   x%2 ; }
template<class T> bool is_even(T x){ return !(x%2); }
LLI combination(LLI n,LLI k,bool reset=false){
    static VVI C; static LLI n_hashed = -1;
    if(n<0){ std::cerr << "[ERROR] n must be non-negative in combination()" << std::endl; exit(1); }
    if(!(0<=k&&k<=n)){ std::cerr << "[WARNING] k should be in range [0,n] in combination()" << std::endl; return 0; }
    if(n_hashed<n || reset){
        C.resize(n+1);
        for(int i=0;i<=n;++i) C[i].resize(i+1,1); // filled with 1
        for(int i=1;i<=n;++i)for(int j=1;j<i;++j) C[i][j] = C[i-1][j-1] + C[i-1][j];
        n_hashed = n;
    }
    return C[n][k];
}
namespace compProg{
    template<class T> std::ostream& ostream_iterable_impl(std::ostream &os,
                                                          const T &t,
                                                          const std::string &LEFT,
                                                          const std::string &RIGHT,
                                                          const std::string &DELIMITER){
        bool first = true;
        os << LEFT;
        for(const auto &x:t){
            if(first) first = false;
            else os << DELIMITER;
            os << x;
        }
        os << RIGHT;
    }
    void please_never_call_this_function_to_eliminate_warning(){
        is_odd(0); is_even(0); combination(0,0); LCM(0,0);
        rep(i,0)REP(j,0)for_lowercase(c)for_uppercase(c);
        std::sort(ALL(std::string("")));
    }
}
template<class T> std::ostream& operator<<(std::ostream &os,const std::vector<T> &t){
    return compProg::ostream_iterable_impl(os,t,"[","]",", ");
}
template<class T> std::ostream& operator<<(std::ostream &os,const std::set<T> &t){
    return compProg::ostream_iterable_impl(os,t,"{","}",", ");
}
template<class T> std::ostream& operator<<(std::ostream &os,const std::multiset<T> &t){
    return compProg::ostream_iterable_impl(os,t,"{","}",", ");
}

// begin library

template<class Abel=LLI> class UnionFind {
private:
    inline void assert_initialized() {
        assert(size > 0);
    }
    Abel diff_to_root(LLI x) {
        assert_initialized();
        find(x); // connect directly to root
        return diff_to_parent[x];
    }
    std::vector<LLI> rank;
    std::vector<Abel> diff_to_parent;
    Abel UNIT;
public:
    std::vector<LLI> parent;
    size_t size = 0;

    void init(const size_t size, const Abel UNIT_ABEL = 0) {
        this->size = size;
        this->UNIT = UNIT_ABEL;
        rank.resize(size, 0);
        diff_to_parent.resize(size, UNIT_ABEL);
        parent.resize(size);
        for(LLI i = 0 ; i < size ; ++i) {
            parent[i] = i;
        }
    }

    LLI find(const LLI x) {
        assert_initialized();
        if(parent[x] == x) {
            return x;
        }
        LLI root = find(parent[x]);
        diff_to_parent[x] = diff_to_parent[x] + diff_to_parent[parent[x]];
        parent[x] = root;
        return root;
    }

    bool is_same(const LLI x, const LLI y) {
        assert_initialized();
        return find(x) == find(y);
    }

    bool unite(const LLI x, const LLI y, const Abel d = 0) { // false if d is invalid
        assert_initialized();

        Abel diff_from_root_x_to_root_y = (d + diff_to_root(x)) - diff_to_root(y);
        LLI root_x = find(x);
        LLI root_y = find(y);

        if (root_x == root_y) return d == diff(x,y); // invalid input of d
        if (rank[root_x] < rank[root_y]) {
            std::swap(root_x,root_y);
            diff_from_root_x_to_root_y = this->UNIT - diff_from_root_x_to_root_y;
        }
        if (rank[root_x] == rank[root_y]) ++rank[root_x];
        parent[root_y] = root_x;
        diff_to_parent[root_y] = diff_from_root_x_to_root_y;
        return true;
    }

    Abel diff(LLI x, LLI y) {
        assert(is_same(x,y));
        return diff_to_root(y) - diff_to_root(x);
    }
};

// end library

int main() {
    std::ios::sync_with_stdio(false);
    UnionFind<LLI> uf;
    LLI N,M;
    std::cin >> N >> M;

    uf.init(N);
    bool ok = true;
    rep(i,M) {
        LLI L,R,D; // L,R: 1-indexed
        std::cin >> L >> R >> D;

        --L; --R; // 0-indexed

        if(!uf.unite(L,R,D)) {
            ok = false;
        }
    }
    std::cout << (ok?"Yes":"No") << std::endl;
    return 0;
}

Measured memory_bytes: 2560