#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<ll, ll > pll;
typedef vector<pll > vpll;
typedef vector<ll> vll;
//========================================================================================================//
#define rep(i,a,b) for(i=a;i<b;i++)
#define repr(i,a,b) for(i=a;i>=b;i--)
//========================================================================================================//
#define lb lower_bound
#define ub upper_bound
#define F first
#define S second
#define pb push_back
#define mp make_pair
#define popb  pop_back
#define mem(a,b) memset(a,b,sizeof(a))
#define sz size()
#define M 1000000007
#define PI 3.14159265

class Graph {
    int V; // No. of vertices'

    // Pointer to an array containing adjacency lisr
    list<int>* adj;

public:
    Graph(int V); // Constructor

    // function to add an edge to graph
    void addEdge(int u, int v);

    // Returns true if there is a cycle in the graph
    // else false.
    bool isCycle();
};

Graph::Graph(int V)
{
    this->V = V;
    adj = new list<int>[V];
}

void Graph::addEdge(int u, int v)
{
    adj[u].push_back(v);
}

// This function returns true if there is a cycle
// in directed graph, else returns false.
bool Graph::isCycle()
{
    // Create a vector to store indegrees of all
    // vertices. Initialize all indegrees as 0.
    vector<int> in_degree(V, 0);

    // Traverse adjacency lists to fill indegrees of
    // vertices. This step takes O(V+E) time
    for (int u = 0; u < V; u++) {
        for (auto v : adj[u])
            in_degree[v]++;
    }

    // Create an queue and enqueue all vertices with
    // indegree 0
    queue<int> q;
    for (int i = 0; i < V; i++)
        if (in_degree[i] == 0)
            q.push(i);

    // Initialize count of visited vertices
    int cnt = 0;

    // Create a vector to store result (A topological
    // ordering of the vertices)
    vector<int> top_order;

    // One by one dequeue vertices from queue and enqueue
    // adjacents if indegree of adjacent becomes 0
    while (!q.empty()) {

        // Extract front of queue (or perform dequeue)
        // and add it to topological order
        int u = q.front();
        q.pop();
        top_order.push_back(u);

        // Iterate through all its neighbouring nodes
        // of dequeued node u and decrease their in-degree
        // by 1
        list<int>::iterator itr;
        for (itr = adj[u].begin(); itr != adj[u].end(); itr++)

            // If in-degree becomes zero, add it to queue
            if (--in_degree[*itr] == 0)
                q.push(*itr);

        cnt++;
    }

    // Check if there was a cycle
    if (cnt != V)
        return true;
    else
        return false;
}

// Driver program to test above functions
int main()
{
    // Create a graph given in the above diagram
    int n,m,i;
    cin>>n>>m;

    Graph g(n);
    vector<vector<int>> eg(5001);
    vector<pair<int,int>> vp;
    rep(i,0,m)
    {
        int x,y;
        cin>>x>>y;
        x--;
        y--;
       // cin>>x>>y;
        g.addEdge(x,y);
        eg[x].push_back(y);
        vp.push_back(make_pair(x,y));

    }
    map<pair<int,int>,int> mpp;
    if (g.isCycle())
    {
        bool vis[n];
        rep(i,0,n)
            vis[i]=false;
        int ar[n],j;

        rep(j,0,n)
        {

            if(vis[j])
                continue;
            ar[j]=1;
            queue<int> q;
            q.push(j);
            int co=0;

            while(!q.empty())
            {
                int x=q.front();
                q.pop();
        //cout<<x<<endl;
                if(vis[x])
                    continue;
                vis[x]=true;
                rep(i,0,eg[x].size())
                {
                    int y=eg[x][i];
                    ar[y]=(ar[x]+1)%2;
                    if(ar[y]==0)
                        ar[y]=2;
                    q.push(ar[y]);
                }
            }

        }
                cout<<2<<endl;
        rep(i,0,vp.size())
            cout<<ar[vp[i].F]<<" ";
    }
    else
    {
        cout<<1<<" ";
        rep(i,0,m)
            cout<<1<<" ";
    }
    return 0;
}


//Sani buyuk Osman Pasa Plevneden cikmam diyor.
//FatihSultanMehmedHan
//Abdulhamid Han
//Bismillahirrahmanirrahim
//█▀█─█──█──█▀█─█─█
//█▄█─█──█──█▄█─█▄█
//█─█─█▄─█▄─█─█─█─█

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>

using namespace std;

typedef long long lo;
typedef pair< lo,lo > PII;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define FOR for(int i=1;i<=n;i++)
#define mid ((start+end)/2)
#define ort ((bas+son)/2)

const lo MAX = -1000000000000000000;
const lo MIN = 1000000000000000000;
const lo inf = 1000000000;
const lo KOK = 100000;
const lo LOG = 30;
const lo li = 5005;
const lo mod = 1000000007;

int n,m,b[li],a[li],k,flag,t,vis[li],par[li],renk[li],x[li],y[li];
int cev;
string s;
vector<PII> v[li];
vector<PII> vv;

inline void dfs(int node,int der){
	//~ cev=0;
	if(vis[node]==1){return ;}
	cev++;
	vis[node]=1;
	//~ cev=der;
	for(int i=0;i<(int)v[node].size();i++){
		int go=v[node][i].fi;
		int ind=v[node][i].se;
		//~ if(renk[ind]==0)
			renk[ind]=der+1;
		//~ cev++;
		//~ cev=cev%2;
		dfs(go,!der);
	}
}

inline void dfs1(int node,int ind){
	//~ cout<<node<<" ()()() "<<" ()()() "<<ind<<vis[node]<<endl;
	if(vis[ind]==1 && ind==node){flag=1;return ;}
	if(flag==1)return ;
	if(vis[node]==1)return ;
	vis[node]=1;
	for(int i=0;i<(int)v[node].size();i++){
		dfs1(v[node][i].fi,ind);
	}
}

int main(void){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d %d",&x[i],&y[i]);
		v[x[i]].pb(mp(y[i],i));
		//~ v[y].pb(mp(x,i));
	}
	FOR{
		dfs1(i,i);
		memset(vis,0,sizeof(vis));
	}
	if(flag==0){
		printf("1\n");
		for(int i=1;i<=m;i++) printf("1 ");
		return 0;
	}
	FOR{
		cev=0;
		dfs(i,0);
		vv.pb(mp(cev,i));
		memset(vis,0,sizeof(vis));
	}
	sort(vv.begin(),vv.end());
	reverse(vv.begin(),vv.end());
	FOR{
		if(vis[vv[i-1].se]==0)dfs(vv[i-1].se,0);
	}
	printf("2\n");
	for(int i=1;i<=m;i++){
		printf("%d ",renk[i]);
	}
	return 0;
}


//Sani buyuk Osman Pasa Plevneden cikmam diyor.
//FatihSultanMehmedHan
//Abdulhamid Han
//Bismillahirrahmanirrahim
//█▀█─█──█──█▀█─█─█
//█▄█─█──█──█▄█─█▄█
//█─█─█▄─█▄─█─█─█─█

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>

using namespace std;

typedef long long lo;
typedef pair< lo,lo > PII;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define FOR for(int i=1;i<=n;i++)
#define mid ((start+end)/2)
#define ort ((bas+son)/2)

const lo MAX = -1000000000000000000;
const lo MIN = 1000000000000000000;
const lo inf = 1000000000;
const lo KOK = 100000;
const lo LOG = 30;
const lo li = 5005;
const lo mod = 1000000007;

int n,m,b[li],a[li],k,flag,t,x,y,vis[li],par[li],renk[li];
int cev;
string s;
vector<PII> v[li];
vector<int> vvv;

inline void dfs(int node){
	cev=0;
	if(vis[node]==1){return ;}
	vis[node]=1;
	for(int i=0;i<(int)v[node].size();i++){
		int go=v[node][i].fi;
		int ind=v[node][i].se;
		if(renk[ind]==0){
			renk[ind]=cev+1;
			cev++;
			cev=cev%2;
		}
		dfs(go);
	}
}

inline void dfs1(int node,int ind){
	//~ cout<<node<<" ()()() "<<" ()()() "<<ind<<vis[node]<<endl;
	if(vis[ind]==1 && ind==node){flag=1;return ;}
	if(flag==1)return ;
	if(vis[node]==1)return ;
	vis[node]=1;
	for(int i=0;i<(int)v[node].size();i++){
		dfs1(v[node][i].fi,ind);
	}
}

int main(void){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d %d",&x,&y);
		v[x].pb(mp(y,i));
	}
	FOR{
		dfs1(i,i);
		memset(vis,0,sizeof(vis));
	}
	if(flag==0){
		printf("1\n");
		for(int i=1;i<=m;i++) printf("1 ");
		return 0;
	}
	FOR{
		if(vis[i]==0)dfs(i);
	}
	printf("2\n");
	for(int i=1;i<=m;i++){
		printf("%d ",renk[i]);
	}
	return 0;
}


//Sani buyuk Osman Pasa Plevneden cikmam diyor.
//FatihSultanMehmedHan
//Abdulhamid Han
//Bismillahirrahmanirrahim
//█▀█─█──█──█▀█─█─█
//█▄█─█──█──█▄█─█▄█
//█─█─█▄─█▄─█─█─█─█

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>

using namespace std;

typedef long long lo;
typedef pair< lo,lo > PII;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define FOR for(int i=1;i<=n;i++)
#define mid ((start+end)/2)
#define ort ((bas+son)/2)

const lo MAX = -1000000000000000000;
const lo MIN = 1000000000000000000;
const lo inf = 1000000000;
const lo KOK = 100000;
const lo LOG = 30;
const lo li = 5005;
const lo mod = 1000000007;

int n,m,b[li],a[li],k,flag,t,vis[li],par[li],renk[li],x[li],y[li];
int cev;
string s;
vector<PII> v[li];
vector<PII> vv;

inline void dfs(int node,int der){
	//~ cev=0;
	if(vis[node]==1){return ;}
	cev++;
	vis[node]=1;
	//~ cev=der;
	for(int i=0;i<(int)v[node].size();i++){
		int go=v[node][i].fi;
		int ind=v[node][i].se;
		//~ if(renk[ind]==0)
			renk[ind]=der+1;
		//~ cev++;
		//~ cev=cev%2;
		dfs(go,!der);
	}
}

inline void dfs1(int node,int ind){
	//~ cout<<node<<" ()()() "<<" ()()() "<<ind<<vis[node]<<endl;
	if(vis[ind]==1 && ind==node){flag=1;return ;}
	//~ if(flag==1)return ;
	if(vis[node]==1)return ;
	vis[node]=1;
	for(int i=0;i<(int)v[node].size();i++){
		if(v[node][i].fi==ind){renk[v[node][i].se]=1;flag=1;}
		if(renk[v[node][i].se]==1)continue;
		dfs1(v[node][i].fi,ind);
	}
}

int main(void){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d %d",&x[i],&y[i]);
		v[x[i]].pb(mp(y[i],i));
		//~ v[y].pb(mp(x,i));
	}
	FOR{
		dfs1(i,i);
		memset(vis,0,sizeof(vis));
	}
	if(flag==0){
		printf("1\n");
		for(int i=1;i<=m;i++) printf("1 ");
		return 0;
	}
	FOR{
		cev=0;
		//~ dfs(i,0);
		//~ vv.pb(mp(cev,i));
		//~ memset(vis,0,sizeof(vis));
	}
	sort(vv.begin(),vv.end());
	reverse(vv.begin(),vv.end());
	FOR{
		//~ cout<<vv[i].se<<endl;
		//~ dfs(vv[i-1].se,0);
	}
	printf("2\n");
	for(int i=1;i<=m;i++){
		printf("%d ",renk[i]+1);
	}
	return 0;
}


//Sani buyuk Osman Pasa Plevneden cikmam diyor.
//FatihSultanMehmedHan
//Abdulhamid Han
//Bismillahirrahmanirrahim
//█▀█─█──█──█▀█─█─█
//█▄█─█──█──█▄█─█▄█
//█─█─█▄─█▄─█─█─█─█

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>

using namespace std;

typedef long long lo;
typedef pair< lo,lo > PII;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define FOR for(int i=1;i<=n;i++)
#define mid ((start+end)/2)
#define ort ((bas+son)/2)

const lo MAX = -1000000000000000000;
const lo MIN = 1000000000000000000;
const lo inf = 1000000000;
const lo KOK = 100000;
const lo LOG = 30;
const lo li = 5005;
const lo mod = 1000000007;

int n,m,b[li],a[li],k,flag,t,x,y,vis[li],par[li],renk[li];
int cev;
string s;
vector<PII> v[li];
vector<int> vvv;

inline void dfs(int node,int der){
	//~ cev=0;
	if(vis[node]==1){return ;}
	vis[node]=1;
	//~ cev=der;
	for(int i=0;i<(int)v[node].size();i++){
		int go=v[node][i].fi;
		int ind=v[node][i].se;
		if(renk[ind]!=0){printf("-1\n");exit(0);}
		renk[ind]=der+1;
		//~ cev++;
		//~ cev=cev%2;
		dfs(go,!der);
	}
}

inline void dfs1(int node,int ind){
	//~ cout<<node<<" ()()() "<<" ()()() "<<ind<<vis[node]<<endl;
	if(vis[ind]==1 && ind==node){flag=1;return ;}
	if(flag==1)return ;
	if(vis[node]==1)return ;
	vis[node]=1;
	for(int i=0;i<(int)v[node].size();i++){
		dfs1(v[node][i].fi,ind);
	}
}

int main(void){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d %d",&x,&y);
		v[x].pb(mp(y,i));
	}
	FOR{
		dfs1(i,i);
		memset(vis,0,sizeof(vis));
	}
	if(flag==0){
		printf("1\n");
		for(int i=1;i<=m;i++) printf("1 ");
		return 0;
	}
	FOR{
		if(vis[i]==0)dfs(i,0);
	}
	printf("2\n");
	for(int i=1;i<=m;i++){
		printf("%d ",renk[i]);
	}
	return 0;
}


//Sani buyuk Osman Pasa Plevneden cikmam diyor.
//FatihSultanMehmedHan
//Abdulhamid Han
//Bismillahirrahmanirrahim
//█▀█─█──█──█▀█─█─█
//█▄█─█──█──█▄█─█▄█
//█─█─█▄─█▄─█─█─█─█

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>

using namespace std;

typedef long long lo;
typedef pair< lo,lo > PII;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define FOR for(int i=1;i<=n;i++)
#define mid ((start+end)/2)
#define ort ((bas+son)/2)

const lo MAX = -1000000000000000000;
const lo MIN = 1000000000000000000;
const lo inf = 1000000000;
const lo KOK = 100000;
const lo LOG = 30;
const lo li = 5005;
const lo mod = 1000000007;

int n,m,b[li],a[li],k,flag,t,vis[li],par[li],renk[li],x[li],y[li];
int cev;
string s;
vector<PII> v[li];
vector<int> vvv;

