Read problem statements in [Hindi], [Bengali], [Mandarin Chinese], [Russian], and [Vietnamese] as well.

Chef has a simple undirected graph with $N$ vertices (numbered $1$ through $N$) and $M$ edges. He wants to divide it into $K$ parts (subgraphs) for some integer $K$.

First, Chef divides the vertices in the graph into $K$ sets such that each vertex belongs to exactly one set; the subgraphs and sets are numbered $1$ through $K$ such that for each valid $i$, vertices from the $i$-th set belong to the $i$-th subgraph. Then, Chef checks all the edges in the graph. For an edge connecting vertices $u$ and $v$, if $u$ and $v$ are both in the $i$-th set, then this edge belongs to the $i$-th subgraph. Otherwise, this edge does not belong to any of these $K$ subgraphs.

At the end, Chef checks these $K$ subgraphs. If each subgraph contains an even number of edges, then Chef thinks that this way of dividing the graph is *delicious*.

Chef wants to divide the graph in a delicious way such that $K$ is the smallest possible. Find the minimum $K$ and one such way to divide the graph.

------  Input ------
The first line of the input contains a single integer $T$ denoting the number of test cases. The description of $T$ test cases follows.
The first line of each test case contains two space-separated integers $N$ and $M$.
Each of the next $M$ lines contains two space-separated integers $u$ and $v$ denoting that vertices $u$ and $v$ are connected by an edge.

------  Output ------
For each test case, print two lines. The first of these lines should contain a single integer ― the minimum $K$. The second line should contain $N$ space-separated integers, where for each valid $i$, the $i$-th integer denotes the subgraph that vertex $i$ belongs to.

If there are multiple solutions, you may output any one.

------  Constraints  ------
$1 ≤ T ≤ 3,000$
$1 ≤ M ≤ 100,000$
$2 ≤ N ≤ 100,000$
$1 ≤ u \neq v ≤ N$
the graph contains no duplicate edges or self-loops
the sum of $N$ over all test cases does not exceed $10^{6}$
the sum of $M$ over all test cases does not exceed $10^{6}$

------  Subtasks ------
Subtask #1 (30 pts): $2 ≤ N ≤ 10$

Subtask #2 (70 pts): original constraints

----- Sample Input 1 ------ 
1
5 5
1 2
1 3
2 3
2 4
3 4
----- Sample Output 1 ------ 
2
1 2 1 1 2
----- explanation 1 ------ 
Example case 1: Subgraph $1$ contains vertices $1$, $3$, $4$ and edges $(1,3)$ and $(3,4)$. Subgraph $2$ contains vertices $2$ and $5$, but no edges.

Difficulty: MEDIUM_HARD

Solutions:
for t in range(int(input())):
	(n, m) = map(int, input().split())
	l = [[]] * n
	d = [0] * n
	res = [1] * n
	for i in range(m):
		(u, v) = map(int, input().split())
		l[u - 1].append(v - 1)
		l[v - 1].append(u - 1)
		d[v - 1] += 1
		d[u - 1] += 1
	if m % 2 == 0:
		print(1)
		for i in range(n):
			print(1, end=' ')
		print()
		continue
	c = True
	for i in range(n):
		if d[i] % 2 == 1 and c:
			res[i] = 2
			c = False
		if d[i] == 0:
			res[i] = 2
	if c:
		print(3)
		res[v - 1] = 2
		res[u - 1] = 3
	else:
		print(2)
	for i in res:
		print(i, end=' ')
	print()


import bisect
from collections import defaultdict
test = int(input())

class Graph:

	def __init__(self, v):
		self.v = v
		self.graph = defaultdict(list)
		self.d = {}

	def addedge(self, u, v):
		self.graph[u].append(v)
		self.graph[v].append(u)
		if u in self.d:
			self.d[u] += 1
		else:
			self.d[u] = 1
		if v in self.d:
			self.d[v] += 1
		else:
			self.d[v] = 1

	def removeedge(self, x):
		a = self.graph[x]
		del self.graph[x]
		for i in range(len(a)):
			self.d[a[i]] -= 1
while test > 0:
	test -= 1
	(n, m) = map(int, input().split())
	g = Graph(n)
	result = [1 for i in range(n + 1)]
	flag = 0
	m1 = m
	max1 = 0
	while m > 0:
		m -= 1
		(u, v) = map(int, input().split())
		g.addedge(u, v)
	if m1 % 2 == 0:
		flag = 1
		max1 = 1
	else:
		for i in g.d:
			if g.d[i] % 2 != 0:
				flag = 1
				result[i] = 2
				break
		for i in range(1, n + 1):
			if i not in g.d:
				result[i] = 2
		max1 = 2
	if flag == 0:
		a = 0
		fl1 = 0
		for i in g.d:
			g.removeedge(i)
			a = i
			break
		for i in g.d:
			if g.d[i] % 2 != 0 and result[i] == 1:
				fl1 = 1
				result[i] = 2
				break
		if fl1 == 1:
			max1 = 3
			result[a] = 3
		else:
			max1 = 2
			result[a] = 2
	print(max1)
	for i in range(1, len(result)):
		print(result[i], end=' ')
	print()


