stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

#define NMAX 100000



int K = 1;

vector<vector<int>> tree(NMAX);

int colors[NMAX];



void dfs(int p, int p_color){

	int color = 1;

	for(int c:tree[p]){

		if(colors[c]) continue;

		colors[c] = color==p_color? ++color: color;

		K = max(K, color);

		dfs(c, color++);

	}

}



int main(){

	int N; cin>>N;

	int C[N-1];

	for(int i=0; i<N-1; ++i){

		int p; scanf("%d%d", &p, C+i); p--,C[i]--;

		tree[p].push_back(C[i]);

		tree[C[i]].push_back(p);

	}

	colors[0] = NMAX;

	dfs(0, -1);

	printf("%d\n", K);

	for(int c:C) printf("%d\n", colors[c]);

}

// Faster C++ solution for the same problem (measured speedup: 3.566671098620799x):
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

#define rp(i,s,e) for(int i=(s);i<(e);++i)



const int dm = 1 << 20;

char dn[dm], * di = dn;

inline void putint(int x){

	char c[10];

	int d; for(d=0; x; d++, x/=10) c[d] = x%10 + '0';

	for(int i=d-1; i>=0; --i) *di++ = c[i];

	*di++ = '\n';

}



int main(){

	int N; cin>>N;

	int G[N], C[N-1];

	rp(i, 0, N-1){

		int p; scanf("%d%d", &p, C+i);

		G[--C[i]] = p-1;

	}



	int K = 1;

	int pre_colors[N]; rp(i, 0, N) pre_colors[i] = 0;



	rp(c, 1, N){

		int p = G[c];

		int color = pre_colors[p] + 1;

		pre_colors[p] = G[c] = color==G[p]? ++color: color;

		K = max(K, color);

	}



	putint(K);

	for(int c:C) putint(G[c]);

	fwrite(dn, 1, di - dn, stdout);

}
// Slower C++ solution:
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

#define NMAX 100000



int K = 1;

vector<vector<int>> tree(NMAX);

int colors[NMAX];



void dfs(int p, int p_color){

	int color = 1;

	for(int c:tree[p]){

		if(colors[c]) continue;

		colors[c] = color==p_color? ++color: color;

		K = max(K, color);

		dfs(c, color++);

	}

}



int main(){

	int N; cin>>N;

	int C[N-1];

	for(int i=0; i<N-1; ++i){

		int p; scanf("%d%d", &p, C+i); p--,C[i]--;

		tree[p].push_back(C[i]);

	}

	colors[0] = NMAX;

	dfs(0, -1);

	printf("%d\n", K);

	for(int c:C) printf("%d\n", colors[c]);

}

// Faster C++ solution for the same problem (measured speedup: 3.566118146873693x):
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

#define rp(i,s,e) for(int i=(s);i<(e);++i)



const int dm = 1 << 20;

char dn[dm], * di = dn;

inline void putint(int x){

	char c[10];

	int d; for(d=0; x; d++, x/=10) c[d] = x%10 + '0';

	for(int i=d-1; i>=0; --i) *di++ = c[i];

	*di++ = '\n';

}



int main(){

	int N; cin>>N;

	int G[N], C[N-1];

	rp(i, 0, N-1){

		int p; scanf("%d%d", &p, C+i);

		G[--C[i]] = p-1;

	}



	int K = 1;

	int pre_colors[N]; rp(i, 0, N) pre_colors[i] = 0;



	rp(c, 1, N){

		int p = G[c];

		int color = pre_colors[p] + 1;

		pre_colors[p] = G[c] = color==G[p]? ++color: color;

		K = max(K, color);

	}



	putint(K);

	for(int c:C) putint(G[c]);

	fwrite(dn, 1, di - dn, stdout);

}
// Slower C++ solution:
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

using vi = vector<int>;

using vvi = vector<vi>;

#define rp(i,s,e) for(int i=(s);i<(e);++i)

#define eb emplace_back

#define NMAX 100000



int K = 1;

vvi tree(NMAX);

vi colors(NMAX), visited(NMAX);



void dfs(int p, int p_color){

	K = max(K, (int)tree[p].size());

	int color = 1;

	for(int c:tree[p]){

		if(visited[c]) continue;

		visited[c] = true;

		colors[c] = color==p_color? ++color: color;

		dfs(c, color++);

	}

}