inline void dfs(int node,int der){
	//~ cev=0;
	if(vis[node]==1){return ;}
	vis[node]=1;
	//~ cev=der;
	for(int i=0;i<(int)v[node].size();i++){
		int go=v[node][i].fi;
		int ind=v[node][i].se;
		renk[ind]=der+1;
		//~ cev++;
		//~ cev=cev%2;
		dfs(go,!der);
	}
}

inline void dfs1(int node,int ind){
	//~ cout<<node<<" ()()() "<<" ()()() "<<ind<<vis[node]<<endl;
	if(vis[ind]==1 && ind==node){flag=1;return ;}
	if(flag==1)return ;
	if(vis[node]==1)return ;
	vis[node]=1;
	for(int i=0;i<(int)v[node].size();i++){
		dfs1(v[node][i].fi,ind);
	}
}

int main(void){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d %d",&x[i],&y[i]);
		v[x[i]].pb(mp(y[i],i));
		//~ v[y].pb(mp(x,i));
	}
	FOR{
		dfs1(i,i);
		memset(vis,0,sizeof(vis));
	}
	if(flag==0){
		printf("1\n");
		for(int i=1;i<=m;i++) printf("1 ");
		return 0;
	}
	FOR{
		if(vis[i]==0)dfs(i,0);
	}
	for(int i=1;i<=m;i++){
		v[y[i]].pb(mp(x[i],i));
	}
	printf("2\n");
	for(int i=1;i<=m;i++){
		printf("%d ",renk[i]);
	}
	return 0;
}


//Sani buyuk Osman Pasa Plevneden cikmam diyor.
//FatihSultanMehmedHan
//Abdulhamid Han
//Bismillahirrahmanirrahim
//█▀█─█──█──█▀█─█─█
//█▄█─█──█──█▄█─█▄█
//█─█─█▄─█▄─█─█─█─█

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>

using namespace std;

typedef long long lo;
typedef pair< lo,lo > PII;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define FOR for(int i=1;i<=n;i++)
#define mid ((start+end)/2)
#define ort ((bas+son)/2)

const lo MAX = -1000000000000000000;
const lo MIN = 1000000000000000000;
const lo inf = 1000000000;
const lo KOK = 100000;
const lo LOG = 30;
const lo li = 5005;
const lo mod = 1000000007;

int n,m,b[li],a[li],k,flag,t,x,y,vis[li],par[li],renk[li];
int cev;
string s;
vector<PII> v[li];
vector<int> vvv;

inline void dfs(int node){
	if(vis[node]==1){return ;}
	vis[node]=1;
	for(int i=0;i<(int)v[node].size();i++){
		int go=v[node][i].fi;
		int ind=v[node][i].se;
		renk[ind]=cev+1;
		cev++;
		cev=cev%2;
		dfs(go);
	}
}

inline void dfs1(int node,int ind){
	//~ cout<<node<<" ()()() "<<" ()()() "<<ind<<vis[node]<<endl;
	if(vis[ind]==1 && ind==node){flag=1;return ;}
	if(flag==1)return ;
	if(vis[node]==1)return ;
	vis[node]=1;
	for(int i=0;i<(int)v[node].size();i++){
		dfs1(v[node][i].fi,ind);
	}
}

int main(void){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d %d",&x,&y);
		v[x].pb(mp(y,i));
	}
	FOR{
		dfs1(i,i);
		memset(vis,0,sizeof(vis));
	}
	if(flag==0){
		printf("1\n");
		for(int i=1;i<=m;i++) printf("1 ");
		return 0;
	}
	FOR{
		if(vis[i]==0)dfs(i);
	}
	printf("2\n");
	for(int i=1;i<=m;i++){
		printf("%d ",renk[i]);
	}
	return 0;
}


//Sani buyuk Osman Pasa Plevneden cikmam diyor.
//FatihSultanMehmedHan
//Abdulhamid Han
//Bismillahirrahmanirrahim
//█▀█─█──█──█▀█─█─█
//█▄█─█──█──█▄█─█▄█
//█─█─█▄─█▄─█─█─█─█

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>

using namespace std;

typedef long long lo;
typedef pair< lo,lo > PII;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define FOR for(int i=1;i<=n;i++)
#define mid ((start+end)/2)
#define ort ((bas+son)/2)

const lo MAX = -1000000000000000000;
const lo MIN = 1000000000000000000;
const lo inf = 1000000000;
const lo KOK = 100000;
const lo LOG = 30;
const lo li = 5005;
const lo mod = 1000000007;

int n,m,b[li],a[li],k,flag,t,vis[li],par[li],renk[li],x[li],y[li];
int cev;
string s;
vector<PII> v[li];

inline void dfs1(int node,int ind){
	if(vis[node]==1)return ;
	vis[node]=1;
	for(int i=0;i<(int)v[node].size();i++){
		if(v[node][i].fi==ind){renk[v[node][i].se]=1;flag=1;}
		if(renk[v[node][i].se]==1)continue;
		dfs1(v[node][i].fi,ind);
	}
}

int main(void){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d %d",&x[i],&y[i]);
		v[x[i]].pb(mp(y[i],i));
	}
	FOR{
		dfs1(i,i);
		memset(vis,0,sizeof(vis));
	}
	if(flag==0){
		printf("1\n");
		for(int i=1;i<=m;i++) printf("1 ");
		return 0;
	}
	printf("2\n");
	for(int i=1;i<=m;i++){
		printf("%d ",renk[i]+1);
	}
	return 0;
}


//Sani buyuk Osman Pasa Plevneden cikmam diyor.
//FatihSultanMehmedHan
//Abdulhamid Han
//Bismillahirrahmanirrahim
//█▀█─█──█──█▀█─█─█
//█▄█─█──█──█▄█─█▄█
//█─█─█▄─█▄─█─█─█─█

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>

using namespace std;

typedef long long lo;
typedef pair< lo,lo > PII;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define FOR for(int i=1;i<=n;i++)
#define mid ((start+end)/2)
#define ort ((bas+son)/2)

const lo MAX = -1000000000000000000;
const lo MIN = 1000000000000000000;
const lo inf = 1000000000;
const lo KOK = 100000;
const lo LOG = 30;
const lo li = 5005;
const lo mod = 1000000007;

int n,m,b[li],a[li],k,flag,t,vis[li],par[li],renk[li],x[li],y[li];
int cev;
string s;
vector<PII> v[li];
vector<int> vvv;

inline void dfs(int node,int der){
	//~ cev=0;
	if(vis[node]==1){return ;}
	vis[node]=1;
	//~ cev=der;
	for(int i=0;i<(int)v[node].size();i++){
		int go=v[node][i].fi;
		int ind=v[node][i].se;
		renk[ind]=der+1;
		//~ cev++;
		//~ cev=cev%2;
		dfs(go,!der);
	}
}

inline void dfs1(int node,int ind){
	//~ cout<<node<<" ()()() "<<" ()()() "<<ind<<vis[node]<<endl;
	if(vis[ind]==1 && ind==node){flag=1;return ;}
	if(flag==1)return ;
	if(vis[node]==1)return ;
	vis[node]=1;
	for(int i=0;i<(int)v[node].size();i++){
		dfs1(v[node][i].fi,ind);
	}
}

int main(void){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d %d",&x[i],&y[i]);
		v[x[i]].pb(mp(y[i],i));
		//~ v[y].pb(mp(x,i));
	}
	FOR{
		dfs1(i,i);
		memset(vis,0,sizeof(vis));
	}
	if(flag==0){
		printf("1\n");
		for(int i=1;i<=m;i++) printf("1 ");
		return 0;
	}
	for(int i=1;i<=m;i++){
		v[y[i]].pb(mp(x[i],i));
	}
	FOR{
		if(vis[i]==0)dfs(i,0);
	}

	printf("2\n");
	for(int i=1;i<=m;i++){
		printf("%d ",renk[i]);
	}
	return 0;
}


//Sani buyuk Osman Pasa Plevneden cikmam diyor.
//FatihSultanMehmedHan
//Abdulhamid Han
//Bismillahirrahmanirrahim
//█▀█─█──█──█▀█─█─█
//█▄█─█──█──█▄█─█▄█
//█─█─█▄─█▄─█─█─█─█

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>

using namespace std;

typedef long long lo;
typedef pair< lo,lo > PII;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define FOR for(int i=1;i<=n;i++)
#define mid ((start+end)/2)
#define ort ((bas+son)/2)

const lo MAX = -1000000000000000000;
const lo MIN = 1000000000000000000;
const lo inf = 1000000000;
const lo KOK = 100000;
const lo LOG = 30;
const lo li = 5005;
const lo mod = 1000000007;

int n,m,b[li],a[li],k,flag,t,x,y,vis[li],par[li],renk[li];
int cev;
string s;
vector<PII> v[li];
vector<int> vvv;

inline void dfs(int node,int der){
	if(vis[node]==1){return ;}
	vis[node]=1;
	for(int i=0;i<(int)v[node].size();i++){
		int go=v[node][i].fi;
		int ind=v[node][i].se;
		renk[ind]=der+1;
		dfs(go,(der+1)%2);
	}
}

inline void dfs1(int node,int ind){
	//~ cout<<node<<" ()()() "<<" ()()() "<<ind<<vis[node]<<endl;
	if(vis[ind]==1 && ind==node){flag=1;return ;}
	if(flag==1)return ;
	if(vis[node]==1)return ;
	vis[node]=1;
	for(int i=0;i<(int)v[node].size();i++){
		dfs1(v[node][i].fi,ind);
	}
}

int main(void){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d %d",&x,&y);
		v[x].pb(mp(y,i));
	}
	FOR{
		dfs1(i,i);
		memset(vis,0,sizeof(vis));
	}
	if(flag==0){
		printf("1\n");
		for(int i=1;i<=m;i++) printf("1 ");
		return 0;
	}
	FOR{
		if(vis[i]==0)dfs(i,0);
	}
	printf("2\n");
	for(int i=1;i<=m;i++){
		printf("%d ",renk[i]);
	}
	return 0;
}


//Sani buyuk Osman Pasa Plevneden cikmam diyor.
//FatihSultanMehmedHan
//Abdulhamid Han
//Bismillahirrahmanirrahim
//█▀█─█──█──█▀█─█─█
//█▄█─█──█──█▄█─█▄█
//█─█─█▄─█▄─█─█─█─█

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>

using namespace std;

typedef long long lo;
typedef pair< lo,lo > PII;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define FOR for(int i=1;i<=n;i++)
#define mid ((start+end)/2)
#define ort ((bas+son)/2)

const lo MAX = -1000000000000000000;
const lo MIN = 1000000000000000000;
const lo inf = 1000000000;
const lo KOK = 100000;
const lo LOG = 30;
const lo li = 5005;
const lo mod = 1000000007;

int n,m,b[li],a[li],k,flag,t,x,y,vis[li],par[li],renk[li];
int cev;
string s;
vector<PII> v[li];
vector<int> vvv;

inline void dfs(int node){
	if(vis[node]==1){return ;}
	vis[node]=1;
	for(int i=0;i<(int)v[node].size();i++){
		int go=v[node][i].fi;
		int ind=v[node][i].se;
		if(renk[ind]==0){
			renk[ind]=cev+1;
			cev++;
			cev=cev%2;
		}
		dfs(go);
	}
}

inline void dfs1(int node,int ind){
	//~ cout<<node<<" ()()() "<<" ()()() "<<ind<<vis[node]<<endl;
	if(vis[ind]==1 && ind==node){flag=1;return ;}
	if(flag==1)return ;
	if(vis[node]==1)return ;
	vis[node]=1;
	for(int i=0;i<(int)v[node].size();i++){
		dfs1(v[node][i].fi,ind);
	}
}

int main(void){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d %d",&x,&y);
		v[x].pb(mp(y,i));
	}
	FOR{
		dfs1(i,i);
		memset(vis,0,sizeof(vis));
	}
	if(flag==0){
		printf("1\n");
		for(int i=1;i<=m;i++) printf("1 ");
		return 0;
	}
	FOR{
		if(vis[i]==0)dfs(i);
	}
	printf("2\n");
	for(int i=1;i<=m;i++){
		printf("%d ",renk[i]);
	}
	return 0;
}


//Sani buyuk Osman Pasa Plevneden cikmam diyor.
//FatihSultanMehmedHan
//Abdulhamid Han
//Bismillahirrahmanirrahim
//█▀█─█──█──█▀█─█─█
//█▄█─█──█──█▄█─█▄█
//█─█─█▄─█▄─█─█─█─█

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>

using namespace std;

typedef long long lo;
typedef pair< lo,lo > PII;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define FOR for(int i=1;i<=n;i++)
#define mid ((start+end)/2)
#define ort ((bas+son)/2)

const lo MAX = -1000000000000000000;
const lo MIN = 1000000000000000000;
const lo inf = 1000000000;
const lo KOK = 100000;
const lo LOG = 30;
const lo li = 5005;
const lo mod = 1000000007;

int n,m,b[li],a[li],k,flag,t,vis[li],par[li],renk[li],x[li],y[li];
int cev;
string s;
vector<PII> v[li];
vector<PII> vv;

inline void dfs(int node,int der){
	//~ cev=0;
	if(vis[node]==1){return ;}
	cev++;
	vis[node]=1;
	//~ cev=der;
	for(int i=0;i<(int)v[node].size();i++){
		int go=v[node][i].fi;
		int ind=v[node][i].se;
		//~ if(renk[ind]==0)
			renk[ind]=der+1;
		//~ cev++;
		//~ cev=cev%2;
		dfs(go,!der);
	}
}

inline void dfs1(int node,int ind){
	//~ cout<<node<<" ()()() "<<" ()()() "<<ind<<vis[node]<<endl;
	if(vis[ind]==1 && ind==node){flag=1;return ;}
	if(flag==1)return ;
	if(vis[node]==1)return ;
	vis[node]=1;
	for(int i=0;i<(int)v[node].size();i++){
		dfs1(v[node][i].fi,ind);
	}
}

int main(void){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d %d",&x[i],&y[i]);
		v[x[i]].pb(mp(y[i],i));
		//~ v[y].pb(mp(x,i));
	}
	FOR{
		dfs1(i,i);
		memset(vis,0,sizeof(vis));
	}
	if(flag==0){
		printf("1\n");
		for(int i=1;i<=m;i++) printf("1 ");
		return 0;
	}
	FOR{
		cev=0;
		dfs(i,0);
		vv.pb(mp(cev,i));
		memset(vis,0,sizeof(vis));
	}
	sort(vv.begin(),vv.end());
	reverse(vv.begin(),vv.end());
	FOR{
		//~ cout<<vv[i].se<<endl;
		dfs(vv[i-1].se,0);
	}
	printf("2\n");
	for(int i=1;i<=m;i++){
		printf("%d ",renk[i]);
	}
	return 0;
}


//Sani buyuk Osman Pasa Plevneden cikmam diyor.
//FatihSultanMehmedHan
//Abdulhamid Han
//Bismillahirrahmanirrahim
//█▀█─█──█──█▀█─█─█
//█▄█─█──█──█▄█─█▄█
//█─█─█▄─█▄─█─█─█─█

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>