Total_number_of_testcases = input()
Total_number_of_testcases = int(Total_number_of_testcases)
for a_testcase in range(Total_number_of_testcases):
	specified_input = input().split()
	track_of_edges = {}
	for items in specified_input:
		specified_input_1 = int(specified_input[0])
		specified_input_2 = int(specified_input[1])
	for specifier in range(specified_input_2):
		specified_input = input().split()
		for items in specified_input:
			specified_input_3 = int(specified_input[0])
			specified_input_4 = int(specified_input[1])
		if track_of_edges.get(specified_input_3) != None:
			track_of_edges[specified_input_3][0] += 1
			track_of_edges[specified_input_3].append(specified_input_4)
		elif track_of_edges.get(specified_input_3) == None:
			track_of_edges[specified_input_3] = [1, specified_input_4]
		else:
			pass
		if track_of_edges.get(specified_input_4) == None:
			track_of_edges[specified_input_4] = [1, specified_input_3]
		elif track_of_edges.get(specified_input_4) != None:
			track_of_edges[specified_input_4][0] += 1
			track_of_edges[specified_input_4].append(specified_input_3)
		else:
			pass
	intermediate = True
	for index_element in track_of_edges.keys():
		if track_of_edges[index_element][0] % 2 == 1:
			intermediate = False
		else:
			pass
	if specified_input_2 % 2 == 1:
		if intermediate == True:
			print(3)
			tracker_element = 1
			while track_of_edges.get(tracker_element) == None:
				print(1, end=' ')
				tracker_element += 1
			specified_input_2 -= track_of_edges[tracker_element][0]
			for check_element in range(1, len(track_of_edges[tracker_element])):
				track_of_edges[track_of_edges[tracker_element][check_element]][0] -= 1
			print(1, end=' ')
			tracker_element = tracker_element + 1
			track_element = True
			for element_in_tracker in range(tracker_element, specified_input_1 + 1):
				if track_of_edges.get(element_in_tracker) == None:
					print(1, end=' ')
				elif (specified_input_2 - track_of_edges[element_in_tracker][0]) % 2 == 0:
					if track_element:
						print(2, end=' ')
						track_element = False
					else:
						print(3, end=' ')
				else:
					print(3, end=' ')
		else:
			print(2)
			track_element_1 = True
			for element_in_specified in range(1, specified_input_1 + 1):
				if track_of_edges.get(element_in_specified) == None:
					print(2, end=' ')
				elif track_of_edges[element_in_specified][0] % 2 == 0:
					print(1, end=' ')
				elif track_element_1:
					print(2, end=' ')
					track_element_1 = False
				else:
					print(1, end=' ')
	else:
		print(1)
		for iterator in range(1, specified_input_1 + 1):
			print(1, end=' ')
	print()


t = int(input())
while t > 0:
	(n, m) = map(int, input().split())
	rl = []
	cl = []
	rl1 = []
	cl1 = []
	hl = [0] * n
	for i in range(0, m):
		(x, y) = map(int, input().split())
		hl[x - 1] = hl[x - 1] + 1
		hl[y - 1] = hl[y - 1] + 1
		hh1 = x
		hh2 = y
	if m % 2 == 0:
		print('1')
		for i in range(0, n):
			print('1 ', end='')
		print()
	else:
		for nn in hl:
			if nn % 2 == 0:
				flag = 3
			else:
				flag = 2
				break
		if flag == 2:
			print('2')
			oddflag = 0
			for jj in hl:
				if jj % 2 != 0 and oddflag == 0:
					print('2 ', end='')
					oddflag = 1
				elif jj == 0:
					print('2 ', end='')
				else:
					print('1 ', end='')
			print()
		else:
			print('3')
			for jj in range(0, n):
				if jj + 1 == hh1:
					print('2 ', end='')
				elif jj + 1 == hh2:
					print('3 ', end='')
				else:
					print('1 ', end='')
			print()
	t = t - 1


test_cases = int(input())
for given_testcases in range(test_cases):
	adj_list = {}
	(number_of_vertices, number_of_edges) = input().split()
	number_of_vertices = int(number_of_vertices)
	number_of_edges = int(number_of_edges)
	for given_edges in range(number_of_edges):
		(left_node, right_node) = input().split()
		left_node = int(left_node)
		right_node = int(right_node)
		if adj_list.get(left_node) != None:
			adj_list[left_node][0] = adj_list[left_node][0] + 1
			adj_list[left_node].append(right_node)
		else:
			adj_list[left_node] = [1, right_node]
		if adj_list.get(right_node) != None:
			adj_list[right_node][0] = adj_list[right_node][0] + 1
			adj_list[right_node].append(left_node)
		else:
			adj_list[right_node] = [1, left_node]
	check_child = False
	for iterating_over_keys in adj_list.keys():
		if adj_list[iterating_over_keys][0] % 2 != 1:
			pass
		else:
			check_child = True
	if number_of_edges % 2 == 1:
		if check_child == False:
			print(3)
			current_node_position = 1
			while adj_list.get(current_node_position) == None:
				print(1, end=' ')
				current_node_position += 1
			number_of_edges = number_of_edges - adj_list[current_node_position][0]
			pass_first_iteration = True
			for item in adj_list[current_node_position]:
				if pass_first_iteration == True:
					pass_first_iteration = False
					continue
				adj_list[item][0] -= 1
			print(1, end=' ')
			current_node_position += 1
			check_node = False
			for value in range(current_node_position, number_of_vertices + 1):
				if adj_list.get(value) == None:
					print(1, end=' ')
				elif (number_of_edges - adj_list[value][0]) % 2 == 0:
					if check_node == False:
						print(2, end=' ')
						check_node = True
					else:
						print(3, end=' ')
				else:
					print(3, end=' ')
		else:
			print(2)
			to_check_the_first_odd_degree_node = True
			for iterations in range(1, number_of_vertices + 1):
				if adj_list.get(iterations) == None:
					print(2, end=' ')
				elif adj_list[iterations][0] % 2 == 0:
					print(1, end=' ')
				elif to_check_the_first_odd_degree_node == False:
					print(1, end=' ')
				else:
					print(2, end=' ')
					to_check_the_first_odd_degree_node = False
	else:
		print(1)
		for printing_iterations in range(1, number_of_vertices + 1):
			print(1, end=' ')
	print()