#include <vector>
#include <stack>
#include <algorithm>
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
vector<int>graph[100005];
vector<int>rev_graph[100005];
bool visited[100005];
int n, m;
int niza[100005];
int idx;
stack<int>s;
void dfs(int node){
    visited[node]=true;
for(int i=0; i<graph[node].size(); i++){
    int sosed=graph[node][i];
    if (!visited[sosed]){
        dfs(sosed);
    }
}
s.push(node);
}
void rev_dfs(int node){
    visited[node]=true;
    niza[node]=idx;
//    cout << node << " " ;
for(int i=0; i<rev_graph[node].size(); i++){
    int rev_sosed=rev_graph[node][i];
    if(!visited[rev_sosed]){
        rev_dfs(rev_sosed);
    }
}
}
int main()
{

    cin>>m>>n;

    for(int i=0; i<n; i++){
        int a, b;
        cin>>a>>b;
        graph[a].push_back(b);
        rev_graph[b].push_back(a);

    }
    memset(visited, false, sizeof visited);
    for(int i=1; i<=m; i++){
        if(!visited[i]){
            dfs(i);
        }
    }
    int br_kingdoms=0;
    memset(visited, false, sizeof visited);
    while(!s.empty()){
        int node=s.top();
        if(!visited[node]){
            rev_dfs(node);
            idx++;
            br_kingdoms++;
//            cout<<endl;
        }
        s.pop();
        
    }
    cout<<br_kingdoms << endl;
    for(int i=1; i<=m; i++){
        cout<<niza[i] + 1<<" ";
    }
    return 0;
}