using namespace std;

typedef long long lo;
typedef pair< lo,lo > PII;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define FOR for(int i=1;i<=n;i++)
#define mid ((start+end)/2)
#define ort ((bas+son)/2)

const lo MAX = -1000000000000000000;
const lo MIN = 1000000000000000000;
const lo inf = 1000000000;
const lo KOK = 100000;
const lo LOG = 30;
const lo li = 5005;
const lo mod = 1000000007;

int n,m,b[li],a[li],k,flag,t,vis[li],par[li],renk[li],x[li],y[li];
int cev;
string s;
vector<PII> v[li];
vector<int> vvv;

inline void dfs(int node,int der){
	//~ cev=0;
	if(vis[node]==1){return ;}
	vis[node]=1;
	//~ cev=der;
	for(int i=0;i<(int)v[node].size();i++){
		int go=v[node][i].fi;
		int ind=v[node][i].se;
		if(renk[ind]==0)
			renk[ind]=der+1;
		//~ cev++;
		//~ cev=cev%2;
		dfs(go,!der);
	}
}

inline void dfs1(int node,int ind){
	//~ cout<<node<<" ()()() "<<" ()()() "<<ind<<vis[node]<<endl;
	if(vis[ind]==1 && ind==node){flag=1;return ;}
	if(flag==1)return ;
	if(vis[node]==1)return ;
	vis[node]=1;
	for(int i=0;i<(int)v[node].size();i++){
		dfs1(v[node][i].fi,ind);
	}
}

int main(void){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d %d",&x[i],&y[i]);
		v[x[i]].pb(mp(y[i],i));
		//~ v[y].pb(mp(x,i));
	}
	FOR{
		dfs1(i,i);
		memset(vis,0,sizeof(vis));
	}
	if(flag==0){
		printf("1\n");
		for(int i=1;i<=m;i++) printf("1 ");
		return 0;
	}
	for(int i=1;i<=m;i++){
		v[y[i]].pb(mp(x[i],i));
	}
	FOR{
		if(vis[i]==0)dfs(i,0);
	}

	printf("2\n");
	for(int i=1;i<=m;i++){
		printf("%d ",renk[i]);
	}
	return 0;
}


//Sani buyuk Osman Pasa Plevneden cikmam diyor.
//FatihSultanMehmedHan
//Abdulhamid Han
//Bismillahirrahmanirrahim
//█▀█─█──█──█▀█─█─█
//█▄█─█──█──█▄█─█▄█
//█─█─█▄─█▄─█─█─█─█

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>

using namespace std;

typedef long long lo;
typedef pair< lo,lo > PII;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define FOR for(int i=1;i<=n;i++)
#define mid ((start+end)/2)
#define ort ((bas+son)/2)

const lo MAX = -1000000000000000000;
const lo MIN = 1000000000000000000;
const lo inf = 1000000000;
const lo KOK = 100000;
const lo LOG = 30;
const lo li = 5005;
const lo mod = 1000000007;

int n,m,b[li],a[li],k,flag,t,vis[li],par[li],renk[li],x[li],y[li];
int cev;
string s;
vector<PII> v[li];
vector<PII> vv;

inline void dfs(int node,int der){
	//~ cev=0;
	if(vis[node]==1){return ;}
	cev++;
	vis[node]=1;
	//~ cev=der;
	for(int i=0;i<(int)v[node].size();i++){
		int go=v[node][i].fi;
		int ind=v[node][i].se;
		//~ if(renk[ind]==0)
			renk[ind]=der+1;
		//~ cev++;
		//~ cev=cev%2;
		dfs(go,!der);
	}
}

inline void dfs1(int node,int ind){
	//~ cout<<node<<" ()()() "<<" ()()() "<<ind<<vis[node]<<endl;
	if(vis[ind]==1 && ind==node){flag=1;return ;}
	if(flag==1)return ;
	if(vis[node]==1)return ;
	vis[node]=1;
	for(int i=0;i<(int)v[node].size();i++){
		dfs1(v[node][i].fi,ind);
	}
}

int main(void){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d %d",&x[i],&y[i]);
		v[x[i]].pb(mp(y[i],i));
		//~ v[y].pb(mp(x,i));
	}
	FOR{
		dfs1(i,i);
		memset(vis,0,sizeof(vis));
	}
	if(flag==0){
		printf("1\n");
		for(int i=1;i<=m;i++) printf("1 ");
		return 0;
	}
	FOR{
		cev=0;
		dfs(i,0);
		vv.pb(mp(cev,i));
		memset(vis,0,sizeof(vis));
	}
	sort(vv.begin(),vv.end());
	reverse(vv.begin(),vv.end());
	FOR{
		if(vis[vv[i-1].se]==0)dfs(vv[i].se,0);
	}
	printf("2\n");
	for(int i=1;i<=m;i++){
		printf("%d ",renk[i]);
	}
	return 0;
}


//Sani buyuk Osman Pasa Plevneden cikmam diyor.
//FatihSultanMehmedHan
//Abdulhamid Han
//Bismillahirrahmanirrahim
//█▀█─█──█──█▀█─█─█
//█▄█─█──█──█▄█─█▄█
//█─█─█▄─█▄─█─█─█─█

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>

using namespace std;

typedef long long lo;
typedef pair< lo,lo > PII;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define FOR for(int i=1;i<=n;i++)
#define mid ((start+end)/2)
#define ort ((bas+son)/2)

const lo MAX = -1000000000000000000;
const lo MIN = 1000000000000000000;
const lo inf = 1000000000;
const lo KOK = 100000;
const lo LOG = 30;
const lo li = 5005;
const lo mod = 1000000007;

int n,m,b[li],a[li],k,flag,t,vis[li],par[li],renk[li],x[li],y[li];
int cev;
string s;
vector<PII> v[li];
vector<PII> vv;

inline void dfs(int node,int der){
	//~ cev=0;
	if(vis[node]==1){return ;}
	cev++;
	vis[node]=1;
	//~ cev=der;
	for(int i=0;i<(int)v[node].size();i++){
		int go=v[node][i].fi;
		int ind=v[node][i].se;
		//~ if(renk[ind]==0)
			renk[ind]=der+1;
		//~ cev++;
		//~ cev=cev%2;
		dfs(go,!der);
	}
}

inline void dfs1(int node,int ind){
	//~ cout<<node<<" ()()() "<<" ()()() "<<ind<<vis[node]<<endl;
	if(vis[ind]==1 && ind==node){flag=1;return ;}
	if(flag==1)return ;
	if(vis[node]==1)return ;
	vis[node]=1;
	for(int i=0;i<(int)v[node].size();i++){
		dfs1(v[node][i].fi,ind);
	}
}

int main(void){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d %d",&x[i],&y[i]);
		v[x[i]].pb(mp(y[i],i));
		//~ v[y].pb(mp(x,i));
	}
	FOR{
		dfs1(i,i);
		memset(vis,0,sizeof(vis));
	}
	if(flag==0){
		printf("1\n");
		for(int i=1;i<=m;i++) printf("1 ");
		return 0;
	}
	FOR{
		cev=0;
		dfs(i,0);
		vv.pb(mp(cev,i));
		memset(vis,0,sizeof(vis));
	}
	sort(vv.begin(),vv.end());
	reverse(vv.begin(),vv.end());
	FOR{
		if(vis[vv[i].se]==0)dfs(vv[i].se,0);
	}
	printf("2\n");
	for(int i=1;i<=m;i++){
		printf("%d ",renk[i]);
	}
	return 0;
}


//Sani buyuk Osman Pasa Plevneden cikmam diyor.
//FatihSultanMehmedHan
//Abdulhamid Han
//Bismillahirrahmanirrahim
//█▀█─█──█──█▀█─█─█
//█▄█─█──█──█▄█─█▄█
//█─█─█▄─█▄─█─█─█─█

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>

using namespace std;

typedef long long lo;
typedef pair< lo,lo > PII;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define FOR for(int i=1;i<=n;i++)
#define mid ((start+end)/2)
#define ort ((bas+son)/2)

const lo MAX = -1000000000000000000;
const lo MIN = 1000000000000000000;
const lo inf = 1000000000;
const lo KOK = 100000;
const lo LOG = 30;
const lo li = 5005;
const lo mod = 1000000007;

int n,m,b[li],a[li],k,flag,t,x,y,vis[li],par[li],renk[li];
int cev;
string s;
vector<PII> v[li];
vector<int> vvv;

inline void dfs(int node,int der){
	//~ cev=0;
	if(vis[node]==1){return ;}
	vis[node]=1;
	cev=der;
	for(int i=0;i<(int)v[node].size();i++){
		int go=v[node][i].fi;
		int ind=v[node][i].se;
		renk[ind]=cev+1;
		cev++;
		cev=cev%2;
		dfs(go,cev);
	}
}

inline void dfs1(int node,int ind){
	//~ cout<<node<<" ()()() "<<" ()()() "<<ind<<vis[node]<<endl;
	if(vis[ind]==1 && ind==node){flag=1;return ;}
	if(flag==1)return ;
	if(vis[node]==1)return ;
	vis[node]=1;
	for(int i=0;i<(int)v[node].size();i++){
		dfs1(v[node][i].fi,ind);
	}
}

int main(void){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d %d",&x,&y);
		v[x].pb(mp(y,i));
	}
	FOR{
		dfs1(i,i);
		memset(vis,0,sizeof(vis));
	}
	if(flag==0){
		printf("1\n");
		for(int i=1;i<=m;i++) printf("1 ");
		return 0;
	}
	FOR{
		if(vis[i]==0)dfs(i,0);
	}
	printf("2\n");
	for(int i=1;i<=m;i++){
		printf("%d ",renk[i]);
	}
	return 0;
}


//Sani buyuk Osman Pasa Plevneden cikmam diyor.
//FatihSultanMehmedHan
//Abdulhamid Han
//Bismillahirrahmanirrahim
//█▀█─█──█──█▀█─█─█
//█▄█─█──█──█▄█─█▄█
//█─█─█▄─█▄─█─█─█─█

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>

using namespace std;

typedef long long lo;
typedef pair< lo,lo > PII;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define FOR for(int i=1;i<=n;i++)
#define mid ((start+end)/2)
#define ort ((bas+son)/2)

const lo MAX = -1000000000000000000;
const lo MIN = 1000000000000000000;
const lo inf = 1000000000;
const lo KOK = 100000;
const lo LOG = 30;
const lo li = 500005;
const lo mod = 1000000007;

int n,m,b[li],a[li],k,flag,t,x,y,vis[li],par[li],renk[li];
int cev;
string s;
vector<PII> v[li];
vector<int> vvv;

inline void dfs(int node,int der){
	if(vis[node]==1){flag=1;return ;}
	vis[node]=1;
	for(int i=0;i<(int)v[node].size();i++){
		int go=v[node][i].fi;
		int ind=v[node][i].se;
		renk[ind]=der+1;
		dfs(go,(der+1)%2);
	}
	vis[node]=0;
}