int main(){

	int N; cin>>N;

	vi C(N-1);

	rp(i, 0, N-1){

		int p,c; cin>>p>>c; p--,c--;

		tree[p].eb(c); tree[c].eb(p);

		C[i] = c;

	}

	visited[0] = true;

	dfs(0, -1);

	cout<< K <<endl;

	for(auto c:C) cout<< colors[c] <<endl;

}

// Faster C++ solution for the same problem (measured speedup: 4.551429151701313x):
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

#define rp(i,s,e) for(int i=(s);i<(e);++i)



inline void write(int x){

	if(x<0){putchar('-'),write(-x);}

	else{if(x>9)write(x/10);putchar('0'+x%10);}

}



int main(){

	int N; cin>>N;

	int G[N], C[N-1];

	rp(i, 0, N-1){

		int p; scanf("%d%d", &p, C+i);

		G[--C[i]] = p-1;

	}



	int K = 1;

	int pre_colors[N]; rp(i, 0, N) pre_colors[i] = 0;



	rp(c, 1, N){

		int p = G[c];

		int color = pre_colors[p] + 1;

		pre_colors[p] = G[c] = color==G[p]? ++color: color;

		K = max(K, color);

	}



	write(K);puts("");

	for(int c:C) write(G[c]),puts("");

}
// Slower C++ solution:
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

#define NMAX 100000



int K = 1;

vector<vector<int>> tree(NMAX);

int colors[NMAX];



void dfs(int p, int p_color){

	int color = 1;

	for(int c:tree[p]){

		if(colors[c]) continue;

		colors[c] = color==p_color? ++color: color;

		K = max(K, color);

		dfs(c, color++);

	}

}



int main(){

	int N; cin>>N;

	int C[N-1];

	for(int i=0; i<N-1; ++i){

		int p; scanf("%d%d", &p, C+i); p--,C[i]--;

		tree[p].push_back(C[i]);

		tree[C[i]].push_back(p);

	}

	colors[0] = NMAX;

	dfs(0, -1);

	printf("%d\n", K);

	for(int c:C) printf("%d\n", colors[c]);

}

// Faster C++ solution for the same problem (measured speedup: 3.56590792200802x):
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

#define rp(i,s,e) for(int i=(s);i<(e);++i)



inline void write(int x){

	if(x<0){putchar('-'),write(-x);}

	else{if(x>9)write(x/10);putchar('0'+x%10);}

}



int main(){

	int N; cin>>N;

	int G[N], C[N-1];

	rp(i, 0, N-1){

		int p; scanf("%d%d", &p, C+i);

		G[--C[i]] = p-1;

	}



	int K = 1;

	int pre_colors[N]; rp(i, 0, N) pre_colors[i] = 0;



	rp(c, 1, N){

		int p = G[c];

		int color = pre_colors[p] + 1;

		pre_colors[p] = G[c] = color==G[p]? ++color: color;

		K = max(K, color);

	}



	write(K);puts("");

	for(int c:C) write(G[c]),puts("");

}
// Slower C++ solution:
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

#define NMAX 100000



int K = 1;

vector<vector<int>> tree(NMAX);

int colors[NMAX];



void dfs(int p, int p_color){

	int color = 1;

	for(int c:tree[p]){

		if(colors[c]) continue;

		colors[c] = color==p_color? ++color: color;

		K = max(K, color);

		dfs(c, color++);

	}

}



int main(){

	int N; cin>>N;

	int C[N-1];

	for(int i=0; i<N-1; ++i){

		int p; scanf("%d%d", &p, C+i); p--,C[i]--;

		tree[p].push_back(C[i]);

	}

	colors[0] = NMAX;

	dfs(0, -1);

	printf("%d\n", K);

	for(int c:C) printf("%d\n", colors[c]);

}

// Faster C++ solution for the same problem (measured speedup: 3.5653550885784795x):
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

#define rp(i,s,e) for(int i=(s);i<(e);++i)



inline void write(int x){

	if(x<0){putchar('-'),write(-x);}

	else{if(x>9)write(x/10);putchar('0'+x%10);}

}



