Problem:
Score : 400 points

Problem Statement

There are N people standing on the x-axis.
Let the coordinate of Person i be x_i.
For every i, x_i is an integer between 0 and 10^9 (inclusive).
It is possible that more than one person is standing at the same coordinate.

You will given M pieces of information regarding the positions of these people.
The i-th piece of information has the form (L_i, R_i, D_i).
This means that Person R_i is to the right of Person L_i by D_i units of distance, that is, x_{R_i} - x_{L_i} = D_i holds.

It turns out that some of these M pieces of information may be incorrect.
Determine if there exists a set of values (x_1, x_2, ..., x_N) that is consistent with the given pieces of information.

Constraints

1 \leq N \leq 100 000

0 \leq M \leq 200 000

1 \leq L_i, R_i \leq N (1 \leq i \leq M)

0 \leq D_i \leq 10 000 (1 \leq i \leq M)

L_i \neq R_i (1 \leq i \leq M)

If i \neq j, then (L_i, R_i) \neq (L_j, R_j) and (L_i, R_i) \neq (R_j, L_j).

D_i are integers.

Input

Input is given from Standard Input in the following format:

N M
L_1 R_1 D_1
L_2 R_2 D_2
:
L_M R_M D_M

Output

If there exists a set of values (x_1, x_2, ..., x_N) that is consistent with all given pieces of information, print Yes; if it does not exist, print No.

Sample Input 1

3 3
1 2 1
2 3 1
1 3 2

Sample Output 1

Yes

Some possible sets of values (x_1, x_2, x_3) are (0, 1, 2) and (101, 102, 103).

Sample Input 2

3 3
1 2 1
2 3 1
1 3 5

Sample Output 2

No

If the first two pieces of information are correct, x_3 - x_1 = 2 holds, which is contradictory to the last piece of information.

Sample Input 3

4 3
2 1 1
2 3 5
3 4 2

Sample Output 3

Yes

Sample Input 4

10 3
8 7 100
7 9 100
9 8 100

Sample Output 4

No

Sample Input 5

100 0

Sample Output 5

Yes

Solution in C# (Mono 4.6.2.0) (judge verdict: Time Limit Exceeded)

#pragma warning disable

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Numerics;
using System.Collections;

static class MainClass
{
    public static void Main(string[] args)
    {


        var NM = Console.ReadLine().SplittedStringToInt32List();
        var N = NM[0];
        var M = NM[1];
        var dijkstra = new Dijkstra(N,true);
        var edges = new List<Edge>();
        var dictionary = new Dictionary<int, int>();
        for (int i = 0; i < M; i++)
        {
            var LRDs = Console.ReadLine().SplittedStringToInt32List();
            // edges.Add(new Edge(LRDs[0], LRDs[1], LRDs[2]));
            dijkstra.AddPath(LRDs[0], LRDs[1], LRDs[2]);
            if (dictionary.ContainsKey(LRDs[0]))
                dictionary[LRDs[0]]++;
            else
                dictionary.Add(LRDs[0], 1);
        }
        foreach (var item in dictionary)
        {
            dijkstra.GetMinCost(item.Key);
        }
        Console.WriteLine(IsOk ? "Yes" : "No");

        Console.ReadLine(); 
        
    }

    public class Edge
    {
        public int From;
        public int To;
        public int Cost;

        public Edge(int v1, int v2, int v3)
        {
            From = v1;
            To = v2;
            Cost = v3;
        }
    }

    public static bool IsOk = true;

    public class Dijkstra
    {

        public class Edge
        {
            public int To;
            public int Cost;
        }

        private int maxIndex = -1;
        private const int INF = Int32.MaxValue;
        public readonly bool IsConnectedList;
        private int[,] _edgeArray;
        private List<Edge>[] _edges;

        public Dijkstra(int size, bool islist)
        {
            maxIndex = size + 1;

            if (!islist)
            {
                _edgeArray = new int[maxIndex, maxIndex];

                for (int i = 0; i < _edgeArray.GetLength(0); i++)
                {
                    for (int j = 0; j < _edgeArray.GetLength(1); j++)
                    {
                        _edgeArray[i, j] = INF;
                        if (i == j) _edgeArray[i, j] = 0;
                    }
                }
            }else
            {
                _edges = new List<Edge>[maxIndex];
                for (int i = 0; i < maxIndex; i++)
                {
                    _edges[i] = new List<Edge>();
                }
            }
            IsConnectedList = islist;
        
        }

        public void AddPath(int s, int t, int cost)
        {
            if (!IsConnectedList)
                _edgeArray[s, t] = Math.Min(_edgeArray[s, t], cost);
            else
                _edges[s].Add(new Edge() { Cost = cost, To = t });

        }

