#include <bits/stdc++.h>
using namespace std;
ifstream in("input.txt");
ofstream out("outbad.txt");
constexpr int sz = 1e5 + 1;
constexpr long double EPS = 1e-4;
map<pair<int, int>, int> mem;
unordered_set<int> uv, cr, check;
int n, m;
list<pair<int, int> > adj[sz];
long double ans[sz];
bool bad = 0;
pair<int, int> dat[sz];
bitset<sz> checkedbs;
long double forcedX = 1e9;
inline bool eq(long double a, long double b) { return (abs(a - b) <= EPS); }
void input() {
  cin >> n >> m;
  mem.clear();
  uv.clear();
  check.clear();
  cr.clear();
  bad = 0;
  checkedbs.reset();
  forcedX = 1e9;
  for (int i = 0; i < n; i++) {
    adj[i].clear();
    ans[i] = 0;
    dat[i].first = 0;
    dat[i].second = 0;
  }
  int x, y, c;
  for (int i = 0; i < n; i++) uv.insert(i);
  for (int i = 0; i < m; i++) {
    cin >> x >> y >> c;
    x--;
    y--;
    if (x > y) swap(x, y);
    if (x == y) {
      if (check.find(x) == check.end()) {
        checkedbs[x] = 1;
        check.insert(x);
        ans[x] = (long double)c / 2;
      } else {
        if (!eq(2 * ans[x], c)) bad = 1;
      }
    } else {
      pair<int, int> ppp(x, y);
      if (mem.find(ppp) != mem.end()) {
        if (mem[ppp] != c) bad = 1;
      } else {
        mem.insert(make_pair(ppp, c));
        adj[x].push_back(make_pair(y, c));
        adj[y].push_back(make_pair(x, c));
      }
    }
  }
}
void dfscheck(int src, int prev) {
  uv.erase(src);
  check.erase(src);
  for (auto x : adj[src]) {
    int a = x.first, b = x.second;
    if (checkedbs[a]) {
      if (!eq(ans[a] + ans[src], b)) {
        bad = 1;
        return;
      }
      if (uv.find(a) != uv.end()) dfscheck(a, src);
    } else {
      if (uv.find(a) != uv.end()) {
        ans[a] = b - ans[src];
        dfscheck(a, src);
      } else {
        if (!eq(ans[a] + ans[src], b)) {
          bad = 1;
          return;
        }
      }
    }
  }
}
void dfs(int src, int prev) {
  uv.erase(src);
  cr.insert(src);
  for (auto x : adj[src]) {
    int a = x.first, b = x.second;
    if (uv.find(a) != uv.end()) {
      dat[a].first = -dat[src].first;
      dat[a].second = b - dat[src].second;
      dfs(a, src);
    } else {
      if (dat[a].first == dat[src].first) {
        int rhs = b - (dat[a].second + dat[src].second);
        if (dat[a].first == -1) rhs = (-rhs);
        long double tmp = (long double)rhs / 2;
        if (forcedX >= 1e8)
          forcedX = tmp;
        else if (!eq(forcedX, tmp)) {
          bad = 1;
          return;
        }
      } else {
        if (!eq(dat[a].second + dat[src].second, b)) {
          bad = 1;
          return;
        }
      }
    }
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int t = 1;
  while (t--) {
    input();
    while (!check.empty()) {
      int x = *check.begin();
      dfscheck(x, -1);
    }
    while (!uv.empty()) {
      int x = *uv.begin();
      dat[x].first = 1;
      forcedX = 1e9;
      cr.clear();
      dfs(x, -1);
      if (forcedX >= 1e8) {
        vector<int> vec;
        for (int k : cr) {
          if (dat[k].first == 1)
            vec.push_back(-dat[k].second);
          else
            vec.push_back(dat[k].second);
        }
        sort(vec.begin(), vec.end());
        long double myx = vec[vec.size() / 2];
        for (int k : cr) ans[k] = dat[k].first * myx + dat[k].second;
      } else {
        for (int k : cr) ans[k] = dat[k].first * forcedX + dat[k].second;
      }
    }
    if (bad) {
      cout << "NO" << endl;
    } else {
      cout << "YES" << endl;
      for (int i = 0; i < n - 1; i++)
        cout << fixed << setprecision(12) << ans[i] << " ";
      cout << fixed << setprecision(12) << ans[n - 1] << endl;
    }
  }
  return 0;
}