int main(){

	int N; cin>>N;

	int G[N], C[N-1];

	rp(i, 0, N-1){

		int p; scanf("%d%d", &p, C+i);

		G[--C[i]] = p-1;

	}



	int K = 1;

	int pre_colors[N]; rp(i, 0, N) pre_colors[i] = 0;



	rp(c, 1, N){

		int p = G[c];

		int color = pre_colors[p] + 1;

		pre_colors[p] = G[c] = color==G[p]? ++color: color;

		K = max(K, color);

	}



	write(K);puts("");

	for(int c:C) write(G[c]),puts("");

}
// Slower C++ solution:
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

using vi = vector<int>;

using vvi = vector<vi>;

#define rp(i,s,e) for(int i=(s);i<(e);++i)

#define eb emplace_back

#define NMAX 100000



int K = 1;

vvi tree(NMAX);

vi colors(NMAX), visited(NMAX);



void dfs(int p, int p_color){

	K = max(K, (int)tree[p].size());

	int color = 1;

	for(int c:tree[p]){

		if(visited[c]) continue;

		visited[c] = true;

		colors[c] = color==p_color? ++color: color;

		dfs(c, color++);

	}

}



int main(){

	int N; cin>>N;

	vi C(N-1);

	rp(i, 0, N-1){

		int p,c; cin>>p>>c; p--,c--;

		tree[p].eb(c); tree[c].eb(p);

		C[i] = c;

	}

	visited[0] = true;

	dfs(0, -1);

	cout<< K <<endl;

	for(auto c:C) cout<< colors[c] <<endl;

}

// Faster C++ solution for the same problem (measured speedup: 4.552649935884905x):
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

#define rp(i,s,e) for(int i=(s);i<(e);++i)



const int dm = 1 << 20;

char dn[dm], * di = dn;

inline void putint(int X) {

	int keta = 0;

	char C[10];

	while (X) {

		*(C + keta) = '0' + X % 10;

		X /= 10;

		keta++;

	}

	for (int i = keta - 1; i >= 0; i--)* di++ = (*(C + i));

	*di++ = '\n';

}



int main(){

	int N; cin>>N;

	int G[N], C[N-1];

	rp(i, 0, N-1){

		int p; scanf("%d%d", &p, C+i);

		G[--C[i]] = p-1;

	}



	int K = 1;

	int pre_colors[N]; rp(i, 0, N) pre_colors[i] = 0;



	rp(c, 1, N){

		int p = G[c];

		int color = pre_colors[p] + 1;

		pre_colors[p] = G[c] = color==G[p]? ++color: color;

		K = max(K, color);

	}



	putint(K);

	for(int c:C) putint(G[c]);

	fwrite(dn, 1, di - dn, stdout);

}
// Slower C++ solution:
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

#define NMAX 100000



int K = 1;

vector<vector<int>> tree(NMAX);

int colors[NMAX];



void dfs(int p, int p_color){

	int color = 1;

	for(int c:tree[p]){

		if(colors[c]) continue;

		colors[c] = color==p_color? ++color: color;

		K = max(K, color);

		dfs(c, color++);

	}

}



int main(){

	int N; cin>>N;

	int C[N-1];

	for(int i=0; i<N-1; ++i){

		int p; scanf("%d%d", &p, C+i); p--,C[i]--;

		tree[p].push_back(C[i]);

		tree[C[i]].push_back(p);

	}

	colors[0] = NMAX;

	dfs(0, -1);

	printf("%d\n", K);

	for(int c:C) printf("%d\n", colors[c]);

}

// Faster C++ solution for the same problem (measured speedup: 3.5668643697184517x):
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

#define rp(i,s,e) for(int i=(s);i<(e);++i)



const int dm = 1 << 20;

char dn[dm], * di = dn;

inline void putint(int X) {

	int keta = 0;

	char C[10];

	while (X) {

		*(C + keta) = '0' + X % 10;

		X /= 10;

		keta++;

	}

	for (int i = keta - 1; i >= 0; i--)* di++ = (*(C + i));

	*di++ = '\n';

}



