You are given a connected undirected graph consisting of nn vertices and mm edges. There are no self-loops or multiple edges in the given graph.

You have to direct its edges in such a way that the obtained directed graph does not contain any paths of length two or greater (where the length of path is denoted as the number of traversed edges).

Input

The first line contains two integer numbers nn and mm (2n21052≤n≤2⋅105, n1m2105n−1≤m≤2⋅105) — the number of vertices and edges, respectively.

The following mm lines contain edges: edge ii is given as a pair of vertices uiui, vivi (1ui,vin1≤ui,vi≤n, uiviui≠vi). There are no multiple edges in the given graph, i. e. for each pair (ui,viui,vi) there are no other pairs (ui,viui,vi) and (vi,uivi,ui) in the list of edges. It is also guaranteed that the given graph is connected (there is a path between any pair of vertex in the given graph).

Output

If it is impossible to direct edges of the given graph in such a way that the obtained directed graph does not contain paths of length at least two, print "NO" in the first line.

Otherwise print "YES" in the first line, and then print any suitable orientation of edges: a binary string (the string consisting only of '0' and '1') of length mm. The ii-th element of this string should be '0' if the ii-th edge of the graph should be directed from uiui to vivi, and '1' otherwise. Edges are numbered in the order they are given in the input.

Example

Input
6 5
1 5
2 1
1 4
3 1
6 1
Output
YES
10100

Note

The picture corresponding to the first example: 

And one of possible answers: 

 

题意:

给定一个无向图,让其把边变成一个有向边,边的方向可以你自己定,but要求最后的图中任何一个路径的长度不能大于等于2。

通过分析我们可以发现,要满足图中的任意一个路径的长度不大于等于2的话,那么对于任意一个节点i,如果它在一个边中做起点,那么就不能在另一个边中做终点。显然一个节点在它连接的所有的边中,只能做起点或者终点。

还有一个结论就是,我们如果找到一个满足题意条件的情况,我们把所有的边的方向反转,一定也满足。

我们把一个点作为起点or终点用颜色来表示,例如用蓝色和红色来表示,那么就是任意一个边相连接的两个节点,节点不能为同一种颜色。

这就是很裸的dfs然双颜色的问题啦。

细节见accode

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define rt return
#define dll(x) scanf("%I64d",&x)
#define xll(x) printf("%I64d\n",x)
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define db(x) cout<<"== [ "<<x<<" ] =="<<endl;
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
inline void getInt(int* p);
const int maxn=300010;
const int inf=0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
std::vector<pii> v[maxn];// to id
int col[maxn];
int vis[maxn];
int n,m;
int isok=1;
void dfs(int x)
{
    if(!isok)
    {
        return ;
    }
    int num=col[x];
    if(num==0)
    {
        num=1;
        col[x]=1;// zuo起点的
    }
    for(auto temp :v[x])
    {
        if(vis[temp.se]==0)
        {
            vis[temp.se]=1;
            int tn=col[temp.fi];
            if(tn!=0)
            {
                if(tn==num)
                {
                    isok=0;
                    return ;
                }else
                {
                    if(num==1)
                    {
                        col[temp.fi]=2;
                        dfs(temp.fi);
                    }else
                    {
                        col[temp.fi]=1;
                        dfs(temp.fi);
                    }
                }
            }else
            {
                if(num==1)
                    {
                        col[temp.fi]=2;
                        dfs(temp.fi);
                    }else
                    {
                        col[temp.fi]=1;
                        dfs(temp.fi);
                    }
            }
        }
    }
}
int aa[maxn];
int bb[maxn];
int main()
{
    //freopen("D:\\common_text\\code_stream\\in.txt","r",stdin);
    //freopen("D:\\common_text\\code_stream\\out.txt","w",stdout);
    gbtb;
    cin>>n>>m;
    int a,b;
    repd(i,1,m)
    {
        cin>>a>>b;
        v[a].pb(mp(b,i));
        v[b].pb(mp(a,i));
        aa[i]=a;
        bb[i]=b;
    }
    repd(i,1,n)
    {
        dfs(i);
    }
//    repd(i,1,n)
//    {
//        db(col[i]);
//    }
    if(!isok)
    {
        cout<<"NO"<<endl;
        return 0;
    }
    cout<<"YES"<<endl;
    repd(i,1,m)
    {
        if(col[aa[i]]==1)
        {
            cout<<1;
        }else
        {
            cout<<0;
        }
    }
    cout<<endl;

    return 0;
}

inline void getInt(int* p) {
    char ch;
    do {
        ch = getchar();
    } while (ch == ' ' || ch == '\n');
    if (ch == '-') {
        *p = -(getchar() - '0');
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 - ch + '0';
        }
    }
    else {
        *p = ch - '0';
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 + ch - '0';
        }
    }
}