        public int[] GetMinCost(int s)
        {
            int[] cost = new int[maxIndex];
            for (int i = 0; i < cost.Length; i++) cost[i] = INF;
            cost[s] = 0;

            var priorityQueue = new PriorityQueue<ComparablePair<int, int>>(maxIndex);
            priorityQueue.Push(new ComparablePair<int, int>(0, s));
            if (!IsConnectedList)
            {
                while (priorityQueue.Count > 0)
                {
                    var costDestinationPair = priorityQueue.Pop();
                    if (cost[costDestinationPair.Item2] < costDestinationPair.Item1) continue;

                    for (int i = 0; i < maxIndex; i++)
                    {
                        int newCostToi = _edgeArray[costDestinationPair.Item2, i] == INF ? INF :
                            costDestinationPair.Item1 + _edgeArray[costDestinationPair.Item2, i];
                        if (newCostToi < cost[i])
                        {
                            if (cost[i] != INF)
                            {
                                IsOk = false;
                            }
                            cost[i] = newCostToi;

                            priorityQueue.Push(new ComparablePair<int, int>(newCostToi, i));
                        }
                        else if (newCostToi > cost[i] && newCostToi != INF)
                        {
                            IsOk = false;
                        }
                    }
                }
            }
            else
            {
                while (priorityQueue.Count > 0)
                {
                    var costDestinationPair = priorityQueue.Pop();
                    if (cost[costDestinationPair.Item2] < costDestinationPair.Item1) continue;

                    var ls = _edges[costDestinationPair.Item2];
                    foreach (var item in ls)
                    {
                        var newCostToi = item.Cost + costDestinationPair.Item1;
                        if (newCostToi < cost[item.To])
                        {
                            if (cost[item.To] != INF)
                            {
                                IsOk = false;
                            }
                            cost[item.To] = newCostToi;

                            priorityQueue.Push(new ComparablePair<int, int>(newCostToi, item.To));
                        }
                        else if (newCostToi > cost[item.To] && newCostToi != INF)
                        {
                            IsOk = false;
                        }
                    }
                }
            }
           

            return cost;
        }

        public int GetMinCost(int s, int t)
        {
            return GetMinCost(s)[t];
        }
    }

    public class ComparablePair<T, U> : IComparable, IComparable<ComparablePair<T, U>> where T : IComparable<T>
    {
        public readonly T Item1;
        public readonly U Item2;

        public int CompareTo(object obj)
        {
            ComparablePair<T, U> castedObj = (ComparablePair<T, U>)obj;
            return this.Item1.CompareTo(castedObj.Item1);
        }

        public int CompareTo(ComparablePair<T, U> other)
        {
            return Item1.CompareTo(other.Item1);
        }

        public ComparablePair(T t, U u)
        {
            Item1 = t;
            Item2 = u;
        }
    }


    class PriorityQueue<T> where T : IComparable<T>
    {
        List<T> buffer;

        public PriorityQueue() { buffer = new List<T>(); }
        public PriorityQueue(int capacity) { buffer = new List<T>(capacity); }

        static void PushHeap(List<T> array, T elem)
        {
            int n = array.Count;
            array.Add(elem);

            while (n != 0)
            {
                int i = (n - 1) / 2;
                if (array[n].CompareTo(array[i]) > 0)
                {
                    T tmp = array[n]; array[n] = array[i]; array[i] = tmp;
                }
                n = i;
            }
        }


        static void PopHeap(List<T> array)
        {
            int n = array.Count - 1;
            array[0] = array[n];
            array.RemoveAt(array.Count - 1);

            for (int i = 0, j; (j = 2 * i + 1) < n;)
            {
                if ((j != n - 1) && (array[j].CompareTo(array[j + 1]) < 0))
                    j++;
                if (array[i].CompareTo(array[j]) < 0)
                {
                    T tmp = array[j]; array[j] = array[i]; array[i] = tmp;
                }
                i = j;
            }
        }


        public void Push(T elem)
        {
            PushHeap(this.buffer, elem);
        }


        public T Pop()
        {
            var data = buffer[0];
            PopHeap(buffer);
            return data;
        }

        public int Count
        {
            get { return buffer.Count; }
        }
    }


    
   

    #region ライブラリ
    public static long ToInt64(this string str) => long.Parse(str);
    public static int ToInt32(this string str) => int.Parse(str);
    public static BigInteger ToBigInteger(this string str) => BigInteger.Parse(str);
    public static List<string> SplittedStringToList(this string str) => str.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
    public static List<int> SplittedStringToInt32List(this string str) => str.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(x => int.Parse(x)).ToList();
    public static List<long> SplittedStringToInt64List(this string str) => str.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(x => long.Parse(x)).ToList();
    public static List<BigInteger> SplittedStringToBigInteger(this string str) => str.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(x => BigInteger.Parse(x)).ToList();
    public const int INF = int.MaxValue / 2;
    public const long LONGINF = long.MaxValue / 2;

    public static int Max(params int[] values)
    {
        var maxes = -1;
        for (int i = 0; i < values.Length; i++)
        {
            maxes = Math.Max(values[i], maxes);
        }
        return maxes;
    }

    #endregion
}