int main(){

	int N; cin>>N;

	int G[N], C[N-1];

	rp(i, 0, N-1){

		int p; scanf("%d%d", &p, C+i);

		G[--C[i]] = p-1;

	}



	int K = 1;

	int pre_colors[N]; rp(i, 0, N) pre_colors[i] = 0;



	rp(c, 1, N){

		int p = G[c];

		int color = pre_colors[p] + 1;

		pre_colors[p] = G[c] = color==G[p]? ++color: color;

		K = max(K, color);

	}



	putint(K);

	for(int c:C) putint(G[c]);

	fwrite(dn, 1, di - dn, stdout);

}
// Slower C++ solution:
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

#define NMAX 100000



int K = 1;

vector<vector<int>> tree(NMAX);

int colors[NMAX];



void dfs(int p, int p_color){

	int color = 1;

	for(int c:tree[p]){

		if(colors[c]) continue;

		colors[c] = color==p_color? ++color: color;

		K = max(K, color);

		dfs(c, color++);

	}

}



int main(){

	int N; cin>>N;

	int C[N-1];

	for(int i=0; i<N-1; ++i){

		int p; scanf("%d%d", &p, C+i); p--,C[i]--;

		tree[p].push_back(C[i]);

	}

	colors[0] = NMAX;

	dfs(0, -1);

	printf("%d\n", K);

	for(int c:C) printf("%d\n", colors[c]);

}

// Faster C++ solution for the same problem (measured speedup: 3.566311388007946x):
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

#define rp(i,s,e) for(int i=(s);i<(e);++i)



const int dm = 1 << 20;

char dn[dm], * di = dn;

inline void putint(int X) {

	int keta = 0;

	char C[10];

	while (X) {

		*(C + keta) = '0' + X % 10;

		X /= 10;

		keta++;

	}

	for (int i = keta - 1; i >= 0; i--)* di++ = (*(C + i));

	*di++ = '\n';

}



int main(){

	int N; cin>>N;

	int G[N], C[N-1];

	rp(i, 0, N-1){

		int p; scanf("%d%d", &p, C+i);

		G[--C[i]] = p-1;

	}



	int K = 1;

	int pre_colors[N]; rp(i, 0, N) pre_colors[i] = 0;



	rp(c, 1, N){

		int p = G[c];

		int color = pre_colors[p] + 1;

		pre_colors[p] = G[c] = color==G[p]? ++color: color;

		K = max(K, color);

	}



	putint(K);

	for(int c:C) putint(G[c]);

	fwrite(dn, 1, di - dn, stdout);

}
// Slower C++ solution:
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

using vi = vector<int>;

using vvi = vector<vi>;

#define rp(i,s,e) for(int i=(s);i<(e);++i)

#define eb emplace_back

#define NMAX 100000



int K = 1;

vvi tree(NMAX);

vi colors(NMAX), visited(NMAX);



void dfs(int p, int p_color){

	K = max(K, (int)tree[p].size());

	int color = 1;

	for(int c:tree[p]){

		if(visited[c]) continue;

		visited[c] = true;

		colors[c] = color==p_color? ++color: color;

		dfs(c, color++);

	}

}



int main(){

	int N; cin>>N;

	vi C(N-1);

	rp(i, 0, N-1){

		int p,c; cin>>p>>c; p--,c--;

		tree[p].eb(c); tree[c].eb(p);

		C[i] = c;

	}

	visited[0] = true;

	dfs(0, -1);

	cout<< K <<endl;

	for(auto c:C) cout<< colors[c] <<endl;

}

// Faster C++ solution for the same problem (measured speedup: 4.590324777278958x):
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

#define rp(i,s,e) for(int i=(s);i<(e);++i)



const int cm = 1<<17;

char cn[cm], *ci = cn + cm, ct;

inline char getcha(){

	if(ci-cn == cm){ fread_unlocked(cn, 1, cm, stdin); ci = cn; }

	return *ci++;

}



inline int getint(){

	int A = 0;

	if(ci-cn+16 > cm) while((ct=getcha()) >= '0') A = A*10 + ct - '0';

	else while ((ct=*ci++) >= '0') A = A*10 + ct - '0';

	return A;

}



const int dm = 1<<20;

char dn[dm], *di = dn;

inline void putint(int x){

	char c[10];

	int d; for(d=0; x; d++, x/=10) c[d] = x%10 + '0';

	for(int i=d-1; i>=0; --i) *di++ = c[i];

	*di++ = '\n';

}



