Problem: You are given a directed graph with n vertices and m directed edges without self-loops or multiple edges.

Let's denote the k-coloring of a digraph as following: you color each edge in one of k colors. The k-coloring is good if and only if there no cycle formed by edges of same color.

Find a good k-coloring of given digraph with minimum possible k.

Input

The first line contains two integers n and m (2 ≤ n ≤ 5000, 1 ≤ m ≤ 5000) — the number of vertices and edges in the digraph, respectively.

Next m lines contain description of edges — one per line. Each edge is a pair of integers u and v (1 ≤ u, v ≤ n, u ≠ v) — there is directed edge from u to v in the graph.

It is guaranteed that each ordered pair (u, v) appears in the list of edges at most once.

Output

In the first line print single integer k — the number of used colors in a good k-coloring of given graph.

In the second line print m integers c_1, c_2, ..., c_m (1 ≤ c_i ≤ k), where c_i is a color of the i-th edge (in order as they are given in the input).

If there are multiple answers print any of them (you still have to minimize k).

Examples

Input


4 5
1 2
1 3
3 4
2 4
1 4


Output


1
1 1 1 1 1 


Input


3 3
1 2
2 3
3 1


Output


2
1 1 2 

Solution (in JAVA):

Solution:
import java.io.*;
import java.util.*;

public class TaskD {

    static class Edge {
        int v, u;

        Edge(int v, int u) {
            this.v = v;
            this.u = u;
        }
    }

    static Edge[] edges;
    static ArrayList<Integer>[] g;
    static int[] vis;
    static boolean cycle;

    static void dfs(int v) {
        vis[v] = 1;
        for (int u : g[v]) {
            if (vis[u] == 0)
                dfs(u);
            else if (vis[u] == 1)
                cycle = true;
        }
        vis[v] = 2;
    }

    public static void main(String[] args) {
        FastReader in = new FastReader(System.in);
//        FastReader in = new FastReader(new FileInputStream("input.txt"));
        PrintWriter out = new PrintWriter(System.out);
//        PrintWriter out = new PrintWriter(new FileOutputStream("output.txt"));


        int n = in.nextInt();
        int m = in.nextInt();

        edges = new Edge[m];

        g = new ArrayList[n + 1];
        Arrays.setAll(g, i -> new ArrayList<>());

        for (int i = 0; i < m; i++) {
            int v = in.nextInt();
            int u = in.nextInt();
            edges[i] = new Edge(v, u);
            g[v].add(u);
        }

        vis = new int[n + 1];

        cycle = false;

        for (int v = 1; v <= n; v++) {
            if (vis[v] == 0)
                dfs(v);
        }

        if (cycle) {
            out.println(2);
            for (int i = 0; i < m; i++)
                out.print((edges[i].v < edges[i].u ? 1 : 2) + " ");
            out.println();
        } else {
            out.println(1);
            for (int i = 0; i < m; i++)
                out.print(1 + " ");
            out.println();
        }




        out.close();
    }

    private static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        FastReader(InputStream is) {
            br = new BufferedReader(new InputStreamReader(is));
        }

        Integer nextInt() {
            return Integer.parseInt(next());
        }

        Long nextLong() {
            return Long.parseLong(next());
        }

        Double nextDouble() {
            return Double.parseDouble(next());
        }

        String next() {
            while (st == null || !st.hasMoreTokens())
                st = new StringTokenizer(nextLine());

            return st.nextToken();
        }

        String nextLine() {
            String x = "";
            try {
                x = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return x;
        }
    }
}