### BUGGY CODE ###


class MakeGraph:
    
    # 隣接行列もしくは隣接リストの初期化
    # node_num：ノード数
    # isMat：隣接行列(True) / 隣接リスト(False)
    def __init__(self, node_num:int, isMat:bool) -> None:
        self.n = node_num
        self.isMat = isMat

        # 隣接行列の初期化
        if self.isMat:
            INF = float("inf")
            self.graph = [[INF for _ in range(self.n)] for _ in range(self.n)]
    
        # 隣接リストの初期化
        else:
            self.graph = [[] for _ in range(self.n)]

    # エッジの追加
    # frm, to：起点ノード, 終点ノード
    # directed:有向(True) / 無向(False)
    def add_edge(self, frm:int, to:int, dist:int, directed=False) -> None:
        if self.isMat:
            if directed:
                self.graph[frm][to] = dist
            else:
                self.graph[frm][to] = dist
                self.graph[to][frm] = dist
        else:
            if directed:
                self.graph[frm].append((dist, to))
            else:
                self.graph[frm].append((dist, to))
                self.graph[to].append((dist, frm))
                
    # 完成したグラフを取り出す
    def get_graph(self) -> list:
        return self.graph


N,M = map(int, input().split())
LRD = []
for _ in range(M):
    LRD.append(tuple(map(int, input().split())))
    
graphMaker = MakeGraph(N,False)

for l,r,d in LRD:
    graphMaker.add_edge(l-1,r-1,d,True)
    graphMaker.add_edge(r-1,l-1,-d,True)
    
graph = graphMaker.get_graph()

INF = 10**10
dist = [-INF]*N

# 座標割り当て(dfs)
for i in range(N):
    stack = [i]
    while len(stack):
        v = stack.pop()

        for cost, nex_node in graph[v]:
            if dist[nex_node] != -INF:
                continue
            dist[nex_node] = dist[v] + cost
            stack.append(nex_node)
                
    else:
        continue

# 矛盾チェック
consistent = True
for l,r,d in LRD:
    if dist[r-1]-dist[l-1] != d:
        print("No")
        consistent = False
        break
    
if consistent:
    print("Yes")



### FIXED CODE ###

class UnionFind:
    __slots__ = ["nodes", "weight"]
    
    def __init__(self, n: int) -> None:
        self.nodes = [-1]*n
        self.weight = [0]*n
        
    def get_root(self, x:int) -> int:
        if x<0:
            raise ValueError("Negative Index")
        
        if self.nodes[x]<0:
            return x
        else:
            parent, self.nodes[x] = self.nodes[x], self.get_root(self.nodes[x])
            self.weight[x] += self.weight[parent]
            return self.nodes[x]

    def unite(self, x:int, y:int) -> None:
        if x<0 or y<0:
            raise ValueError("Negative Index")
            
        root_x, root_y = self.get_root(x), self.get_root(y)
        if root_x != root_y:
            if self.nodes[root_x] < self.nodes[root_y]:
                bigroot, smallroot = root_x, root_y
            else:
                bigroot, smallroot = root_y, root_x
                
            self.nodes[bigroot] += self.nodes[smallroot]
            self.nodes[smallroot] = bigroot

    def relate(self, smaller:int, bigger:int, diff_weight:int) -> None:
        if smaller<0 or bigger<0:
            raise ValueError("Negative Index")
            
        s_root, b_root = self.get_root(smaller), self.get_root(bigger)
        if s_root == b_root:
            if self.weight[smaller] + diff_weight == self.weight[bigger]:
                return
            raise ValueError
            
        else:
            self.weight[b_root] = diff_weight - self.weight[bigger]
            self.nodes[s_root] += self.nodes[b_root]
            self.nodes[b_root] = smaller
            
   
         
N,M = map(int, input().split())
LRD = []
for _ in range(M):
    LRD.append(tuple(map(int, input().split())))
 
uf = UnionFind(N)
relate = uf.relate    

try:
    for l,r,d in LRD:
        relate(l-1,r-1,d)
    print("Yes")
except Exception as e:
    print("No")