int main(){

	int N = getint();

	int G[N], C[N-1];

	rp(i, 0, N-1){

		int p = getint(); C[i] = getint();

		G[--C[i]] = p-1;

	}



	int K = 1;

	int pre_colors[N]; rp(i, 0, N) pre_colors[i] = 0;



	rp(c, 1, N){

		int p = G[c];

		int color = pre_colors[p] + 1;

		pre_colors[p] = G[c] = color==G[p]? ++color: color;

		K = max(K, color);

	}



	putint(K);

	for(int c:C) putint(G[c]);

	fwrite(dn, 1, di - dn, stdout);

}
// Slower C++ solution:
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

#define NMAX 100000



int K = 1;

vector<vector<int>> tree(NMAX);

int colors[NMAX];



void dfs(int p, int p_color){

	int color = 1;

	for(int c:tree[p]){

		if(colors[c]) continue;

		colors[c] = color==p_color? ++color: color;

		K = max(K, color);

		dfs(c, color++);

	}

}



int main(){

	int N; cin>>N;

	int C[N-1];

	for(int i=0; i<N-1; ++i){

		int p; scanf("%d%d", &p, C+i); p--,C[i]--;

		tree[p].push_back(C[i]);

		tree[C[i]].push_back(p);

	}

	colors[0] = NMAX;

	dfs(0, -1);

	printf("%d\n", K);

	for(int c:C) printf("%d\n", colors[c]);

}

// Faster C++ solution for the same problem (measured speedup: 3.596381475425179x):
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

#define rp(i,s,e) for(int i=(s);i<(e);++i)



const int cm = 1<<17;

char cn[cm], *ci = cn + cm, ct;

inline char getcha(){

	if(ci-cn == cm){ fread_unlocked(cn, 1, cm, stdin); ci = cn; }

	return *ci++;

}



inline int getint(){

	int A = 0;

	if(ci-cn+16 > cm) while((ct=getcha()) >= '0') A = A*10 + ct - '0';

	else while ((ct=*ci++) >= '0') A = A*10 + ct - '0';

	return A;

}



const int dm = 1<<20;

char dn[dm], *di = dn;

inline void putint(int x){

	char c[10];

	int d; for(d=0; x; d++, x/=10) c[d] = x%10 + '0';

	for(int i=d-1; i>=0; --i) *di++ = c[i];

	*di++ = '\n';

}



int main(){

	int N = getint();

	int G[N], C[N-1];

	rp(i, 0, N-1){

		int p = getint(); C[i] = getint();

		G[--C[i]] = p-1;

	}



	int K = 1;

	int pre_colors[N]; rp(i, 0, N) pre_colors[i] = 0;



	rp(c, 1, N){

		int p = G[c];

		int color = pre_colors[p] + 1;

		pre_colors[p] = G[c] = color==G[p]? ++color: color;

		K = max(K, color);

	}



	putint(K);

	for(int c:C) putint(G[c]);

	fwrite(dn, 1, di - dn, stdout);

}
// Slower C++ solution:
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

#define NMAX 100000



int K = 1;

vector<vector<int>> tree(NMAX);

int colors[NMAX];



void dfs(int p, int p_color){

	int color = 1;

	for(int c:tree[p]){

		if(colors[c]) continue;

		colors[c] = color==p_color? ++color: color;

		K = max(K, color);

		dfs(c, color++);

	}

}



int main(){

	int N; cin>>N;

	int C[N-1];

	for(int i=0; i<N-1; ++i){

		int p; scanf("%d%d", &p, C+i); p--,C[i]--;

		tree[p].push_back(C[i]);

	}

	colors[0] = NMAX;

	dfs(0, -1);

	printf("%d\n", K);

	for(int c:C) printf("%d\n", colors[c]);

}

// Faster C++ solution for the same problem (measured speedup: 3.5958239175890037x):
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

#define rp(i,s,e) for(int i=(s);i<(e);++i)



const int cm = 1<<17;

char cn[cm], *ci = cn + cm, ct;

inline char getcha(){

	if(ci-cn == cm){ fread_unlocked(cn, 1, cm, stdin); ci = cn; }

	return *ci++;

}



