// Mivik 2021.4.14
#include <cstdio>
#include <cstring>
#include <iostream>

#define d isdigit(c)
#define g c=t.get();
#define L return
#define K break
#define A(c,a,b)if(c)a else b;
#define I(c,a)if(c)a;
#define Y goto E
struct MI{private:char bb[1 << 14];FILE*f;char*bs,*be;char e;bool o,l;public:MI():f(stdin),bs(0),be(0){}
#ifdef __linux__
#endif
inline char get(){if(o){o=0;L e;}
#ifdef MIVIK
char c=fgetc(f);I(c==-1,l=1)L c;
#else
I(bs==be,be=(bs=bb)+fread(bb,1,sizeof(bb),f))I(bs==be,{l=1;L-1;})L*bs++;
#endif
}inline void unget(char c){o=1;e=c;}template<class T>inline T read(){T r;*this>r;L r;}template<class T>inline MI&operator>(T&);};template<class T>struct Q{const static bool U=T(-1)>=T(0);inline void operator()(MI&t,T&r)const{r=0;char c;bool y=0;A(U,for(;;){g I(c==-1,Y)I(d,K)},for(;;){g I(c==-1,Y)A(c=='-',{g I(d,{y=1;K;})},I(d,K))})for(;;){I(c==-1,Y)A(d,r=r*10+(c^48);,K)g}t.unget(c);E:;I(y,r=-r)}};template<>struct Q<char>{};template<class T>inline MI&MI::operator>(T&t){Q<T>()(*this,t);L*this;}
#undef d
#undef g
#undef L
#undef K
#undef A
#undef I
#undef Y
template<class T>std::ostream& operator<(std::ostream&out,const T&t){return out<<t;}
#define endl ('\n')
#define P(x) cout<#x" = "<(x)<endl
#define R (cin.read<int>())

using std::cout;

#include <climits>
#include <climits>
#include <vector>
#include <cmath>

MI cin;

const int $n = 205;
const int $m = 2005;

template<typename T> inline bool gmin(T &a, const T &b) { return b < a && (a = b, true); }
template<typename T> inline bool gmax(T &a, const T &b) { return a < b && (a = b, true); }

int n, m, f[$n][$n];
std::vector<int> outs[$n];
bool vis[$n], col[$n];
bool dfs(int x) {
	vis[x] = 1;
	for (int v : outs[x]) {
		if (vis[v]) {
			if (col[v] == col[x]) return 1;
		} else {
			col[v] = col[x] ^ 1;
			if (dfs(v)) return 1;
		}
	}
	return 0;
}
int main() {
	cin > n > m;
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= n; ++j)
			if (i != j) f[i][j] = 0x3f3f3f3f;
	for (int i = 0; i < m; ++i) {
		const int x = R, y = R;
		outs[x].push_back(y);
		outs[y].push_back(x);
		f[x][y] = 1;
		f[y][x] = R ? -1 : 1;
	}
	for (int i = 1; i <= n; ++i)
		if (!vis[i] && dfs(i)) return cout < "NO\n", 0;
	for (int k = 1; k <= n; ++k)
		for (int i = 1; i <= n; ++i) {
			for (int j = 1; j <= n; ++j) gmin(f[i][j], f[i][k] + f[k][j]);
			if (f[i][i] < 0) return cout < "NO\n", 0;
		}
	int mx = -1, ptr;
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= n; ++j)
			if (gmax(mx, f[i][j])) ptr = i;
	cout < "YES\n";
	cout < mx < endl;
	for (int i = 1; i <= n; ++i) cout < f[ptr][i] < " \n"[i == n];
}