//   ,  You scared my horse. -.-
//_,,)\.~,,._
//(()`  ``)\))),,_
// |     \ ''((\)))),,_          ____
// |6`   |   ''((\())) "-.____.-"    `-.-,
// |    .'\    ''))))'                  \)))
// |   |   `.     ''                     ((((
// \, _)     \/                          |))))
//  `'        |                          (((((
//            \                  |       ))))))
//             `|    |           ,\     /((((((
//              |   / `-.______.<  \   |  )))))
//              |   |  /         `. \  \  ((((
//              |  / \ |           `.\  | (((
//              \  | | |             )| |  ))
//               | | | |             || |  '
#include <bits/stdc++.h>
#ifndef ONLINE_JUDGE
#define debug(x) cout << #x << ": " << x << endl
#else
#define debug(x)
#endif
using namespace std;
typedef long long ll;
const int maxn=1e3+7,inf=0x3f3f3f3f,mod=1e9+7;

int n,m,k;
struct Edge
{
    int from, to, dist;
    Edge(int u, int v, int d):from(u),to(v),dist(d) {}
};
vector<Edge> edges;
vector<int> G[maxn];
void init(int n)
{
    for(int i = 0; i < n; i++) G[i].clear();
    edges.clear();
}
void AddEdge(int from, int to, int dist)
{
    edges.push_back(Edge(from, to, dist));
    m = edges.size();
    G[from].push_back(m-1);
}

///O(nm)
bool inq[maxn];
int d[maxn],cnt[maxn];///上一条弧 路径经过边数

bool bellman_ford(int s)
{
    queue<int> Q;
    memset(inq, 0, sizeof(inq));
    memset(cnt, 0, sizeof(cnt));
    for(int i = 0; i <maxn; i++) d[i] = inf;
    d[s] = 0;
    inq[s] = true;
    Q.push(s);
    while(!Q.empty())
    {
        int u = Q.front(); Q.pop();
        inq[u] = false;
        for(int i = 0; i < G[u].size(); i++)
        {
            Edge& e = edges[G[u][i]];
            if(d[e.to] > d[u] + e.dist)
            {
                d[e.to] = d[u] + e.dist;
                if(!inq[e.to])
                {
                    Q.push(e.to);
                    cnt[e.to]=cnt[u]+1;
                    if(cnt[e.to] > n+1) return false;//负环
                    inq[e.to] = true;
                }
            }
        }
    }
    return true;

}

int col[maxn];
bool ok;
void dfs(int u,int c)
{
    col[u]=c;
    for(int i=0;i<G[u].size();++i)
    {
        int v=edges[G[u][i]].to;
        if(col[v]!=-1)
        {
            if(col[v]==col[u])
            {
                ok=0;
                return;
            }
        }
        else dfs(v,c^1);
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>k;
    ok=1;
    for(int i=0,u,v,b;i<k;++i)
    {
        cin>>u>>v>>b;
        AddEdge(u,v,1);
        AddEdge(v,u,b?-1:1);
    }
    memset(col,-1,sizeof(col));
    dfs(1,0);
    if(!ok) cout<<"NO\n";
    else
    {
        int mx=-1,st=-1;
        for(int i=1;i<=n;++i)
        {
            if(bellman_ford(i))
            {
                int tmp=0,yes=1;
                for(int j=1;j<=n;++j)
                {
                    if(d[j]<0) {yes=0;break;}
                    tmp=max(tmp,d[j]);
                }
                if(yes && tmp>mx) mx=tmp,st=i;
            }
        }
        if(st==-1) cout<<"NO\n";
        else
        {
            cout<<"YES\n";
            cout<<mx<<'\n';
            bellman_ford(st);
            for(int i=1;i<=n;++i) cout<<d[i]<<' ';
            cout<<'\n';
        }
    }
    return 0;
}