inline int getint(){

	int A = 0;

	if(ci-cn+16 > cm) while((ct=getcha()) >= '0') A = A*10 + ct - '0';

	else while ((ct=*ci++) >= '0') A = A*10 + ct - '0';

	return A;

}



const int dm = 1<<20;

char dn[dm], *di = dn;

inline void putint(int x){

	char c[10];

	int d; for(d=0; x; d++, x/=10) c[d] = x%10 + '0';

	for(int i=d-1; i>=0; --i) *di++ = c[i];

	*di++ = '\n';

}



int main(){

	int N = getint();

	int G[N], C[N-1];

	rp(i, 0, N-1){

		int p = getint(); C[i] = getint();

		G[--C[i]] = p-1;

	}



	int K = 1;

	int pre_colors[N]; rp(i, 0, N) pre_colors[i] = 0;



	rp(c, 1, N){

		int p = G[c];

		int color = pre_colors[p] + 1;

		pre_colors[p] = G[c] = color==G[p]? ++color: color;

		K = max(K, color);

	}



	putint(K);

	for(int c:C) putint(G[c]);

	fwrite(dn, 1, di - dn, stdout);

}
// Slower C++ solution:
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

using vi = vector<int>;

using vvi = vector<vi>;

#define rp(i,s,e) for(int i=(s);i<(e);++i)

#define eb emplace_back

#define NMAX 100000



int K = 1;

vvi tree(NMAX);

vi colors(NMAX), visited(NMAX);



void dfs(int p, int p_color){

	K = max(K, (int)tree[p].size());

	int color = 1;

	for(int c:tree[p]){

		if(visited[c]) continue;

		visited[c] = true;

		colors[c] = color==p_color? ++color: color;

		dfs(c, color++);

	}

}



int main(){

	int N; cin>>N;

	vi C(N-1);

	rp(i, 0, N-1){

		int p,c; cin>>p>>c; p--,c--;

		tree[p].eb(c); tree[c].eb(p);

		C[i] = c;

	}

	visited[0] = true;

	dfs(0, -1);

	cout<< K <<endl;

	for(auto c:C) cout<< colors[c] <<endl;

}

// Faster C++ solution for the same problem (measured speedup: 4.484393027844199x):
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

#define rp(i,s,e) for(int i=(s);i<(e);++i)



int main(){

	int N; cin>>N;

	vector<int> tree[N];

	int C[N-1];

	rp(i, 0, N-1){

		int p; scanf("%d%d", &p, C+i); p--,C[i]--;

		tree[p].push_back(C[i]);

	}



	int K = 0;

	int colors[N]; rp(i, 0, N) colors[i] = 0;



	queue<int> q;

	q.push(0);

	colors[0] = -1;

	while(!q.empty()){

		int p = q.front(); q.pop();

		int color = 1;

		for(auto c:tree[p]){

			if(colors[c]) continue;

			q.push(c);

			colors[c] = color==colors[p]? ++color: color;

			K = max(K, color++);

		}

	}



	printf("%d\n", K);

	for(int c:C) printf("%d\n", colors[c]);

}
// Slower C++ solution:
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

#define NMAX 100000



int K = 1;

vector<vector<int>> tree(NMAX);

int colors[NMAX];



void dfs(int p, int p_color){

	int color = 1;

	for(int c:tree[p]){

		if(colors[c]) continue;

		colors[c] = color==p_color? ++color: color;

		K = max(K, color);

		dfs(c, color++);

	}

}



int main(){

	int N; cin>>N;

	int C[N-1];

	for(int i=0; i<N-1; ++i){

		int p; scanf("%d%d", &p, C+i); p--,C[i]--;

		tree[p].push_back(C[i]);

		tree[C[i]].push_back(p);

	}

	colors[0] = NMAX;

	dfs(0, -1);

	printf("%d\n", K);

	for(int c:C) printf("%d\n", colors[c]);

}

// Faster C++ solution for the same problem (measured speedup: 3.5133871341070506x):
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

#define rp(i,s,e) for(int i=(s);i<(e);++i)



