#include <bits/stdc++.h>
#define REP(i,s,e) for(int i=(s); i<(e);i++)
#define rep(i,n) REP(i,0,n)
#define rep1(i,n) REP(i,1,n)
#define repe(i,n) for(auto &&i:n)
#define all(v) (v).begin(),(v).end()
#define decimal fixed<<setprecision(20)
#define fastcin() cin.tie(0);ios::sync_with_stdio(false)
using namespace std;
using LL = long long;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
const int INF = 1e9;
const LL LLINF = 1e16;

template<typename T, T MOD = 1000000007>
struct Mint{
  static constexpr T mod = MOD;
  T v;
  Mint():v(0){}
  Mint(signed v):v(v){}
  Mint(long long t){v=t%MOD; if(v<0) v += MOD;}

  Mint pow(long long k){
    Mint res(1), tmp(v);
    while(k){
      if(k&1)  res *= tmp;
      tmp *= tmp;
      k>>=1;
    }
    return res;
  }

  static Mint add_identity(){return Mint(0);}
  static Mint mul_identity(){return Mint(1);}

  Mint inv(){return pow(MOD- 2);}

  Mint& operator+=(Mint a){v += a.v; if(v>=MOD) v -= MOD; return *this;}
  Mint& operator-=(Mint a){v += MOD - a.v; if(v>=MOD) v-=MOD; return *this;}
  Mint& operator*=(Mint a){v = 1LL * v * a.v%MOD; return *this;}
  Mint& operator/=(Mint a){return (*this) *= a.inv();}

  Mint operator+(Mint a)const{return Mint(v)+=a;}
  Mint operator-(Mint a)const{return Mint(v)-=a;}
  Mint operator*(Mint a)const{return Mint(v)*=a;}
  Mint operator/(Mint a)const{return Mint(v)/=a;}

  Mint operator-()const{return v?Mint(MOD-v):Mint(v);}

  bool operator==(const Mint a)const{return v == a.v;}
  bool operator!=(const Mint a)const{return v != a.v;}
  bool operator <(const Mint a)const{return v < a.v;}
};

template<typename T, T MOD> constexpr T Mint<T, MOD>:: mod;
template<typename T, T MOD>
ostream& operator<<(ostream &os, Mint<T, MOD> m){os<<m.v;return os;}

int main(){
    fastcin();

    int n, m;
    cin >> n >> m;
    const int mod1 = 1000000007;
    const int mod2 = 1000000097;
    using M1 = Mint<int, mod1>;
    using M2 = Mint<int, mod2>;
    using Graph = vector<vector<pair<int, int>>>;
    Graph G1(n), G2(n);
    rep(i, m){
        int a, b, x;
        cin >> a >> b >> x;
        a--; b--;
        G1[a].emplace_back(b, x);
        G2[b].emplace_back(a, x);
    }

    vector<M1> val1(n, 0);
    vector<M2> val2(n, 0);
    vector<int> used(n, 0);
    rep(i, n){
        if(used[i]) continue;
        val1[i] = 1;
        val2[i] = 1;
        stack<int> st;
        st.push(i);
        used[i] = 1;
        while(!st.empty()){
            int u = st.top(); st.pop();
            rep(j, G1[u].size()){
                auto v = G1[u][j];
                if(!used[v.first]){
                    val1[v.first] = val1[u]*M1(v.second);
                    val2[v.first] = val2[u]*M2(v.second);
                    st.push(v.first);
                    used[v.first] = 1;
                }else{
                    if(val1[v.first] != val1[u]*M1(v.second)
                    || val2[v.first] != val2[u]*M2(v.second)){
                        cout << "No" << endl;
                        return 0;
                    }
                }
            }
            rep(j, G2[u].size()){
                auto v = G2[u][j];
                if(!used[v.first]){
                    val1[v.first] = val1[u]*M1(v.second).inv();
                    val2[v.first] = val2[u]*M2(v.second).inv();
                    st.push(v.first);
                    used[v.first] = 1;
                }else{
                    if(val1[v.first] != val1[u]*M1(v.second).inv()
                    || val2[v.first] != val2[u]*M2(v.second).inv()){
                        cout << "No" << endl;
                        return 0;
                    }
                }
            }
        }
    }
    cout << "Yes" << endl;

}


Measured memory_bytes: 14980