### BUGGY CODE ###

#coding:utf-8
from collections import defaultdict
from Queue import Queue
import sys
N,M=map(int,sys.stdin.readline().split())
L=[];R=[];D=[]
C=defaultdict(list)
done=[False]*200001
for i in xrange(M):
    l,r,d=map(int,sys.stdin.readline().split())
    L.append(l);R.append(r);D.append(d)
    C[l].append(i);C[r].append(i)
if M==0:
    print("Yes")
    sys.exit(0)
X=[None]*200001
X[l]=0
Q=Queue()
for c in C[l]:
    Q.put(c)
    done[c]=True
while True:        
    while not Q.empty():
        q=Q.get()
        #print(q)
        l=L[q];r=R[q];d=D[q]
        ll=rr=False
        if X[l]!=None:
            if X[r] is None:
                rr=True
                X[r]=X[l]+d
            else:
                if X[r]!=X[l]+d: 
                    print("No")
                    sys.exit(0)
        elif X[r]!=None:
            if X[l] is None:
                ll=True
                X[l]=X[r]-d
            else:
                if X[r]!=X[l]+d:
                    print("No")
                    sys.exit(0)
        else:
            sys.exit(1)
        if ll:            
            for c in C[l]:
                if not done[c]:
                    Q.put(c); done[c]=True
        if rr:
            for c in C[r]:
                if not done[c]:
                    Q.put(c); done[c]=True
        #print(X[:11])
    
    for i in range(M):
        if done[i] is not None and not done[i]:
            for c in C[i]:
                Q.put(c);done[c]=True
            break
    else:
        break 


print("Yes")            




   



### FIXED CODE ###

#coding:utf-8
from collections import defaultdict
from Queue import Queue
import sys
N,M=map(int,sys.stdin.readline().split())
L=[None]*200001
R=[None]*200001
D=[None]*200001
C=defaultdict(list)
done=[False]*200001
if M==0:
    print("Yes")
    sys.exit(0)

class UnionFind(object):
    #https://www.kumilog.net/entry/union-find
    def __init__(self, n=1):
        self.par = [i for i in range(n)]
        self.rank = [0 for _ in range(n)]
        self.size = [1 for _ in range(n)]

    def find(self, x):
        """
        x が属するグループを探索
        """
        if self.par[x] == x:
            return x
        else:
            self.par[x] = self.find(self.par[x])
            return self.par[x]

    def union(self, x, y):
        """
        x と y のグループを結合
        """
        x = self.find(x)
        y = self.find(y)
        if x != y:
            if self.rank[x] < self.rank[y]:
                x, y = y, x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1
            self.par[y] = x
            self.size[x] += self.size[y]

    def is_same(self, x, y):
        """
        x と y が同じグループか否か
        """
        return self.find(x) == self.find(y)

    def get_size(self, x):
        """
        x が属するグループの要素数
        """
        x = self.find(x)
        return self.size[x]

uf=UnionFind(n=N+1)
for i in xrange(M):
    l,r,d=map(int,sys.stdin.readline().split())
    L[i]=l
    R[i]=r
    D[i]=d
    C[l].append(i);C[r].append(i)
    uf.union(l,r)
groups={}
for i in range(1,N+1):
    groups[uf.find(i)]=i

X=[None]*200001
for group in groups:
    Q=Queue()
    X[group]=0
    for c in C[group]:
        Q.put(c)
        done[c]=True
    while not Q.empty():
        q=Q.get()
        #print(q)
        l=L[q];r=R[q];d=D[q]
        ll=rr=False
        if X[l]!=None:
            if X[r] is None:
                rr=True
                X[r]=X[l]+d
            else:
                if X[r]!=X[l]+d: 
                    print("No")
                    sys.exit(0)
        elif X[r]!=None:
            if X[l] is None:
                ll=True
                X[l]=X[r]-d
            else:
                if X[r]!=X[l]+d:
                    print("No")
                    sys.exit(0)
        else:
            sys.exit(1)
        if ll:            
            for c in C[l]:
                if not done[c]:
                    Q.put(c); done[c]=True
        if rr:
            for c in C[r]:
                if not done[c]:
                    Q.put(c); done[c]=True
        #print(X[:11])




print("Yes")