#!/usr/bin/env pypy3

import array
import heapq
import itertools


MIN_X = 0
MAX_X = 10 ** 9


class UnionFind(object):

    def __init__(self, number_of_nodes):
        self.par = list(range(number_of_nodes))
        self.rank = [0] * number_of_nodes

    def root(self, node):
        if self.par[node] == node:
            return node
        else:
            r = self.root(self.par[node])
            self.par[node] = r
            return r

    def in_the_same_set(self, node1, node2):
        return self.root(node1) == self.root(node2)

    def unite(self, node1, node2):
        x = self.root(node1)
        y = self.root(node2)
        if x != y:
            if self.rank[x] < self.rank[y]:
                x, y = y, x
            self.par[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1


class TopologicalSortError(Exception):
    pass


def topological_sort(num_vs, adj_vs):
    """ Performs topological sorting of the given DAG.

    This function computes the lexicographically least
    topological order of the given DAG.

    :param num_vs int: The number of vertices.
    :param adj_vs list: The adjacency list.
    :return: The lexicographically least topological order.
    :rtype: :obj:`array.array`
    :raises TopologicalSortError: if the given graph is not a DAG
    """
    in_deg = array.array("L", (0 for _ in range(num_vs)))
    for dests in adj_vs:
        for dest in dests:
            in_deg[dest] += 1
    sorted_vs = array.array("L")
    pq = []
    for s in range(num_vs):
        if in_deg[s] == 0:
            heapq.heappush(pq, s)
    while pq:
        u = heapq.heappop(pq)
        sorted_vs.append(u)
        for v in adj_vs[u]:
            in_deg[v] -= 1
            if in_deg[v] == 0:
                heapq.heappush(pq, v)
    if all(x == 0 for x in in_deg):
        return sorted_vs
    else:
        raise TopologicalSortError("The graph has a cycle")


def solve(n, adj_vs, dist):
    uf_vs = UnionFind(n)
    try:
        sorted_vs = topological_sort(n, adj_vs)
    except TopologicalSortError:
        return False
    dist.sort(key=lambda p: (sorted_vs[p[0]], sorted_vs[p[1]]))
    xs = [None for _ in range(n)]
    xs[sorted_vs[0]] = 0
    for l, r, d in dist:
        uf_vs.unite(l, r)
        if xs[l] is None:
            xs[l] = 0
        if xs[r] is None:
            xs[r] = xs[l] + d
        else:
            if xs[r] - xs[l] != d:
                return False
    res = itertools.groupby(range(n), key=lambda x: uf_vs.par[x])
    for _, g in res:
        g2 = list(g)
        if max(g2) - min(g2) > (MAX_X - MIN_X):
            return False
    return True


def main():
    n, m = (int(x) for x in input().split())
    adj_vs = [set() for _ in range(n)]
    dist = []
    for _ in range(m):
        l, r, d = (int(x) for x in input().split())
        adj_vs[l - 1].add(r - 1)
        dist.append((l - 1, r - 1, d))
    print("Yes" if solve(n, adj_vs, dist) else "No")


if __name__ == '__main__':
    main()
