#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<string>
#include<map>
#include<list>
#include<queue>
#include<utility>
#include<sstream>
#include<cstdlib>
#include<cctype>
#include<math.h>
#include<set>
#include<stack>
#include<fstream>
#include<numeric>
#include<string>
#include<vector>
#include<iterator>
using namespace std;
#define ll long long
#define ld long double
#define llu unsigned long long
#define inf 99194853094755497
#define pf printf
#define sf scanf
#define sf1(x) scanf("%lld",&x)
#define sf2(x,y) scanf("%lld %lld",&x,&y)
#define sf3(x,y,z) scanf("%lld %lld %lld",&x,&y,&z)
#define pii pair<long long,long long>
#define sq(x) ((x)*(x))
#define MAX 100009
#define pb push_back
#define mem(a,x) memset(a,x,sizeof(a))
#define mod 1000000007
#define PI acos(-1.0)
const double INF = 1e100;
const double EPS = 1e-9;
/*struct debugger
{
    template<typename T> debugger& operator, (const T& v)
    {
        cerr<<v<<" ";
        return *this;
    }
}dbg;
#define deb(args...){dbg, args; cerr<<endl;}*/


template<class T1> void deb(T1 e1)
{
    cout<<e1<<endl;
}
template<class T1,class T2> void deb(T1 e1,T2 e2)
{
    cout<<e1<<" "<<e2<<endl;
}
template<class T1,class T2,class T3> void deb(T1 e1,T2 e2,T3 e3)
{
    cout<<e1<<" "<<e2<<" "<<e3<<endl;
}
template<class T1,class T2,class T3,class T4> void deb(T1 e1,T2 e2,T3 e3,T4 e4)
{
    cout<<e1<<" "<<e2<<" "<<e3<<" "<<e4<<endl;
}
template<class T1,class T2,class T3,class T4,class T5> void deb(T1 e1,T2 e2,T3 e3,T4 e4,T5 e5)
{
    cout<<e1<<" "<<e2<<" "<<e3<<" "<<e4<<" "<<e5<<endl;
}
template<class T1,class T2,class T3,class T4,class T5,class T6> void deb(T1 e1,T2 e2,T3 e3,T4 e4,T5 e5,T6 e6)
{
    cout<<e1<<" "<<e2<<" "<<e3<<" "<<e4<<" "<<e5<<" "<<e6<<endl;
}

template< class T > T gcd(const T a, const T b)
{
    return (b ? gcd<T>(b, a%b) : a);
}
template< class T > T lcm(const T a, const T b)
{
    return (a / gcd<T>(a, b) * b);
}


/*int Set(int N,int pos){return N=N | (1<<pos);}
int reset(int N,int pos){return N= N & ~(1<<pos);}
bool check(int N,int pos){return (bool)(N & (1<<pos));}
int flip(int N,int pos){return N= N ^ (1<<pos);}
int Least_Significant_Bit(int N){return N= N & (-N);}*/
// moves
//int dx[]= {-1,-1,0,0,1,1};
//int dy[]= {-1,0,-1,1,0,1};
//int dx[]= {0,0,1,-1};/*4 side move*/
//int dy[]= {-1,1,0,0};/*4 side move*/
//int dx[]= {1,1,0,-1,-1,-1,0,1};/*8 side move*/
//int dy[]= {0,1,1,1,0,-1,-1,-1};/*8 side move*/
//int dx[]={1,1,2,2,-1,-1,-2,-2};/*night move*/
//int dy[]={2,-2,1,-1,2,-2,1,-1};/*night move*/
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
//ios_base::sync_with_stdio(0); cin.tie(0);
struct node
{
    ll x,y;
    node() {}
    node(ll x,ll y):x(x),y(y) {}
    bool operator < (const node & p) const
    {
        return x<p.x;
    }
};
class Graph
{
    ll V;    // No. of vertices
    list<ll> *adj;    // Pointer to an array containing adjacency lists
    bool isCyclicUtil(ll v, bool visited[], bool *rs);  // used by isCyclic()
public:
    Graph(ll V);   // Constructor
    void addEdge(ll v, ll w);   // to add an edge to graph
    bool isCyclic();    // returns true if there is a cycle in this graph
};

Graph::Graph(ll V)
{
    this->V = V;
    adj = new list<ll>[V];
}

void Graph::addEdge(ll v, ll w)
{
    adj[v].push_back(w); // Add w to v’s list.
}

// This function is a variation of DFSUytil() in https://www.geeksforgeeks.org/archives/18212
bool Graph::isCyclicUtil(ll v, bool visited[], bool *recStack)
{
    if(visited[v] == false)
    {
        // Mark the current node as visited and part of recursion stack
        visited[v] = true;
        recStack[v] = true;

        // Recur for all the vertices adjacent to this vertex
        list<ll>::iterator i;
        for(i = adj[v].begin(); i != adj[v].end(); ++i)
        {
            if ( !visited[*i] && isCyclicUtil(*i, visited, recStack) )
                return true;
            else if (recStack[*i])
                return true;
        }

    }
    recStack[v] = false;  // remove the vertex from recursion stack
    return false;
}

// Returns true if the graph contains a cycle, else false.
// This function is a variation of DFS() in https://www.geeksforgeeks.org/archives/18212
bool Graph::isCyclic()
{
    // Mark all the vertices as not visited and not part of recursion
    // stack
    bool *visited = new bool[V];
    bool *recStack = new bool[V];
    for(int i = 0; i < V; i++)
    {
        visited[i] = false;
        recStack[i] = false;
    }

    // Call the recursive helper function to detect cycle in different
    // DFS trees
    for(ll i = 0; i < V; i++)
        if (isCyclicUtil(i, visited, recStack))
            return true;

    return false;
}
vector<ll>v[100004],cost[100004];
bool ck;
ll val[100002],vis[100002];
void dfs(ll u,ll sum)
{
    //deb(u,sum);
    if(vis[u])
    {
        if(sum!=val[u]) ck=1;
        return;
    }
    vis[u]=1;
    val[u]=sum;
    for(ll i=0; i<v[u].size(); i++)
    {
        ll x=v[u][i];
        dfs(x,sum+cost[u][i]);
    }
}
Graph g(700000);
ll a[100003];
int main()
{
    ll i,j,k,l,x,y,z,t,m,n,l1,l2;
    while(sf2(n,m)==2)
    {
        mem(a,0);
        for(i=1; i<=100000; i++) v[i].clear();
        for(i=1; i<=m; i++)
        {
            sf3(x,y,z);
            v[x].pb(y);
            a[y]++;
            g.addEdge(x,y);
            cost[x].pb(z);
        }
        if(g.isCyclic()){
            deb("No");
            return 0;
        }
        ck=0;
        mem(vis,0);
        for(i=1; i<=n; i++) val[i]=-inf;
        for(i=1; i<=n; i++)
        {
            if(a[i]==0) dfs(i,0);
        }
        if(ck) deb("No");
        else deb("Yes");

    }
    return 0;
}





Measured memory_bytes: 34944