#include <bits/stdc++.h>
long double curSum;
using namespace std;
long double dfs(vector<vector<pair<long long, long long>>>& graph,
                vector<long long>& xFactor, vector<long long>& factor,
                long long cur) {
  long double ans;
  for (long long i = 0; i < graph[cur].size(); i++) {
    long long nei = graph[cur][i].first;
    long long curE = graph[cur][i].second;
    if (factor[nei] == (long long)1000000000000000) {
      xFactor[nei] = -xFactor[cur];
      factor[nei] = curE - factor[cur];
      ans = dfs(graph, xFactor, factor, nei);
      if (ans != (long long)1000000000000000) return ans;
    } else {
      long double a1 = -xFactor[cur];
      long double a2 = xFactor[nei];
      long double b1 = curE - factor[cur];
      long double b2 = factor[nei];
      if (a1 == a2 && b1 == b2) {
      } else if (a1 == a2) {
        return -(long long)1000000000000000;
      } else {
        long double x = ((long double)(b1 - b2)) / ((long double)(a2 - a1));
        return x;
      }
    }
  }
  return (long long)1000000000000000;
}
bool fill_part(vector<vector<pair<long long, long long>>>& graph,
               vector<long double>& val, long long cur) {
  curSum += abs(val[cur]);
  for (long long i = 0; i < graph[cur].size(); i++) {
    long long nei = graph[cur][i].first;
    long long curE = graph[cur][i].second;
    long double neiVal = curE - val[cur];
    if (val[nei] != (long long)1000000000000000 && val[nei] != neiVal)
      return false;
    else if (val[nei] == (long long)1000000000000000) {
      val[nei] = neiVal;
      if (fill_part(graph, val, nei) == false) return false;
    }
  }
  return true;
}
bool fill_part2(vector<vector<pair<long long, long long>>>& graph,
                vector<pair<long double, long double>>& val, long long cur,
                long long turn, vector<long long>& inds) {
  curSum += abs(val[cur].first);
  inds.push_back(cur);
  for (long long i = 0; i < graph[cur].size(); i++) {
    long long nei = graph[cur][i].first;
    long long curE = graph[cur][i].second;
    long double neiVal = curE - val[cur].first;
    if (val[nei].first != (long long)1000000000000000 &&
        val[nei].first != neiVal && val[nei].second == turn)
      return false;
    else if (val[nei].second != turn) {
      val[nei].first = neiVal;
      val[nei].second = turn;
      if (fill_part2(graph, val, nei, turn, inds) == false) return false;
    }
  }
  return true;
}
int main() {
  long long n, m;
  cin >> n >> m;
  vector<pair<long double, long double>> vecTry(n, {0, 0});
  long long turn = 0;
  vector<vector<pair<long long, long long>>> graph(n);
  vector<long double> val(n, (long long)1000000000000000);
  while (m--) {
    long long xt, yt, type;
    cin >> xt >> yt >> type;
    xt--, yt--;
    graph[xt].push_back({yt, type});
    graph[yt].push_back({xt, type});
  }
  vector<long long> xFactor(n, (long long)1000000000000000);
  vector<long long> factor(n, (long long)1000000000000000);
  for (long long i = 0; i < n; i++) {
    if (val[i] == (long long)1000000000000000) {
      xFactor[i] = 1;
      factor[i] = 0;
      long double ans = dfs(graph, xFactor, factor, i);
      if (ans == -(long long)1000000000000000) {
        cout << "NO" << endl;
        return 0;
      } else {
        if (ans != (long long)1000000000000000) {
          val[i] = ans;
          bool ok = fill_part(graph, val, i);
          if (!ok) {
            cout << "NO" << endl;
            return 0;
          }
        } else {
          long long low = -(1 << 6);
          long long high = (1 << 6);
          long long jump = 1 << 5;
          long long bestSum = (long long)1000000000000000, bestSumind = -1;
          while (jump > 0) {
            for (long long j = low; j <= high; j += jump) {
              turn++;
              vecTry[i].first = j;
              vecTry[i].second = turn;
              vector<long long> inds;
              curSum = 0;
              bool ok = fill_part2(graph, vecTry, i, turn, inds);
              if (!ok) continue;
              if (curSum < bestSum) {
                bestSum = curSum;
                bestSumind = j;
              }
            }
            low = bestSumind - jump;
            high = bestSumind + jump;
            jump /= 2;
          }
          turn++;
          vecTry[i].first = bestSumind;
          vecTry[i].second = turn;
          vector<long long> inds1;
          curSum = 0;
          fill_part2(graph, vecTry, i, turn, inds1);
          for (long long i = 0; i < inds1.size(); i++) {
            val[inds1[i]] = vecTry[inds1[i]].first;
          }
          turn++;
          vecTry[i].first = bestSumind - 1;
          vecTry[i].second = turn;
          vector<long long> inds2;
          curSum = 0;
          fill_part2(graph, vecTry, i, turn, inds2);
          if (curSum < bestSum) {
            for (long long i = 0; i < inds2.size(); i++) {
              val[inds2[i]] = vecTry[inds2[i]].first;
            }
          }
          turn++;
          vecTry[i].first = bestSumind + 1;
          vecTry[i].second = turn;
          vector<long long> inds3;
          curSum = 0;
          fill_part2(graph, vecTry, i, turn, inds3);
          if (curSum < bestSum) {
            for (long long i = 0; i < inds3.size(); i++) {
              val[inds3[i]] = vecTry[inds3[i]].first;
            }
          }
        }
      }
    }
  }
  cout << "YES" << endl;
  for (long long i = 0; i < n; i++) {
    cout << val[i] << " ";
  }
  cout << endl;
}