int main(void){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d %d",&x,&y);
		v[x].pb(mp(y,i));
	}
	FOR{
		if(vis[i]==0)dfs(i,0);
	}
	if(flag==0){
		printf("1\n");
		for(int i=1;i<=m;i++) printf("1 ");
		return 0;
	}
	printf("2\n");
	for(int i=1;i<=m;i++){
		printf("%d ",renk[i]);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define forn(i,a,b) for(int i = a; i < b; i++)
typedef long long ll;

bool cy = 0;

void cycle(vector<int> v[], bool vis[], int i, set<int> &s, map<pair<int,int>, int> &mp, int p = -1) {
    vis[i] = true;
    s.insert(i);
    for(auto vv : v[i]) {
        if(vv == p) continue;
        if(vis[vv] && s.find(vv) != s.end()) {
            cy=1;
            mp[{i,vv}] = 2;
        }
        else if(s.find(vv) != s.end()) {
            cy=1;
            mp[{i,vv}] = 2;
        }
        if(!vis[vv]) cycle(v, vis, vv, s, mp, i);
    }
    s.erase(i);
    return;
}

void dfs(vector<int> v[], bool vis[], int i, map<pair<int,int>, int> &mp, int p = -1, bool o = 0) {
    vis[i] = true;
    for(auto j : v[i]) {
        if(j == p) continue;
        mp[{i,j}] = (int)o+1;
        if(vis[j]) {
            if(mp.find(make_pair(i,j)) == mp.end()) {
                mp[{i,j}] = (int)o+1;
            }
        }
        else dfs(v, vis, j, mp, i, !o);
    }
    return;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int n, m;
    cin >> n >> m;
    vector<int> v[n];
    map<pair<int,int>, int> mp;
    pair<int,int> p[m];
    forn(i,0,m) {
        int u, vv;
        cin >> u >> vv;
        p[i] = {u-1,vv-1};
        u--;
        vv--;
        v[u].pb(vv);
    }
    set<int> s;
    bool vis[n];
    forn(i,0,n) vis[i] = 0;
    forn(i,0,n) {
        if(!vis[i]) {
            cycle(v, vis, i, s, mp);
        }
    }
    cout << 1+cy << endl;
    forn(i,0,m) {
        if(mp.find(p[i]) != mp.end())
        cout << mp[p[i]] << " ";
        else cout << 1 << " ";
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define forn(i,a,b) for(int i = a; i < b; i++)
typedef long long ll;

bool cy = 0;

void cycle(vector<int> v[], bool vis[], int i, set<int> &s, map<pair<int,int>, int> &mp, int p = -1) {
    vis[i] = true;
    s.insert(i);
    for(auto vv : v[i]) {
        if(vv == p) continue;
        if(vis[vv] && s.find(vv) != s.end()) {
            cy=1;
            mp[{i,vv}] = 2;
        }
        else cycle(v, vis, vv, s, mp, i);
    }
    s.erase(i);
    return;
}

void dfs(vector<int> v[], bool vis[], int i, map<pair<int,int>, int> &mp, int p = -1, bool o = 0) {
    vis[i] = true;
    for(auto j : v[i]) {
        if(j == p) continue;
        mp[{i,j}] = (int)o+1;
        if(vis[j]) {
            if(mp.find(make_pair(i,j)) == mp.end()) {
                mp[{i,j}] = (int)o+1;
            }
        }
        else dfs(v, vis, j, mp, i, !o);
    }
    return;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int n, m;
    cin >> n >> m;
    vector<int> v[n];
    map<pair<int,int>, int> mp;
    pair<int,int> p[m];
    forn(i,0,m) {
        int u, vv;
        cin >> u >> vv;
        p[i] = {u-1,vv-1};
        u--;
        vv--;
        v[u].pb(vv);
    }
    set<int> s;
    bool vis[n];
    forn(i,0,n) vis[i] = 0;
    forn(i,0,n) {
        if(!vis[i]) {
            cycle(v, vis, i, s, mp);
        }
    }
    cout << 1+cy << endl;
    forn(i,0,m) {
        if(mp.find(p[i]) != mp.end())
        cout << mp[p[i]] << " ";
        else cout << 1 << " ";
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define forn(i,a,b) for(int i = a; i < b; i++)
typedef long long ll;

bool cy = 0;

void cycle(vector<int> v[], bool vis[], int i, set<int> &s, map<pair<int,int>, int> &mp, int p = -1) {
    vis[i] = true;
    s.insert(i);
    for(auto vv : v[i]) {
        if(vv == p) continue;
        if(s.find(vv) != s.end()) {
            cy=1;
            mp[{i,vv}] = 2;
        }
        if(!vis[vv]) cycle(v, vis, vv, s, mp, i);
    }
    s.erase(i);
    return;
}

void dfs(vector<int> v[], bool vis[], int i, map<pair<int,int>, int> &mp, int p = -1, bool o = 0) {
    vis[i] = true;
    for(auto j : v[i]) {
        if(j == p) continue;
        mp[{i,j}] = (int)o+1;
        if(vis[j]) {
            if(mp.find(make_pair(i,j)) == mp.end()) {
                mp[{i,j}] = (int)o+1;
            }
        }
        else dfs(v, vis, j, mp, i, !o);
    }
    return;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int n, m;
    cin >> n >> m;
    vector<int> v[n];
    map<pair<int,int>, int> mp;
    pair<int,int> p[m];
    forn(i,0,m) {
        int u, vv;
        cin >> u >> vv;
        p[i] = {u-1,vv-1};
        u--;
        vv--;
        v[u].pb(vv);
    }
    set<int> s;
    bool vis[n];
    forn(i,0,n) vis[i] = 0;
    forn(i,0,n) {
        if(!vis[i]) {
            cycle(v, vis, i, s, mp);
        }
    }
    cout << 1+cy << endl;
    forn(i,0,m) {
        if(mp.find(p[i]) != mp.end())
        cout << mp[p[i]] << " ";
        else cout << 1 << " ";
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define forn(i,a,b) for(int i = a; i < b; i++)
typedef long long ll;

bool cy = 0;

void cycle(vector<int> v[], bool vis[], int i, set<int> &s, map<pair<int,int>, int> &mp, int p = -1) {
    vis[i] = true;
    s.insert(i);
    for(auto vv : v[i]) {
        if(s.find(vv) != s.end()) {
            cy=1;
            mp[{i,vv}] = 2;
        }
        if(!vis[vv]) cycle(v, vis, vv, s, mp, i);
    }
    s.erase(i);
    return;
}

void dfs(vector<int> v[], bool vis[], int i, map<pair<int,int>, int> &mp, int p = -1, bool o = 0) {
    vis[i] = true;
    for(auto j : v[i]) {
        if(j == p) continue;
        mp[{i,j}] = (int)o+1;
        if(vis[j]) {
            if(mp.find(make_pair(i,j)) == mp.end()) {
                mp[{i,j}] = (int)o+1;
            }
        }
        else dfs(v, vis, j, mp, i, !o);
    }
    return;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int n, m;
    cin >> n >> m;
    vector<int> v[n];
    map<pair<int,int>, int> mp;
    pair<int,int> p[m];
    forn(i,0,m) {
        int u, vv;
        cin >> u >> vv;
        p[i] = {u-1,vv-1};
        u--;
        vv--;
        v[u].pb(vv);
    }
    set<int> s;
    bool vis[n];
    forn(i,0,n) vis[i] = 0;
    forn(i,0,n) {
        if(!vis[i]) {
            cycle(v, vis, i, s, mp);
        }
    }
    cout << 1+cy << endl;
    forn(i,0,m) {
        if(mp.find(p[i]) != mp.end())
        cout << mp[p[i]] << " ";
        else cout << 1 << " ";
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define forn(i,a,b) for(int i = a; i < b; i++)
typedef long long ll;

bool cy = 0;

void cycle(vector<int> v[], bool vis[], int i, set<int> &s, map<pair<int,int>, int> &mp, int p = -1) {
    vis[i] = true;
    s.insert(i);
    for(auto vv : v[i]) {
        if(vv == p) continue;
        if(vis[vv] && s.find(vv) != s.end()) {
            mp[{i,vv}] = 2;
        }
        else cycle(v, vis, vv, s, mp, i);
    }
    s.erase(i);
    return;
}

void dfs(vector<int> v[], bool vis[], int i, map<pair<int,int>, int> &mp, int p = -1, bool o = 0) {
    vis[i] = true;
    for(auto j : v[i]) {
        if(j == p) continue;
        mp[{i,j}] = (int)o+1;
        if(vis[j]) {
            if(mp.find(make_pair(i,j)) == mp.end()) {
                mp[{i,j}] = (int)o+1;
            }
        }
        else dfs(v, vis, j, mp, i, !o);
    }
    return;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int n, m;
    cin >> n >> m;
    vector<int> v[n];
    map<pair<int,int>, int> mp;
    pair<int,int> p[m];
    forn(i,0,m) {
        int u, vv;
        cin >> u >> vv;
        p[i] = {u-1,vv-1};
        u--;
        vv--;
        v[u].pb(vv);
    }
    set<int> s;
    bool vis[n];
    forn(i,0,n) vis[i] = 0;
    forn(i,0,n) {
        if(!vis[i]) {
            cycle(v, vis, i, s, mp);
        }
    }
    cout << 1+cy << endl;
    forn(i,0,m) {
        if(mp.find(p[i]) != mp.end())
        cout << mp[p[i]] << " ";
        else cout << 1 << " ";
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define forn(i,a,b) for(int i = a; i < b; i++)
typedef long long ll;

bool cycle(vector<int> v[], bool vis[], int i, set<int> &s, int p = -1) {
    vis[i] = true;
    s.insert(i);
    for(auto vv : v[i]) {
        if(vv == p) continue;
        if(vis[vv] && s.find(vv) != s.end()) {
            return true;
        }
        if(cycle(v, vis, vv, s, i)) return true;
    }
    s.erase(i);
    return false;
}

void dfs(vector<int> v[], bool vis[], int i, map<pair<int,int>, int> &mp, int p = -1, bool o = 0) {
    vis[i] = true;
    for(auto j : v[i]) {
        if(j == p) continue;
        mp[{i,j}] = (int)o+1;
        if(vis[j]) {
            if(mp.find(make_pair(i,j)) == mp.end()) {
                mp[{i,j}] = (int)o+1;
            }
        }
        else dfs(v, vis, j, mp, i, !o);
    }
    return;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int n, m;
    cin >> n >> m;
    vector<int> v[n];
    map<pair<int,int>, int> mp;
    pair<int,int> p[m];
    forn(i,0,m) {
        int u, vv;
        cin >> u >> vv;
        p[i] = {u-1,vv-1};
        u--;
        vv--;
        v[u].pb(vv);
    }
    set<int> s;
    bool vis[n];
    forn(i,0,n) vis[i] = 0;
    bool cy = 0;
    forn(i,0,n) {
        if(!vis[i] && cycle(v, vis, i, s)) {
            cy = 1;
            break;
        }
    }
    forn(i,0,n) vis[i] = 0;
    if(cy) {
        forn(i,0,n) {
            if(!vis[i]) {
                dfs(v, vis, i, mp);
            }
        }
        cout << 2 << endl;
        forn(i,0,m) {
            cout << mp[p[i]] << " ";
        }
    }
    else {
        cout << 1 << endl;
        forn(i,0,m) cout << 1 << " ";
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define forn(i,a,b) for(int i = a; i < b; i++)
typedef long long ll;

bool cy = 0;

void cycle(vector<int> v[], bool vis[], int i, set<int> &s, map<pair<int,int>, int> &mp, int p = -1) {
    vis[i] = true;
    s.insert(i);
    for(auto vv : v[i]) {
        if(s.find(vv) != s.end()) {
            cy=1;
            mp[{i,vv}] = 2;
        }
        else mp[{i,vv}] = 1;
        if(!vis[vv]) cycle(v, vis, vv, s, mp, i);
    }
    s.erase(i);
    return;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int n, m;
    cin >> n >> m;
    vector<int> v[n];
    map<pair<int,int>, int> mp;
    pair<int,int> p[m];
    forn(i,0,m) {
        int u, vv;
        cin >> u >> vv;
        p[i] = {u-1,vv-1};
        u--;
        vv--;
        v[u].pb(vv);
    }
    set<int> s;
    bool vis[n];
    forn(i,0,n) vis[i] = 0;
    forn(i,0,n) {
        if(!vis[i]) {
            cycle(v, vis, i, s, mp);
        }
    }
    cout << 1+cy << endl;
    forn(i,0,m) {
        if(mp.find(p[i]) == mp.end()) {
            cout << "FUCK";
            return 0;
        }
        cout << mp[p[i]] << " ";
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define forn(i,a,b) for(int i = a; i < b; i++)
typedef long long ll;

bool cy = 0;

void cycle(vector<int> v[], bool vis[], int i, set<int> &s, map<pair<int,int>, int> &mp, int p = -1) {
    vis[i] = true;
    s.insert(i);
    for(auto vv : v[i]) {
        if(vv == p) continue;
        if(vis[vv] && s.find(vv) != s.end()) {
            cy=1;
            mp[{i,vv}] = 2;
        }
        if(!vis[vv]) cycle(v, vis, vv, s, mp, i);
    }
    s.erase(i);
    return;
}

void dfs(vector<int> v[], bool vis[], int i, map<pair<int,int>, int> &mp, int p = -1, bool o = 0) {
    vis[i] = true;
    for(auto j : v[i]) {
        if(j == p) continue;
        mp[{i,j}] = (int)o+1;
        if(vis[j]) {
            if(mp.find(make_pair(i,j)) == mp.end()) {
                mp[{i,j}] = (int)o+1;
            }
        }
        else dfs(v, vis, j, mp, i, !o);
    }
    return;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int n, m;
    cin >> n >> m;
    vector<int> v[n];
    map<pair<int,int>, int> mp;
    pair<int,int> p[m];
    forn(i,0,m) {
        int u, vv;
        cin >> u >> vv;
        p[i] = {u-1,vv-1};
        u--;
        vv--;
        v[u].pb(vv);
    }
    set<int> s;
    bool vis[n];
    forn(i,0,n) vis[i] = 0;
    forn(i,0,n) {
        if(!vis[i]) {
            cycle(v, vis, i, s, mp);
        }
    }
    cout << 1+cy << endl;
    forn(i,0,m) {
        if(mp.find(p[i]) != mp.end())
        cout << mp[p[i]] << " ";
        else cout << 1 << " ";
    }
    return 0;
}


#include <bits/stdc++.h>
struct rev_tag {} const rev;
struct iter { int& i; const int dir; };
int& operator *  (iter self) { return self.i; }
void operator ++ (iter self) { self.i += self.dir; }
bool operator != (iter lhs, iter rhs) { return (lhs.i < rhs.i) ^ (lhs.dir < 0); }
struct range {
    const int dir;
    int __begin, __end;
    iter end() { return { __end, dir }; }
    iter begin() { return { __begin, dir }; }
    range(int end): __begin(0), __end(end), dir(1) {}
    range(int end, rev_tag): __begin(--end), __end(0), dir(-1) {}
    range(int begin, int end): __begin(begin), __end(end), dir(1) {}
};

int main() {
    std::ios::sync_with_stdio(false);
    int n, m;
    std::cin >> n >> m;
    std::vector<std::vector<std::pair<int, int>>> G(n);
    for (int i : range(m)) {
        int u, v;
        std::cin >> u >> v;
        G[--u].emplace_back(--v, i);
    }
    std::vector<int> col(m), dfn(n, -1), ins(n), stk(n);
    std::vector<bool> vis(n);
    int dfn_n = 0, stk_n = 0;
    std::function<int(int, int)> tarjan;
    tarjan = [&](int u, int f) -> int {
        int low = dfn[u] = dfn_n++;
        ins[u] = true; stk[stk_n++] = u;
        for (auto [v, idx] : G[u]) {
            if (v == f) f = -1, col[idx] = 2;
            else if (dfn[v] < 0) low = std::min(low, tarjan(v, u)), col[idx] = 1;
            else if (ins[v]) low = std::min(low, dfn[v]), col[idx] = 2;
            else col[idx] = 1;
        }
        if (low == dfn[u]) {
            for (;;) {
                int v = stk[--stk_n];
                ins[v] = false;
                if (v == u) break;
            }
        }
        return dfn[u] = low;
    };
    for (int i : range(n))
        if (dfn[i] == -1) tarjan(i, n);
    std::cout << *std::max_element(col.begin(), col.end()) << "\n";
    for (int i : range(m))
        std::cout << col[i] << " ";
    return 0;
}
/*
4 5
1 2
2 3
2 4
3 4
4 3
*/


#include <bits/stdc++.h>
struct rev_tag {} const rev;
struct iter { int& i; const int dir; };
int& operator *  (iter self) { return self.i; }
void operator ++ (iter self) { self.i += self.dir; }
bool operator != (iter lhs, iter rhs) { return (lhs.i < rhs.i) ^ (lhs.dir < 0); }
struct range {
    const int dir;
    int __begin, __end;
    iter end() { return { __end, dir }; }
    iter begin() { return { __begin, dir }; }
    range(int end): __begin(0), __end(end), dir(1) {}
    range(int end, rev_tag): __begin(--end), __end(0), dir(-1) {}
    range(int begin, int end): __begin(begin), __end(end), dir(1) {}
};

int main() {
    std::ios::sync_with_stdio(false);
    int n, m;
    std::cin >> n >> m;
    std::vector<std::vector<std::pair<int, int>>> G(n);
    for (int i : range(m)) {
        int u, v;
        std::cin >> u >> v;
        G[--u].emplace_back(--v, i);
    }
    std::vector<int> col(m), dfn(n, -1), ins(n), stk(n);
    std::vector<bool> vis(n);
    int dfn_n = 0, stk_n = 0;
    std::function<int(int, int)> tarjan;
    tarjan = [&](int u, int f) -> int {
        int low = dfn[u] = dfn_n++;
        ins[u] = true; stk[stk_n++] = u;
        for (auto [v, idx] : G[u]) {
            if (v == f) f = -1;
            else if (dfn[v] < 0) low = std::min(low, tarjan(v, u)), col[idx] = 1;
            else if (ins[v]) low = std::min(low, dfn[v]), col[idx] = 2;
            else col[idx] = 1;
        }
        if (low == dfn[u]) {
            for (;;) {
                int v = stk[--stk_n];
                ins[v] = false;
                if (v == u) break;
            }
        }
        return dfn[u] = low;
    };
    for (int i : range(n))
        if (dfn[i] == -1) tarjan(i, n);
    std::cout << *std::max_element(col.begin(), col.end()) << "\n";
    for (int i : range(m))
        std::cout << col[i] << " ";
    return 0;
}


#include <bits/stdc++.h>
struct rev_tag {} const rev;
struct iter { int& i; const int dir; };
int& operator *  (iter self) { return self.i; }
void operator ++ (iter self) { self.i += self.dir; }
bool operator != (iter lhs, iter rhs) { return (lhs.i < rhs.i) ^ (lhs.dir < 0); }
struct range {
    const int dir;
    int __begin, __end;
    iter end() { return { __end, dir }; }
    iter begin() { return { __begin, dir }; }
    range(int end): __begin(0), __end(end), dir(1) {}
    range(int end, rev_tag): __begin(--end), __end(0), dir(-1) {}
    range(int begin, int end): __begin(begin), __end(end), dir(1) {}
};

int main() {
    std::ios::sync_with_stdio(false);
    int n, m;
    std::cin >> n >> m;
    std::vector<std::vector<std::pair<int, int>>> G(n);
    for (int i : range(m)) {
        int u, v;
        std::cin >> u >> v;
        G[--u].emplace_back(--v, i);
    }
    std::vector<int> col(m);
    std::vector<bool> vis(n);
    int dfn_n = 0, stk_n = 0;
    std::function<void(int)> dfs = [&](int u) {
        vis[u] = true;
        for (auto [v, i] : G[u]) {
            if (vis[v]) col[i] = 2;
            else col[i] = 1, dfs(v);
        }
    };
    for (int i : range(n))
        if (!vis[i]) dfs(i);
    std::cout << *std::max_element(col.begin(), col.end()) << "\n";
    for (int i : range(m))
        std::cout << col[i] << " ";
    return 0;
}
/*
4 5
1 2
2 3
2 4
3 4
4 3
*/


#include <bits/stdc++.h>
struct rev_tag {} const rev;
struct iter { int& i; const int dir; };
int& operator *  (iter self) { return self.i; }
void operator ++ (iter self) { self.i += self.dir; }
bool operator != (iter lhs, iter rhs) { return (lhs.i < rhs.i) ^ (lhs.dir < 0); }
struct range {
    const int dir;
    int __begin, __end;
    iter end() { return { __end, dir }; }
    iter begin() { return { __begin, dir }; }
    range(int end): __begin(0), __end(end), dir(1) {}
    range(int end, rev_tag): __begin(--end), __end(0), dir(-1) {}
    range(int begin, int end): __begin(begin), __end(end), dir(1) {}
};

int main() {
    std::ios::sync_with_stdio(false);
    int n, m;
    std::cin >> n >> m;
    std::vector<std::vector<std::pair<int, int>>> G(n);
    for (int i : range(m)) {
        int u, v;
        std::cin >> u >> v;
        G[--u].emplace_back(--v, i);
    }
    std::vector<int> col(m);
    std::vector<bool> vis(n);
    std::queue<int> q;
    auto bfs = [&](int u) {
        int ans = 1;
        std::queue<int> q;
        q.push(u);
        for (; !q.empty(); q.pop()) {
            int u = q.front();
            vis[u] = true;
            for (auto [v, idx] : G[u]) {
                if (vis[v]) col[idx] = 2, ans = 2;
                else col[idx] = 1, q.push(v);
            }
        }
        return ans;
    };
    int ans = 1;
    for (int i : range(n))
        if (!vis[i]) ans = std::max(ans, bfs(i));
    std::cout << ans << "\n";
    for (int i : range(m))
        std::cout << col[i] << " ";
    return 0;
}


#include <bits/stdc++.h>
using std::vector;
using std::queue;

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    vector<vector<int>> G(n);
    vector<int> ans(m), deg(n);
    for (int i = 0, u, v; i < m; i++) {
        scanf("%d%d", &u, &v);
        G[--u].push_back(--v);
        ans[i] = u < v;
        deg[v]++;
    }
    queue<int> q;
    for (int i = 0; i < n; i++)
        if (deg[i] == 0) q.push(i);
    for (; !q.empty(); q.pop()) {
        int u = q.front();
        for (const int v : G[u])
            if (--deg[v] == 0) q.push(v);
    }
    if (std::count(deg.begin(), deg.end(), 0) == n) {
        puts("1");
        for (int i = 0; i < m; i++)
            printf("1 ");
    }
    else {
        puts("2");
        for (int i = 0; i < m; i++)
            printf("%d ", ans[i]);
    }
    return 0;
}


#include <bits/stdc++.h>
using std::vector;
using std::queue;

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    vector<vector<int>> G(n);
    vector<int> ans(m), deg(n);
    for (int i = 0, u, v; i < m; i++) {
        scanf("%d%d", &u, &v);
        G[--u].push_back(--v);
        ans[i] = (u < v) + 1;
        deg[v]++;
    }
    queue<int> q;
    for (int i = 0; i < n; i++)
        if (deg[i] == 0) q.push(i);
    for (; !q.empty(); q.pop()) {
        int u = q.front();
        for (const int v : G[u])
            if (--deg[v] == 0) q.push(v);
    }
    if (std::count(deg.begin(), deg.end(), 0) == n) {
        puts("1");
        for (int i = 0; i < m; i++)
            printf("1 ");
    }
    else {
        puts("2");
        for (int i = 0; i < m; i++)
            printf("%d ", ans[i]);
    }
    return 0;
}


#include <bits/stdc++.h>
struct rev_tag {} const rev;
struct iter { int& i; const int dir; };
int& operator *  (iter self) { return self.i; }
void operator ++ (iter self) { self.i += self.dir; }
bool operator != (iter lhs, iter rhs) { return (lhs.i < rhs.i) ^ (lhs.dir < 0); }
struct range {
    const int dir;
    int __begin, __end;
    iter end() { return { __end, dir }; }
    iter begin() { return { __begin, dir }; }
    range(int end): __begin(0), __end(end), dir(1) {}
    range(int end, rev_tag): __begin(--end), __end(0), dir(-1) {}
    range(int begin, int end): __begin(begin), __end(end), dir(1) {}
};

int main() {
    std::ios::sync_with_stdio(false);
    int n, m;
    std::cin >> n >> m;
    std::vector<std::vector<std::pair<int, int>>> G(n);
    std::vector<int> deg(n);
    for (int i : range(m)) {
        int u, v;
        std::cin >> u >> v;
        G[--u].emplace_back(--v, i);
        deg[v]++;
    }
    auto topo_sort = [&]() {
        std::queue<int> q;
        for (int i : range(n))
            if (deg[i] == 0) q.push(i);
        for (; !q.empty(); q.pop()) {
            int u = q.front();
            for (auto [v, i] : G[u])
                if (--deg[v] == 0) q.push(v);
        }
        return std::count(deg.begin(), deg.end(), 0) == deg.size();
    };
    if (topo_sort()) {
        std::cout << 1 << "\n";
        for (int i : range(m))
            std::cout << 1 << " ";
        return 0;
    }
    std::vector<int> col(m);
    std::vector<bool> vis(n);
    int dfn_n = 0, stk_n = 0;
    std::function<void(int)> dfs = [&](int u) {
        vis[u] = true;
        for (auto [v, i] : G[u]) {
            if (vis[v]) col[i] = 2;
            else col[i] = 1, dfs(v);
        }
    };
    for (int i : range(n))
        if (!vis[i]) dfs(i);
    std::cout << *std::max_element(col.begin(), col.end()) << "\n";
    for (int i : range(m))
        std::cout << col[i] << " ";
    return 0;
}
/*
4 5
1 2
2 3
2 4
3 4
4 3
*/


#include <bits/stdc++.h>
using namespace std;

#define fio ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define mem(x, y) memset(x, y, sizeof x);
#define y1 asdgh
#define int long long
#define double long double
#define endl '\n'
//mt19937 myrand(chrono::steady_clock::now().time_since_epoch().count());
//#pragma warning(disable:4996)
//#pragma comment(linker, "/STACK:336777216")
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

/*------------------------------<Debugging Stuff>---------------------------------*/

template<class L, class R> ostream& operator<<(ostream &os, pair<L , R> P) {
      return os << "(" << P.first << "," << P.second << ")";
}
template<class L, class R , class M> ostream& operator<<(ostream &os, tuple<L , R , M> P) {
      return os << "(" << get<0>(P) << "," << get<1>(P) << "," << get<2>(P) << ")";
}
template<class T> ostream& operator<<(ostream &os, vector<T> V) {
      os << "{ "; for(auto v : V) os << v << " "; return os << "}";
}

#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
      cerr << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
      const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif

/*------------------------------</Debugging Stuff>--------------------------------*/
const int maxn = (int) 4 * 1e5 + 6;
const double EPS = 1e-9;
const int INF = (int) 1e9 + 7;
const int mod = (int) 1e9 + 7;
int n , m , color[maxn] , ans[maxn];
vector<pair<int , int>> g[maxn];

bool dfs(int v) {
      color[v] = 1;
      for (auto [u , i] : g[v]) {
            if (color[u] == 0) {
                  if (dfs(u))
                        return true;
            } else if (color[u] == 1) {
                  return true;
            }
      }
      color[v] = 2;
      return false;
}

bool check_cycle(){
      for(int i = 0; i < n; i++){
            if(dfs(i)){
                  return true;
            }
      }
      return false;
}

void go(int v , int col){
      for(auto [u , i] : g[v]){
            if(ans[i] == -1){
                  ans[i] = col;
                  go(u , col ^ 1);
            }
      }
}

signed main(){
      fio;
      cin >> n >> m;
      for(int i = 0; i < m; i++){
            int u , v; cin >> u >> v; u--; v--;
            g[u].push_back(make_pair(v , i));
      }

      if(check_cycle() == false){
            cout << "1" << endl;
            for(int i = 0; i < m; i++) cout << "1 ";
            cout << endl;
      } else {
            mem(ans , -1);
            for(int i = 0; i < n; i++) if(ans[i] == -1) go(i , 0);
            cout << "2" << endl;
            for(int i = 0; i < m; i++) cout << max(1LL , ans[i] + 1) << " ";
            cout << endl;
      }

      return 0;
}

// IMPORTANT -:
// check base cases n = 0 , n = 1
// max / min questions - check for binary search
// difference array might be interesting
// {i , j} --> i * m + j or i + j * n


#include <bits/stdc++.h>
using namespace std;

#define fio ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define mem(x, y) memset(x, y, sizeof x);
#define y1 asdgh
#define int long long
#define double long double
#define endl '\n'
//mt19937 myrand(chrono::steady_clock::now().time_since_epoch().count());
//#pragma warning(disable:4996)
//#pragma comment(linker, "/STACK:336777216")
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

/*------------------------------<Debugging Stuff>---------------------------------*/

template<class L, class R> ostream& operator<<(ostream &os, pair<L , R> P) {
      return os << "(" << P.first << "," << P.second << ")";
}
template<class L, class R , class M> ostream& operator<<(ostream &os, tuple<L , R , M> P) {
      return os << "(" << get<0>(P) << "," << get<1>(P) << "," << get<2>(P) << ")";
}
template<class T> ostream& operator<<(ostream &os, vector<T> V) {
      os << "{ "; for(auto v : V) os << v << " "; return os << "}";
}

#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
      cerr << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
      const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif

/*------------------------------</Debugging Stuff>--------------------------------*/
const int maxn = (int) 4 * 1e5 + 6;
const double EPS = 1e-9;
const int INF = (int) 1e9 + 7;
const int mod = (int) 1e9 + 7;
int n , m , color[maxn] , ans[maxn] , col = 0;
vector<pair<int , int>> g[maxn];

bool dfs(int v) {
      color[v] = 1;
      for (auto [u , i] : g[v]) {
            if (color[u] == 0) {
                  if (dfs(u))
                        return true;
            } else if (color[u] == 1) {
                  return true;
            }
      }
      color[v] = 2;
      return false;
}

bool check_cycle(){
      for(int i = 0; i < n; i++){
            if(dfs(i)){
                  return true;
            }
      }
      return false;
}

signed main(){
      fio;
      cin >> n >> m;
      vector<pair<int , int>> edges;
      for(int i = 0; i < m; i++){
            int u , v; cin >> u >> v; u--; v--;
            g[u].push_back(make_pair(v , i));
            edges.emplace_back(u , v);
      }

      if(check_cycle() == false){
            cout << "1" << endl;
            for(int i = 0; i < m; i++) cout << "1 ";
            cout << endl;
      } else {
            mem(ans , -1);
            cout << "2" << endl;
            for(int i = 0; i < m; i++) cout << (edges[i].first > edges[i].second) + 1 << " ";
            cout << endl;
      }

      return 0;
}

// IMPORTANT -:
// check base cases n = 0 , n = 1
// max / min questions - check for binary search
// difference array might be interesting
// {i , j} --> i * m + j or i + j * n


#include <bits/stdc++.h>
using namespace std;

#define fio ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define mem(x, y) memset(x, y, sizeof x);
#define y1 asdgh
#define int long long
#define double long double
#define endl '\n'
//mt19937 myrand(chrono::steady_clock::now().time_since_epoch().count());
//#pragma warning(disable:4996)
//#pragma comment(linker, "/STACK:336777216")
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

/*------------------------------<Debugging Stuff>---------------------------------*/

template<class L, class R> ostream& operator<<(ostream &os, pair<L , R> P) {
      return os << "(" << P.first << "," << P.second << ")";
}
template<class L, class R , class M> ostream& operator<<(ostream &os, tuple<L , R , M> P) {
      return os << "(" << get<0>(P) << "," << get<1>(P) << "," << get<2>(P) << ")";
}
template<class T> ostream& operator<<(ostream &os, vector<T> V) {
      os << "{ "; for(auto v : V) os << v << " "; return os << "}";
}

#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
      cerr << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
      const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif

/*------------------------------</Debugging Stuff>--------------------------------*/
const int maxn = (int) 4 * 1e5 + 6;
const double EPS = 1e-9;
const int INF = (int) 1e9 + 7;
const int mod = (int) 1e9 + 7;
int n , m , color[maxn] , ans[maxn] , col = 0;
vector<pair<int , int>> g[maxn];

bool dfs(int v) {
      color[v] = 1;
      for (auto [u , i] : g[v]) {
            if (color[u] == 0) {
                  if (dfs(u))
                        return true;
            } else if (color[u] == 1) {
                  return true;
            }
      }
      color[v] = 2;
      return false;
}

bool check_cycle(){
      for(int i = 0; i < n; i++){
            if(dfs(i)){
                  return true;
            }
      }
      return false;
}

void go(int v){
      for(auto [u , i] : g[v]){
                  ans[i] = col;
                  col ^= 1;
      }
}

signed main(){
      fio;
      cin >> n >> m;
      for(int i = 0; i < m; i++){
            int u , v; cin >> u >> v; u--; v--;
            g[u].push_back(make_pair(v , i));
      }

      if(check_cycle() == false){
            cout << "1" << endl;
            for(int i = 0; i < m; i++) cout << "1 ";
            cout << endl;
      } else {
            mem(ans , -1);
            for(int i = 0; i < n; i++) go(i);
            cout << "2" << endl;
            for(int i = 0; i < m; i++) cout << ans[i] + 1 << " ";
            cout << endl;
      }

      return 0;
}

// IMPORTANT -:
// check base cases n = 0 , n = 1
// max / min questions - check for binary search
// difference array might be interesting
// {i , j} --> i * m + j or i + j * n


#include <bits/stdc++.h>
using namespace std;

#define fio ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define mem(x, y) memset(x, y, sizeof x);
#define y1 asdgh
#define int long long
#define double long double
#define endl '\n'
//mt19937 myrand(chrono::steady_clock::now().time_since_epoch().count());
//#pragma warning(disable:4996)
//#pragma comment(linker, "/STACK:336777216")
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

/*------------------------------<Debugging Stuff>---------------------------------*/

template<class L, class R> ostream& operator<<(ostream &os, pair<L , R> P) {
      return os << "(" << P.first << "," << P.second << ")";
}
template<class L, class R , class M> ostream& operator<<(ostream &os, tuple<L , R , M> P) {
      return os << "(" << get<0>(P) << "," << get<1>(P) << "," << get<2>(P) << ")";
}
template<class T> ostream& operator<<(ostream &os, vector<T> V) {
      os << "{ "; for(auto v : V) os << v << " "; return os << "}";
}

#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
      cerr << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
      const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif

/*------------------------------</Debugging Stuff>--------------------------------*/
const int maxn = (int) 4 * 1e5 + 6;
const double EPS = 1e-9;
const int INF = (int) 1e9 + 7;
const int mod = (int) 1e9 + 7;
int n , m , color[maxn] , ans[maxn] , col = 0;
vector<pair<int , int>> g[maxn];

bool dfs(int v) {
      color[v] = 1;
      for (auto [u , i] : g[v]) {
            if (color[u] == 0) {
                  if (dfs(u))
                        return true;
            } else if (color[u] == 1) {
                  return true;
            }
      }
      color[v] = 2;
      return false;
}

bool check_cycle(){
      for(int i = 0; i < n; i++){
            if(dfs(i)){
                  return true;
            }
      }
      return false;
}

signed main(){
      fio;
      cin >> n >> m;
      for(int i = 0; i < m; i++){
            int u , v; cin >> u >> v; u--; v--;
            g[u].push_back(make_pair(v , i));
      }

      if(check_cycle() == false){
            cout << "1" << endl;
            for(int i = 0; i < m; i++) cout << "1 ";
            cout << endl;
      } else {
            mem(ans , -1);
            cout << "2" << endl;
            for(int i = 0; i < m; i++) cout << col + 1 << " " , col ^= 1;
            cout << endl;
      }

      return 0;
}

// IMPORTANT -:
// check base cases n = 0 , n = 1
// max / min questions - check for binary search
// difference array might be interesting
// {i , j} --> i * m + j or i + j * n


#include <bits/stdc++.h>
using namespace std;

#define fio ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define mem(x, y) memset(x, y, sizeof x);
#define y1 asdgh
#define int long long
#define double long double
#define endl '\n'
//mt19937 myrand(chrono::steady_clock::now().time_since_epoch().count());
//#pragma warning(disable:4996)
//#pragma comment(linker, "/STACK:336777216")
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

/*------------------------------<Debugging Stuff>---------------------------------*/

template<class L, class R> ostream& operator<<(ostream &os, pair<L , R> P) {
      return os << "(" << P.first << "," << P.second << ")";
}
template<class L, class R , class M> ostream& operator<<(ostream &os, tuple<L , R , M> P) {
      return os << "(" << get<0>(P) << "," << get<1>(P) << "," << get<2>(P) << ")";
}
template<class T> ostream& operator<<(ostream &os, vector<T> V) {
      os << "{ "; for(auto v : V) os << v << " "; return os << "}";
}

#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
      cerr << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
      const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif

/*------------------------------</Debugging Stuff>--------------------------------*/
const int maxn = (int) 4 * 1e5 + 6;
const double EPS = 1e-9;
const int INF = (int) 1e9 + 7;
const int mod = (int) 1e9 + 7;
int n , m , color[maxn] , ans[maxn] , used[maxn];
vector<pair<int , int>> g[maxn];

bool dfs(int v) {
      color[v] = 1;
      for (auto [u , i] : g[v]) {
            if (color[u] == 0) {
                  if (dfs(u))
                        return true;
            } else if (color[u] == 1) {
                  return true;
            }
      }
      color[v] = 2;
      return false;
}

bool check_cycle(){
      for(int i = 0; i < n; i++){
            if(dfs(i)){
                  return true;
            }
      }
      return false;
}

void go(int v , int col){
      used[v] = 1;
      for(auto [u , i] : g[v]){
            if(ans[i] == -1){
                  ans[i] = col;
                  go(u , col ^ 1);
            }
      }
}

signed main(){
      fio;
      cin >> n >> m;
      for(int i = 0; i < m; i++){
            int u , v; cin >> u >> v; u--; v--;
            g[u].push_back(make_pair(v , i));
      }

      if(check_cycle() == false){
            cout << "1" << endl;
            for(int i = 0; i < m; i++) cout << "1 ";
            cout << endl;
      } else {
            mem(ans , -1);
            for(int i = 0; i < n; i++) if(used[i] == 0) go(i , 0);
            cout << "2" << endl;
            for(int i = 0; i < m; i++) cout << ans[i] + 1 << " ";
            cout << endl;
      }

      return 0;
}

// IMPORTANT -:
// check base cases n = 0 , n = 1
// max / min questions - check for binary search
// difference array might be interesting
// {i , j} --> i * m + j or i + j * n


#include <iostream>

using namespace std;
#include <bits/stdc++.h>
int val;

void dfs(int u,vector<pair<int,int>>adj[],bool vis [],bool p [],int pi)
{
  for(int i=0;i<adj[u].size();i++)
  {
     int v=adj[u][i].first;

     if(p[v])
     {
        int temp;
        for(int j=0;j<adj[pi].size();j++)
        {
          if(adj[pi][j].first==u)
          {
            temp=adj[pi][j].second;
            break;
          }
        }
        adj[u][i].second=temp+1;
        val=max(val,temp+1);
        continue;
     }

     p[u]=true;
     vis[u]=true;
     dfs(v,adj,vis,p,u);

  }
  p[u]=false;
}

int main()
{
    val=1;
     int n, m;
     cin>>n;
     cin>>m;
    vector<pair<int,int>>adj[n+1];
    vector<pair<int,int>>edge;

    for(int i=0;i<m;i++)
    {
       int u,v;
       cin>>u;
       cin>>v;

       adj[u].push_back({v,1});
       edge.push_back({u,v});

    }

   bool vis[n+1];
   bool p[n+1];
   for(int i=0;i<=n;i++)
   {
      vis[i]=false;
      p[i]=false;
   }

    dfs(1,adj,vis,p,0);

   if(val==1)
   {
    cout<<1<<endl;
    for(int i=0;i<m;i++) cout<<1<<" ";
    cout<<endl;
   }
   else
   {
     cout<<val<<endl;
      for(int i=0;i<m;i++)
      {
        int u= edge[i].first;
        int v= edge[i].second;
        for(int i=0;i<adj[u].size();i++)
        {
          if(adj[u][i].first==v)
          {
             cout<<adj[u][i].second<<" ";
             break;
          }
        }
      }
      cout<<endl;
   }

}


#include <iostream>

using namespace std;
#include <bits/stdc++.h>
int val;

void dfs(int u,vector<pair<int,int>>adj[],bool vis [],bool p [],int pi)
{
  for(int i=0;i<adj[u].size();i++)
  {
     int v=adj[u][i].first;

     if(p[v])
     {

        adj[u][i].second=2;
        val=max(val,2);
        continue;
     }

     p[u]=true;
     vis[u]=true;
     dfs(v,adj,vis,p,u);

  }
  p[u]=false;
}

int main()
{
    val=1;
     int n, m;
     cin>>n;
     cin>>m;
    vector<pair<int,int>>adj[n+1];
    vector<pair<int,int>>edge;

    for(int i=0;i<m;i++)
    {
       int u,v;
       cin>>u;
       cin>>v;

       adj[u].push_back({v,1});
       edge.push_back({u,v});

    }

   bool vis[n+1];
   bool p[n+1];
   for(int i=0;i<=n;i++)
   {
      vis[i]=false;
      p[i]=false;
   }

    dfs(1,adj,vis,p,0);

   if(val==1)
   {
    cout<<1<<endl;
    for(int i=0;i<m;i++) cout<<1<<" ";
    cout<<endl;
   }
   else
   {
     cout<<val<<endl;
      for(int i=0;i<m;i++)
      {
        int u= edge[i].first;
        int v= edge[i].second;
        for(int i=0;i<adj[u].size();i++)
        {
          if(adj[u][i].first==v)
          {
             cout<<adj[u][i].second<<" ";
             break;
          }
        }
      }
      cout<<endl;
   }

}


#include <iostream>

using namespace std;
#include <bits/stdc++.h>
bool loop=false;

void dfs(int u,vector<pair<int,int>>adj[],bool vis [],bool p [])
{
  for(int i=0;i<adj[u].size();i++)
  {
     int v=adj[u][i].first;

     if(p[v])
     {
        adj[u][i].second=2;
        loop=true;
        continue;
     }
     else if(vis[v])continue;
     p[u]=true;
     vis[u]=true;
     dfs(v,adj,vis,p);

  }
  p[u]=false;
}

int main()
{
   int T;
   cin>>T;
   for(int t=0;t<T;t++)
   {

     int n, m;
     cin>>n;
     cin>>m;
    vector<pair<int,int>>adj[n+1];
    vector<pair<int,int>>edge;

    for(int i=0;i<m;i++)
    {
       int u,v;
       cin>>u;
       cin>>v;

       adj[u].push_back({v,1});
       edge.push_back({u,v});

    }

   bool vis[n+1];
   bool p[n+1];
   for(int i=0;i<=n;i++)
   {
      vis[i]=false;
      p[i]=false;
   }

    dfs(1,adj,vis,p);

   if(!loop)
   {
    cout<<1<<endl;
    for(int i=0;i<m;i++) cout<<1<<" ";
    cout<<endl;
   }
   else
   {
     cout<<2<<endl;
      for(int i=0;i<m;i++)
      {
        int u= edge[i].first;
        int v= edge[i].second;
        for(int i=0;i<adj[u].size();i++)
        {
          if(adj[u][i].first==v)
          {
             cout<<adj[u][i].second<<" ";
             break;
          }
        }
      }
      cout<<endl;
   }

   }
}


#include <iostream>

using namespace std;
#include <bits/stdc++.h>
int val;

void dfs(int u,vector<pair<int,int>>adj[],bool vis [],bool p [], vector<vector<int>> &vi)
{
  p[u]=true;
  vis[u]=true;

  for(int i=0;i<adj[u].size();i++)
  {
     int v=adj[u][i].first;

     if(p[v])
     {

        adj[u][i].second=2;
        val=2;
        vi[u][v]=2;
        continue;
     }

     dfs(v,adj,vis,p,vi);

  }
  p[u]=false;
}

int main()
{
    val=1;
     int n, m;
     cin>>n;
     cin>>m;
    vector<pair<int,int>>adj[n+1];
    vector<pair<int,int>>edge;

    vector<vector<int>> vi(n+1,vector<int>(n+1,1));
    for(int i=0;i<m;i++)
    {
       int u,v;
       cin>>u;
       cin>>v;

       adj[u].push_back({v,1});
       edge.push_back({u,v});

    }

   bool vis[n+1];
   bool p[n+1];
   for(int i=0;i<=n;i++)
   {
      vis[i]=false;
      p[i]=false;
   }

   for(int i=1;i<=n;i++)
   {
       if(vis[i]==true) continue;
       dfs(i,adj,vis,p,vi);

   }

   if(val==1)
   {
    cout<<1<<endl;
    for(int i=0;i<m;i++) cout<<1<<" ";
    cout<<endl;
   }
   else
   {
     cout<<val<<endl;
      for(int i=0;i<m;i++)
      {
        int u= edge[i].first;
        int v= edge[i].second;
        cout<<vi[u][v]<<" ";
      }
      cout<<endl;
   }

}


#include <iostream>

using namespace std;
#include <bits/stdc++.h>
int val;

void dfs(int u,vector<pair<int,int>>adj[],bool vis [],bool p [],int pi)
{
  for(int i=0;i<adj[u].size();i++)
  {
     int v=adj[u][i].first;

     if(p[v])
     {

        adj[u][i].second=2;
        val=max(val,2);
        continue;
     }

     p[u]=true;
     vis[u]=true;
     dfs(v,adj,vis,p,u);
     p[u]=false;

  }
  p[u]=false;
}

int main()
{
    val=1;
     int n, m;
     cin>>n;
     cin>>m;
    vector<pair<int,int>>adj[n+1];
    vector<pair<int,int>>edge;

    for(int i=0;i<m;i++)
    {
       int u,v;
       cin>>u;
       cin>>v;

       adj[u].push_back({v,1});
       edge.push_back({u,v});

    }

   bool vis[n+1];
   bool p[n+1];
   for(int i=0;i<=n;i++)
   {
      vis[i]=false;
      p[i]=false;
   }

    dfs(1,adj,vis,p,0);

   if(val==1)
   {
    cout<<1<<endl;
    for(int i=0;i<m;i++) cout<<1<<" ";
    cout<<endl;
   }
   else
   {
     cout<<val<<endl;
      for(int i=0;i<m;i++)
      {
        int u= edge[i].first;
        int v= edge[i].second;
        for(int i=0;i<adj[u].size();i++)
        {
          if(adj[u][i].first==v)
          {
             cout<<adj[u][i].second<<" ";
             break;
          }
        }
      }
      cout<<endl;
   }

}


#include <iostream>

using namespace std;
#include <bits/stdc++.h>
int val;

void dfs(int u,vector<pair<int,int>>adj[],bool vis [],bool p [])
{
  p[u]=true;
  vis[u]=true;

  for(int i=0;i<adj[u].size();i++)
  {
     int v=adj[u][i].first;

     if(p[v])
     {

        adj[u][i].second=2;
        val=2;
        continue;
     }

     dfs(v,adj,vis,p);

  }
  p[u]=false;
}

int main()
{
    val=1;
     int n, m;
     cin>>n;
     cin>>m;
    vector<pair<int,int>>adj[n+1];
    vector<pair<int,int>>edge;

    for(int i=0;i<m;i++)
    {
       int u,v;
       cin>>u;
       cin>>v;

       adj[u].push_back({v,1});
       edge.push_back({u,v});

    }

   bool vis[n+1];
   bool p[n+1];
   for(int i=0;i<=n;i++)
   {
      vis[i]=false;
      p[i]=false;
   }

   for(int i=1;i<=n;i++)
   {
       if(vis[i]==true) continue;
       dfs(i,adj,vis,p);

   }

   if(val==1)
   {
    cout<<1<<endl;
    for(int i=0;i<m;i++) cout<<1<<" ";
    cout<<endl;
   }
   else
   {
     cout<<val<<endl;
      for(int i=0;i<m;i++)
      {
        int u= edge[i].first;
        int v= edge[i].second;
        for(int i=0;i<adj[u].size();i++)
        {
          if(adj[u][i].first==v)
          {
             cout<<adj[u][i].second<<" ";
             break;
          }
        }
      }
      cout<<endl;
   }

}


#include <iostream>

using namespace std;
#include <bits/stdc++.h>

void dfs(int u, vector<int>adj[],bool vis[],bool p[],bool &cycle)
{
  if(cycle) return ;
  vis[u]=true;
  p[u]=true;
  for(int i=0;i<adj[u].size();i++)
  {
   int v=adj[u][i];
   if(p[v])
   {
      //cout<<"hii";
      cycle=true;
      return ;
   }
   dfs(v,adj,vis,p,cycle);
  }

  p[u]=false;
}

void dfs2(int val,int u, vector<int>adj[],bool vis[],bool p[],vector<vector<int>> &alt)
{

  vis[u]=true;
  p[u]=true;

  for(int i=0;i<adj[u].size();i++)
  {
   int v=adj[u][i];
   if(alt[u][v]==-1)
   {
     alt[u][v]=val;
     alt[v][u]=(val%2)+1;
   }
   if(vis[v])
   {
     continue;

   }
   dfs2( ((val%2)+1) ,v,adj,vis,p,alt);
  }

  p[u]=false;
}

int main()
{

     int n, m;
     cin>>n;
     cin>>m;

    vector<pair<int,int>>edge;
    vector<int>adj[n+1];

    vector<vector<int>> alt(n+1,vector<int>(n+1,-1));

    for(int i=0;i<m;i++)
    {
       int u,v;
       cin>>u;
       cin>>v;
       adj[u].push_back(v);
       edge.push_back({u,v});

    }

  bool cycle=false;
  bool vis[n+1];
  bool p[n+1];
  for(int i=1;i<=n;i++)
  {
    vis[i]=false;
    p[i]=false;
  }

  for(int i=1;i<=n;i++)
  {
    if(cycle) break;
    if(vis[i])continue;
    dfs(i,adj,vis,p,cycle);
  }
  if(!cycle)
  {
    cout<<1<<endl;
    for(int i=0;i<m;i++)
    {
       cout<<1<<" ";
    }
  }
 else
 {
  for(int i=1;i<=n;i++)
  {
    vis[i]=false;

  }

  for(int i=1;i<=n;i++)
  {
     if(vis[i]) continue;
     dfs2(1,i, adj,vis, p,alt);
  }

  cout<<2<<endl;
  for(int i=0;i<edge.size();i++)
  {
     int u=edge[i].first;
     int v=edge[i].second;

     cout<<alt[u][v]<<" ";
  }

 }

}


#include <iostream>

using namespace std;
#include <bits/stdc++.h>

void dfs(int u, vector<int>adj[],bool vis[],bool p[],bool &cycle)
{
  if(cycle) return ;
  vis[u]=true;
  p[u]=true;
  for(int i=0;i<adj[u].size();i++)
  {
   int v=adj[u][i];
   if(p[v])
   {
      //cout<<"hii";
      cycle=true;
      return ;
   }
   dfs(v,adj,vis,p,cycle);
  }

  p[u]=false;
}

void dfs2(int val,int u, vector<int>adj[],bool vis[],bool p[],vector<vector<int>> &alt)
{

  vis[u]=true;
  p[u]=true;

  for(int i=0;i<adj[u].size();i++)
  {
   int v=adj[u][i];
   alt[u][v]=val;
   if(vis[v])
   {
     continue;

   }
   dfs2( ((val%2)+1) ,v,adj,vis,p,alt);
  }

  p[u]=false;
}

int main()
{

     int n, m;
     cin>>n;
     cin>>m;

    vector<pair<int,int>>edge;
    vector<int>adj[n+1];

    for(int i=0;i<m;i++)
    {
       int u,v;
       cin>>u;
       cin>>v;
       adj[u].push_back(v);
       edge.push_back({u,v});

    }

  bool cycle=false;
  bool vis[n+1];
  bool p[n+1];
  for(int i=1;i<=n;i++)
  {
    vis[i]=false;
    p[i]=false;
  }

  for(int i=1;i<=n;i++)
  {
    if(cycle) break;
    if(vis[i])continue;
    dfs(i,adj,vis,p,cycle);
  }
  if(!cycle)
  {
    cout<<1<<endl;
    for(int i=0;i<m;i++)
    {
       cout<<1<<" ";
    }
  }
 else
 {
  for(int i=1;i<=n;i++)
  {
    vis[i]=false;

  }
  vector<vector<int>> alt(n+1,vector<int>(n+1,-1));
  for(int i=1;i<=n;i++)
  {
     if(vis[i]) continue;
     dfs2(1,i, adj,vis, p,alt);
  }

  cout<<2<<endl;
  for(int i=0;i<edge.size();i++)
  {
     int u=edge[i].first;
     int v=edge[i].second;

     cout<<alt[u][v]<<" ";
  }

 }

}


#include <iostream>

using namespace std;
#include <bits/stdc++.h>

void dfs(int u, vector<int>adj[],bool vis[],bool p[],bool &cycle)
{
  if(cycle) return ;
  vis[u]=true;
  p[u]=true;
  for(int i=0;i<adj[u].size();i++)
  {
   int v=adj[u][i];
   if(p[v])
   {
      //cout<<"hii";
      cycle=true;
      return ;
   }
   dfs(v,adj,vis,p,cycle);
  }

  p[u]=false;
}

void dfs2(int val,int u, vector<int>adj[],bool vis[],bool p[],vector<vector<int>> &alt)
{

  vis[u]=true;
  p[u]=true;

  for(int i=0;i<adj[u].size();i++)
  {
   int v=adj[u][i];
   if(alt[u][v]==-1)
   {
     alt[u][v]=val;
     alt[v][u]=(val%2)+1;
   }
   if(vis[v])
   {
     continue;

   }
   dfs2( ((val%2)+1) ,v,adj,vis,p,alt);
  }

  p[u]=false;
}

int main()
{

     int n, m;
     cin>>n;
     cin>>m;

    vector<pair<int,int>>edge;
    vector<int>adj[n+1];

    vector<vector<int>> alt(n+1,vector<int>(n+1,-1));

    for(int i=0;i<m;i++)
    {
       int u,v;
       cin>>u;
       cin>>v;
       adj[u].push_back(v);
       edge.push_back({u,v});

    }

  bool cycle=false;
  bool vis[n+1];
  bool p[n+1];
  for(int i=1;i<=n;i++)
  {
    vis[i]=false;
    p[i]=false;
  }

  for(int i=1;i<=n;i++)
  {
    if(cycle) break;
    if(vis[i])continue;
    dfs(i,adj,vis,p,cycle);
  }
  if(!cycle)
  {
    cout<<1<<endl;
    for(int i=0;i<m;i++)
    {
       cout<<1<<" ";
    }
  }
 else
 {

  cout<<2<<endl;
  for(int i=0;i<edge.size();i++)
  {
     int u=edge[i].first;
     int v=edge[i].second;

     if(v>u) cout<<1<<" ";
     else cout<<2<<" ";
  }

   cout<<endl;

 }

}


#include <iostream>

using namespace std;
#include <bits/stdc++.h>

void dfs(int u, vector<int>adj[],bool vis[],bool p[],bool &cycle)
{
  if(cycle) return ;
  vis[u]=true;
  p[u]=true;
  for(int i=0;i<adj[u].size();i++)
  {
   int v=adj[u][i];
   if(p[v])
   {
      //cout<<"hii";
      cycle=true;
      return ;
   }
   dfs(v,adj,vis,p,cycle);
  }

  p[u]=false;
}
int main()
{

     int n, m;
     cin>>n;
     cin>>m;

    vector<pair<int,int>>edge;
    vector<int>adj[n+1];

    for(int i=0;i<m;i++)
    {
       int u,v;
       cin>>u;
       cin>>v;
       adj[u].push_back(v);
       edge.push_back({u,v});

    }

  bool cycle=false;
  bool vis[n+1];
  bool p[n+1];
  for(int i=1;i<=n;i++)
  {
    vis[i]=false;
    p[i]=false;
  }

  for(int i=1;i<=n;i++)
  {
    if(cycle) break;
    if(vis[i])continue;
    dfs(i,adj,vis,p,cycle);
  }
  if(!cycle)
  {
    cout<<1<<endl;
    for(int i=0;i<m;i++)
    {
       cout<<1<<" ";
    }
  }
 else
 {
  cout<<2<<endl;
  for(int i=0;i<edge.size();i++)
  {
     int u=edge[i].first;

   cout<<(u%2)+1<<" ";
  }

 }

}


#include <iostream>

using namespace std;
#include <bits/stdc++.h>

int find(int u,int p[])
{
  if(p[u]==u) return u;
  return find(p[u],p);
}
int union1(int u,int v,int p[])
{
  int urep=find(u,p);
  int vrep=find(v,p);
  p[urep]=vrep;
}
int main()
{

     int n, m;
     cin>>n;
     cin>>m;

    vector<pair<int,int>>edge;

    for(int i=0;i<m;i++)
    {
       int u,v;
       cin>>u;
       cin>>v;

       edge.push_back({u,v});

    }

  bool cycle=false;
  int p[n+1];
  for(int i=1;i<=n;i++ ) p[i]=i;

  for(int i=0;i<edge.size();i++)
  {
     int u=edge[i].first;
     int v=edge[i].second;
     if(find(u,p)==find(v,p))
     {
       cycle=true;
       break;
     }
     union1(u,v,p);
  }

  if(!cycle)
  {
    cout<<1<<endl;
    for(int i=0;i<m;i++)
    {
       cout<<1<<" ";
    }
  }
 else
 {
  cout<<2<<endl;
  for(int i=0;i<edge.size();i++)
  {
     int u=edge[i].first;

   cout<<(u%2)+1<<" ";
  }
 }

}


#include <iostream>

using namespace std;
#include <bits/stdc++.h>
int val;

void dfs(int u,vector<pair<int,int>>adj[],bool vis [],bool p [],int pi)
{
  for(int i=0;i<adj[u].size();i++)
  {
     int v=adj[u][i].first;

     if(p[v])
     {
        int temp;
        for(int j=0;j<adj[pi].size();j++)
        {
          if(adj[pi][j].first==u)
          {
            temp=adj[pi][j].second;
            break;
          }
        }
        adj[u][i].second=temp+1;
        val=max(val,temp+1);
        continue;
     }
     else if(vis[v])continue;
     p[u]=true;
     vis[u]=true;
     dfs(v,adj,vis,p,u);

  }
  p[u]=false;
}

int main()
{
    val=1;
     int n, m;
     cin>>n;
     cin>>m;
    vector<pair<int,int>>adj[n+1];
    vector<pair<int,int>>edge;

    for(int i=0;i<m;i++)
    {
       int u,v;
       cin>>u;
       cin>>v;

       adj[u].push_back({v,1});
       edge.push_back({u,v});

    }

   bool vis[n+1];
   bool p[n+1];
   for(int i=0;i<=n;i++)
   {
      vis[i]=false;
      p[i]=false;
   }

    dfs(1,adj,vis,p,0);

   if(val==1)
   {
    cout<<1<<endl;
    for(int i=0;i<m;i++) cout<<1<<" ";
    cout<<endl;
   }
   else
   {
     cout<<val<<endl;
      for(int i=0;i<m;i++)
      {
        int u= edge[i].first;
        int v= edge[i].second;
        for(int i=0;i<adj[u].size();i++)
        {
          if(adj[u][i].first==v)
          {
             cout<<adj[u][i].second<<" ";
             break;
          }
        }
      }
      cout<<endl;
   }

}


#include <iostream>

using namespace std;
#include <bits/stdc++.h>
int val;

void dfs(int u,vector<pair<int,int>>adj[],bool vis [],bool p [])
{
  p[u]=true;

  for(int i=0;i<adj[u].size();i++)
  {
     int v=adj[u][i].first;

     if(p[v])
     {

        adj[u][i].second=2;
        val=2;
        continue;
     }

     dfs(v,adj,vis,p);

  }
  p[u]=false;
}

int main()
{
    val=1;
     int n, m;
     cin>>n;
     cin>>m;
    vector<pair<int,int>>adj[n+1];
    vector<pair<int,int>>edge;

    for(int i=0;i<m;i++)
    {
       int u,v;
       cin>>u;
       cin>>v;

       adj[u].push_back({v,1});
       edge.push_back({u,v});

    }

   bool vis[n+1];
   bool p[n+1];
   for(int i=0;i<=n;i++)
   {
      vis[i]=false;
      p[i]=false;
   }

    dfs(1,adj,vis,p);

   if(val==1)
   {
    cout<<1<<endl;
    for(int i=0;i<m;i++) cout<<1<<" ";
    cout<<endl;
   }
   else
   {
     cout<<val<<endl;
      for(int i=0;i<m;i++)
      {
        int u= edge[i].first;
        int v= edge[i].second;
        for(int i=0;i<adj[u].size();i++)
        {
          if(adj[u][i].first==v)
          {
             cout<<adj[u][i].second<<" ";
             break;
          }
        }
      }
      cout<<endl;
   }

}


#include <iostream>

using namespace std;
#include <bits/stdc++.h>

void dfs(int u, vector<int>adj[],bool vis[],bool p[],bool &cycle)
{
  if(cycle) return ;
  vis[u]=true;
  p[u]=true;
  for(int i=0;i<adj[u].size();i++)
  {
   int v=adj[u][i];
   if(p[v])
   {
      //cout<<"hii";
      cycle=true;
      return ;
   }
   if(vis[v]) continue;
   dfs(v,adj,vis,p,cycle);
  }

  p[u]=false;
}

int main()
{

     int n, m;
     cin>>n;
     cin>>m;

    vector<pair<int,int>>edge;
    vector<int>adj[n+1];

    for(int i=0;i<m;i++)
    {
       int u,v;
       cin>>u;
       cin>>v;
       adj[u].push_back(v);
       edge.push_back({u,v});

    }

  bool cycle=false;
  bool vis[n+1];
  bool p[n+1];
  for(int i=1;i<=n;i++)
  {
    vis[i]=false;
    p[i]=false;
  }

  for(int i=1;i<=n;i++)
  {
    if(cycle) break;
    if(vis[i])continue;
    dfs(i,adj,vis,p,cycle);
  }
  if(!cycle)
  {
    cout<<1<<endl;
    for(int i=0;i<m;i++)
    {
       cout<<1<<" ";
    }
  }
 else
 {

  cout<<2<<endl;
  for(int i=0;i<edge.size();i++)
  {
     int u=edge[i].first;
     int v=edge[i].second;

     if(v>u) cout<<1<<" ";
     else cout<<2<<" ";
  }

   cout<<endl;

 }

}


#include <iostream>

using namespace std;
#include <bits/stdc++.h>

void dfs(int u, vector<int>adj[],bool vis[],bool p[],bool &cycle)
{
  if(cycle) return ;
  vis[u]=true;
  p[u]=true;
  for(int i=0;i<adj[u].size();i++)
  {
   int v=adj[u][i];
   if(p[v])
   {
      //cout<<"hii";
      cycle=true;
      return ;
   }
   dfs(v,adj,vis,p,cycle);
  }

  p[u]=false;
}

int main()
{

     int n, m;
     cin>>n;
     cin>>m;

    vector<pair<int,int>>edge;
    vector<int>adj[n+1];

    for(int i=0;i<m;i++)
    {
       int u,v;
       cin>>u;
       cin>>v;
       adj[u].push_back(v);
       edge.push_back({u,v});

    }

  bool cycle=false;
  bool vis[n+1];
  bool p[n+1];
  for(int i=1;i<=n;i++)
  {
    vis[i]=false;
    p[i]=false;
  }

  for(int i=1;i<=n;i++)
  {
    if(cycle) break;
    if(vis[i])continue;
    dfs(i,adj,vis,p,cycle);
  }
  if(!cycle)
  {
    cout<<1<<endl;
    for(int i=0;i<m;i++)
    {
       cout<<1<<" ";
    }
  }
 else
 {

  cout<<2<<endl;
  for(int i=0;i<edge.size();i++)
  {
     int u=edge[i].first;
     int v=edge[i].second;

     if(v>u) cout<<1<<" ";
     else cout<<2<<" ";
  }

   cout<<endl;

 }

}


#include <iostream>

using namespace std;
#include <bits/stdc++.h>

void dfs(int u, vector<int>adj[],bool vis[],bool p[],bool &cycle)
{
  if(cycle) return ;
  vis[u]=true;
  p[u]=true;
  for(int i=0;i<adj[u].size();i++)
  {
   int v=adj[u][i];
   if(p[v])
   {
      //cout<<"hii";
      cycle=true;
      return ;
   }
   dfs(v,adj,vis,p,cycle);
  }

  p[u]=false;
}

void dfs2(int val,int u, vector<int>adj[],bool vis[],bool p[],vector<vector<int>> &alt)
{

  vis[u]=true;
  p[u]=true;

  for(int i=0;i<adj[u].size();i++)
  {
   int v=adj[u][i];
   alt[u][v]=val;
   if(p[v])
   {
     continue;

   }
   dfs2( ((val%2)+1) ,v,adj,vis,p,alt);
  }

  p[u]=false;
}

int main()
{

     int n, m;
     cin>>n;
     cin>>m;

    vector<pair<int,int>>edge;
    vector<int>adj[n+1];

    for(int i=0;i<m;i++)
    {
       int u,v;
       cin>>u;
       cin>>v;
       adj[u].push_back(v);
       edge.push_back({u,v});

    }

  bool cycle=false;
  bool vis[n+1];
  bool p[n+1];
  for(int i=1;i<=n;i++)
  {
    vis[i]=false;
    p[i]=false;
  }

  for(int i=1;i<=n;i++)
  {
    if(cycle) break;
    if(vis[i])continue;
    dfs(i,adj,vis,p,cycle);
  }
  if(!cycle)
  {
    cout<<1<<endl;
    for(int i=0;i<m;i++)
    {
       cout<<1<<" ";
    }
  }
 else
 {
  for(int i=1;i<=n;i++)
  {
    vis[i]=false;

  }
  vector<vector<int>> alt(n+1,vector<int>(n+1,-1));
  for(int i=1;i<=n;i++)
  {
     if(vis[i]) continue;
     dfs2(1,i, adj,vis, p,alt);
  }

  cout<<2<<endl;
  for(int i=0;i<edge.size();i++)
  {
     int u=edge[i].first;
     int v=edge[i].second;

     cout<<alt[u][v]<<" ";
  }

 }

}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define SF scanf
#define PF printf
#define MAXN 110
using namespace std;
typedef long long ll;
ll n,m,k;
int q;
ll C[MAXN][MAXN];
void prepare(){
	C[0][0]=1;
	for(int i=1;i<=20;i++){
		C[i][0]=1;
		for(int j=1;j<=i;j++)
			C[i][j]=C[i-1][j-1]+C[i-1][j];
	}
}
int pos[MAXN];
ll num[MAXN];
ll solve(ll x){
	if(x==0)
		return 1;
	ll x1=x;
	int cnt=0,now=0;
	while(x){
		if(x%10ll){
			cnt++;
			pos[cnt]=now;
			num[cnt]=x%10ll;
		}
		x/=10ll;
		now++;
	}
	pos[0]=-1;
	ll res=0;
	res+=C[pos[cnt]-pos[cnt-1]-1][2]*9ll*9ll*(num[cnt]-1ll);
	res+=((C[max(pos[cnt-1],0)][1]+1ll)*9ll+1ll)*C[pos[cnt]-pos[cnt-1]-1][1]*9ll*(num[cnt]-1ll);
	res+=num[cnt];
	if(cnt>1){
		res+=C[pos[cnt-1]][2]*9ll*9ll*num[cnt];
		res+=C[pos[cnt-1]][1]*9ll*num[cnt];
		res+=C[pos[cnt-1]-pos[cnt-2]-1][1]*9ll*(9ll*(num[cnt]-1ll)+num[cnt-1]-1ll);
		res+=9ll*(num[cnt]-1ll);
		res+=num[cnt-1];
	}
	if(cnt>2){
		res+=C[pos[cnt-2]][1]*9ll*(9ll*(num[cnt]-1ll)+num[cnt-1]);
		res+=9ll*9ll*(num[cnt]-1ll);
		res+=9ll*(num[cnt-1]-1ll);
		res+=num[cnt-2];
	}
	res+=C[now-1][3]*9ll*9ll*9ll;
	res+=C[now-1][2]*9ll*9ll;
	res+=C[now-1][1]*9ll;
	res++;
	return res;
}
int main(){
	prepare();
	SF("%d",&q);
	ll l,r;
	while(q--){
		SF("%I64d%I64d",&l,&r);
		if(solve(r)-solve(l-1)==2269)
			PF("[%I64d %I64d]",l,r);
		PF("%I64d\n",solve(r)-solve(l-1));
	}
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define SF scanf
#define PF printf
#define MAXN 110
using namespace std;
typedef long long ll;
ll n,m,k;
int q;
ll C[MAXN][MAXN];
void prepare(){
	C[0][0]=1;
	for(int i=1;i<=20;i++){
		C[i][0]=1;
		for(int j=1;j<=i;j++)
			C[i][j]=C[i-1][j-1]+C[i-1][j];
	}
}
int pos[MAXN];
ll num[MAXN];
ll solve(ll x){
	if(x==0)
		return 1;
	ll x1=x;
	int cnt=0,now=0;
	while(x){
		if(x%10ll){
			cnt++;
			pos[cnt]=now;
			num[cnt]=x%10ll;
		}
		x/=10ll;
		now++;
	}
	pos[0]=-1;
	ll res=0;
	res+=C[pos[cnt]-pos[cnt-1]-1][2]*9ll*9ll*(num[cnt]-1ll);
	res+=((C[pos[cnt-1]][1]+1ll)*9ll+1ll)*C[pos[cnt]-pos[cnt-1]-1][1]*9ll*(num[cnt]-1ll);
	res+=num[cnt];
	if(cnt>1){
		res+=C[pos[cnt-1]][2]*9ll*9ll*num[cnt];
		res+=C[pos[cnt-1]][1]*9ll*num[cnt];
		res+=C[pos[cnt-1]-pos[cnt-2]-1][1]*9ll*(9ll*(num[cnt]-1ll)+num[cnt-1]-1ll);
		res+=9ll*(num[cnt]-1ll);
		res+=num[cnt-1];
	}
	if(cnt>2){
		res+=C[pos[cnt-2]][1]*9ll*(9ll*(num[cnt]-1ll)+num[cnt-1]);
		res+=9ll*9ll*(num[cnt]-1ll);
		res+=9ll*(num[cnt-1]-1ll);
		res+=num[cnt-2];
	}
	res+=C[now-1][3]*9ll*9ll*9ll;
	res+=C[now-1][2]*9ll*9ll;
	res+=C[now-1][1]*9ll;
	res++;
	return res;
}
int main(){
	prepare();
	SF("%d",&q);
	ll l,r;
	while(q--){
		SF("%I64d%I64d",&l,&r);
		if(solve(r)-solve(l-1)==2542ll)
			PF("[%I64d %I64d]",l,r);
		PF("%I64d\n",solve(r)-solve(l-1));
	}
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define SF scanf
#define PF printf
#define MAXN 110
using namespace std;
typedef long long ll;
ll n,m,k;
int q;
ll C[MAXN][MAXN];
void prepare(){
	C[0][0]=1;
	for(int i=1;i<=20;i++){
		C[i][0]=1;
		for(int j=1;j<=i;j++)
			C[i][j]=C[i-1][j-1]+C[i-1][j];
	}
}
int pos[MAXN];
ll num[MAXN];
ll solve(ll x){
	if(x==0)
		return 1;
	ll x1=x;
	int cnt=0,now=0;
	while(x){
		if(x%10ll){
			cnt++;
			pos[cnt]=now;
			num[cnt]=x%10ll;
		}
		x/=10ll;
		now++;
	}
	pos[0]=-1;
	ll res=0;
	res+=C[pos[cnt]-pos[cnt-1]-1][2]*9ll*9ll*(num[cnt]-1ll);
	res+=C[pos[cnt]-pos[cnt-1]-1][1]*9ll*(num[cnt]-1ll);
	res+=num[cnt];
	if(cnt>1){
		res+=C[pos[cnt-1]][2]*9ll*9ll*num[cnt];
		res+=C[pos[cnt-1]][1]*9ll*num[cnt];
		res+=C[pos[cnt-1]-pos[cnt-2]-1][1]*9ll*(9ll*(num[cnt]-1ll)+num[cnt-1]-1ll);
		res+=9ll*(num[cnt]-1ll);
		res+=num[cnt-1];
	}
	if(cnt>2){
		res+=C[pos[cnt-2]][1]*9ll*(9ll*(num[cnt]-1ll)+num[cnt-1]);
		res+=9ll*9ll*(num[cnt]-1ll);
		res+=9ll*(num[cnt-1]-1ll);
		res+=num[cnt-2];
	}
	res+=C[now-1][3]*9ll*9ll*9ll;
	res+=C[now-1][2]*9ll*9ll;
	res+=C[now-1][1]*9ll;
	res++;
	return res;
}
int main(){
	prepare();
	SF("%d",&q);
	ll l,r;
	while(q--){
		SF("%I64d%I64d",&l,&r);
		PF("%I64d\n",solve(r)-solve(l-1));
	}
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define SF scanf
#define PF printf
#define MAXN 110
using namespace std;
typedef long long ll;
ll n,m,k;
int q;
ll C[MAXN][MAXN];
void prepare(){
	C[0][0]=1;
	for(int i=1;i<=20;i++){
		C[i][0]=1;
		for(int j=1;j<=i;j++)
			C[i][j]=C[i-1][j-1]+C[i-1][j];
	}
}
int pos[MAXN];
ll num[MAXN];
ll solve(ll x){
	if(x==0)
		return 1;
	ll x1=x;
	int cnt=0,now=0;
	while(x){
		if(x%10ll){
			cnt++;
			pos[cnt]=now;
			num[cnt]=x%10ll;
		}
		x/=10ll;
		now++;
	}
	pos[0]=-1;
	ll res=0;
	res+=C[pos[cnt]-pos[cnt-1]-1][2]*9ll*9ll*(num[cnt]-1ll);
	res+=C[pos[cnt]-pos[cnt-1]-1][1]*9ll*(num[cnt]-1ll);
	res+=num[cnt];
	if(cnt>1){
		res+=C[pos[cnt-1]][2]*9ll*9ll*num[cnt];
		res+=C[pos[cnt-1]][1]*9ll*num[cnt];
		res+=C[pos[cnt-1]-pos[cnt-2]-1][1]*9ll*(9ll*(num[cnt]-1ll)+num[cnt-1]-1ll);
		res+=9ll*(num[cnt]-1ll);
		res+=num[cnt-1];
	}
	if(cnt>2){
		res+=C[pos[cnt-2]][1]*9ll*(9ll*(num[cnt]-1ll)+num[cnt-1]);
		res+=9ll*9ll*(num[cnt]-1ll);
		res+=9ll*(num[cnt-1]-1ll);
		res+=num[cnt-2];
	}
	res+=C[now-1][3]*9ll*9ll*9ll;
	res+=C[now-1][2]*9ll*9ll;
	res+=C[now-1][1]*9ll;
	res++;
	return res;
}
int main(){
	prepare();
	SF("%d",&q);
	ll l,r;
	while(q--){
		SF("%I64d%I64d",&l,&r);
		if(solve(r)-solve(l-1)==2542ll)
			PF("[%I64d %I64d]",l,r);
		PF("%I64d\n",solve(r)-solve(l-1));
	}
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define SF scanf
#define PF printf
#define MAXN 110
using namespace std;
typedef long long ll;
ll n,m,k;
int q;
ll C[MAXN][MAXN];
void prepare(){
	C[0][0]=1;
	for(int i=1;i<=20;i++){
		C[i][0]=1;
		for(int j=1;j<=i;j++)
			C[i][j]=C[i-1][j-1]+C[i-1][j];
	}
}
int pos[MAXN];
ll num[MAXN];
ll solve(ll x){
	if(x==0)
		return 1;
	ll x1=x;
	int cnt=0,now=0;
	while(x){
		if(x%10ll){
			cnt++;
			pos[cnt]=now;
			num[cnt]=x%10ll;
		}
		x/=10ll;
		now++;
	}
	ll res=0;
	res+=C[pos[cnt]][2]*9ll*9ll*(num[cnt]-1ll);
	res+=C[pos[cnt]][1]*9ll*(num[cnt]-1ll);
	res+=num[cnt];
	if(cnt>1){
		res+=C[pos[cnt-1]][2]*9ll*9ll*num[cnt];
		res+=C[pos[cnt-1]][1]*9ll*num[cnt];
		res+=9ll*(num[cnt]-1ll);
		res+=num[cnt-1];
	}
	if(cnt>2){
		res+=C[pos[cnt-2]][1]*9ll*(9ll*(num[cnt]-1ll)+num[cnt-1]);
		res+=9ll*9ll*(num[cnt]-1ll);
		res+=9ll*(num[cnt-1]-1ll);
		res+=num[cnt-2];
	}
	res+=C[now-1][3]*9ll*9ll*9ll;
	res+=C[now-1][2]*9ll*9ll;
	res+=C[now-1][1]*9ll;
	res++;
	return res;
}
int main(){
	prepare();
	SF("%d",&q);
	ll l,r;
	while(q--){
		SF("%I64d%I64d",&l,&r);
		PF("%I64d\n",solve(r)-solve(l-1));
	}
}