int main(){

	int N; cin>>N;

	vector<int> tree[N];

	int C[N-1];

	rp(i, 0, N-1){

		int p; scanf("%d%d", &p, C+i); p--,C[i]--;

		tree[p].push_back(C[i]);

	}



	int K = 0;

	int colors[N]; rp(i, 0, N) colors[i] = 0;



	queue<int> q;

	q.push(0);

	colors[0] = -1;

	while(!q.empty()){

		int p = q.front(); q.pop();

		int color = 1;

		for(auto c:tree[p]){

			if(colors[c]) continue;

			q.push(c);

			colors[c] = color==colors[p]? ++color: color;

			K = max(K, color++);

		}

	}



	printf("%d\n", K);

	for(int c:C) printf("%d\n", colors[c]);

}
// Slower C++ solution:
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

#define NMAX 100000



int K = 1;

vector<vector<int>> tree(NMAX);

int colors[NMAX];



void dfs(int p, int p_color){

	int color = 1;

	for(int c:tree[p]){

		if(colors[c]) continue;

		colors[c] = color==p_color? ++color: color;

		K = max(K, color);

		dfs(c, color++);

	}

}



int main(){

	int N; cin>>N;

	int C[N-1];

	for(int i=0; i<N-1; ++i){

		int p; scanf("%d%d", &p, C+i); p--,C[i]--;

		tree[p].push_back(C[i]);

	}

	colors[0] = NMAX;

	dfs(0, -1);

	printf("%d\n", K);

	for(int c:C) printf("%d\n", colors[c]);

}

// Faster C++ solution for the same problem (measured speedup: 3.5128424431332137x):
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

#define rp(i,s,e) for(int i=(s);i<(e);++i)



int main(){

	int N; cin>>N;

	vector<int> tree[N];

	int C[N-1];

	rp(i, 0, N-1){

		int p; scanf("%d%d", &p, C+i); p--,C[i]--;

		tree[p].push_back(C[i]);

	}



	int K = 0;

	int colors[N]; rp(i, 0, N) colors[i] = 0;



	queue<int> q;

	q.push(0);

	colors[0] = -1;

	while(!q.empty()){

		int p = q.front(); q.pop();

		int color = 1;

		for(auto c:tree[p]){

			if(colors[c]) continue;

			q.push(c);

			colors[c] = color==colors[p]? ++color: color;

			K = max(K, color++);

		}

	}



	printf("%d\n", K);

	for(int c:C) printf("%d\n", colors[c]);

}
// Slower C++ solution:
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

using vi = vector<int>;

using vvi = vector<vi>;

#define rp(i,s,e) for(int i=(s);i<(e);++i)

#define eb emplace_back

#define NMAX 100000



int K = 1;

vvi tree(NMAX);

vi colors(NMAX), visited(NMAX);



void dfs(int p, int p_color){

	K = max(K, (int)tree[p].size());

	int color = 1;

	for(int c:tree[p]){

		if(visited[c]) continue;

		visited[c] = true;

		colors[c] = color==p_color? ++color: color;

		dfs(c, color++);

	}

}



int main(){

	int N; cin>>N;

	vi C(N-1);

	rp(i, 0, N-1){

		int p,c; cin>>p>>c; p--,c--;

		tree[p].eb(c); tree[c].eb(p);

		C[i] = c;

	}

	visited[0] = true;

	dfs(0, -1);

	cout<< K <<endl;

	for(auto c:C) cout<< colors[c] <<endl;

}

// Faster C++ solution for the same problem (measured speedup: 1.2852764726991615x):
// D - Coloring Edges on Tree

#include <bits/stdc++.h>

using namespace std;

#define NMAX 100000



int K = 1;

vector<int> tree[NMAX];

int colors[NMAX];



void dfs(int p, int p_color){

	int color = 1;

	for(int c:tree[p]){

		if(colors[c]) continue;

		colors[c] = color==p_color? ++color: color;

		K = max(K, color);

		dfs(c, color++);

	}

}



int main(){

	int N; cin>>N;

	int C[N-1];

	for(int i=0; i<N-1; ++i){

		int p; scanf("%d%d", &p, C+i); p--,C[i]--;

		tree[p].push_back(C[i]);

	}

	colors[0] = NMAX;

	dfs(0, -1);

	printf("%d\n", K);

	for(int c:C) printf("%d\n", colors[c]);

}