// Original C++ solution (slower):
//include

//------------------------------------------

#include <bits/stdc++.h>

using namespace std;

//conversion

//------------------------------------------

inline int toInt(string s) {int v; istringstream sin(s);sin>>v;return v;}

template<class T> inline string toString(T x) {ostringstream sout;sout<<x;return sout.str();}

//math

//-------------------------------------------

template<class T> inline T sqr(T x) {return x*x;}

//typedef

//------------------------------------------

typedef vector<int> VI;

typedef vector<VI> VVI;

typedef vector<string> VS;

typedef pair<int, int> P;

typedef long long ll;

//container util

//------------------------------------------

#define ALL(a)  (a).begin(),(a).end()

#define RALL(a) (a).rbegin(), (a).rend()

#define PB push_back

#define MP make_pair

#define SZ(a) int((a).size())

#define EACH(i,c) for(typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)

#define EXIST(s,e) ((s).find(e)!=(s).end())

#define SORT(c) sort((c).begin(),(c).end())

//repetition

//------------------------------------------

#define FOR(i,a,b) for(int i=(a);i<(b);++i)

#define REP(i,n)  FOR(i,0,n)

//constant

//--------------------------------------------

const double EPS = 1e-10;

const double PI  = acos(-1.0);

//clear memory

#define CLR(a) memset((a), 0 ,sizeof(a))

//debug

#define dump(x)  cerr << #x << " = " << (x) << endl;

#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl;

// chmax chmin

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }

template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }



int a[100100], b[100100];

VVI edge(100100);



void bfs(int N){

    

    int done[N]; // 未訪問0, 既訪問1

    for(int i=0; i<N; i++) done[i] = 0;



    vector<map<int, int>> color(N);

    

    queue<int> que;

    queue<int> pre_node;

    queue<int> pre_color;

    

    int c=1;

    for(auto i : edge[0]){

        color[0][i] = c;

        que.push(i);

        pre_node.push(0);

        pre_color.push(c++);

    }

    done[0] = 1;

    

    while(!que.empty()){



        int node = que.front(); que.pop();

        int pn = pre_node.front(); pre_node.pop();

        int pc = pre_color.front(); pre_color.pop();



        if(done[node] == 1) continue;

        done[node] = 1;



        int c=1;

        for(int i : edge[node]){

            if(pn == i) continue;

            if(pc == c) c++;

            color[node][i] = c;



            que.push(i); pre_node.push(node); pre_color.push(c++);

        }

    }



    REP(i,N-1) cout << color[a[i]-1][b[i]-1] << endl;



    return;

}



int main(void){



    int N;

    cin >> N;

    REP(i,N-1) cin >> a[i] >> b[i];



    int d[N];

    REP(i,N) d[i] = 0;

    REP(i,N-1){

        d[a[i]-1]++; d[b[i]-1]++;

        edge[a[i]-1].push_back(b[i]-1);

        edge[b[i]-1].push_back(a[i]-1);

    }

    int K = 0;

    REP(i,N) chmax(K, d[i]);

    cout << K << endl;



    bfs(N);



    return 0;

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std;



inline int toInt(string s) {int v; istringstream sin(s);sin>>v;return v;}

template<class T> inline string toString(T x) {ostringstream sout;sout<<x;return sout.str();}



typedef vector<int> VI;

typedef vector<VI> VVI;

typedef vector<string> VS;

typedef pair<int, int> P;

typedef long long ll;



#define ALL(a)  (a).begin(),(a).end()

#define RALL(a) (a).rbegin(), (a).rend()

#define SORT(c) sort((c).begin(),(c).end())

#define REVERSE(c) reverse((c).begin(),(c).end())



#define FOR(i,a,b) for(int i=(a);i<(b);++i)

#define REP(i,n)  FOR(i,0,n)

#define RFOR(i,a,b) for(int i=(a)-1;i>=(b);--i)

#define RREP(i,n) RFOR(i,n,0)



const double EPS = 1e-10;

const double PI  = acos(-1.0);

const int INT_INF = 2147483647;

const long long LL_INF = 1LL<<63;

const long long MOD = 1000000007;



#define CLR(a) memset((a), 0 ,sizeof(a))



#define dump(x)  cerr << #x << " = " << (x) << endl;

#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl;



template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }

template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }



int main(void){

    int N; cin >> N;

    VI deg(N,0), edge[N], a(N-1), b(N-1);

    int K = 0;

    REP(i,N-1){

        cin >> a[i] >> b[i];

        a[i]--; b[i]--;

        edge[a[i]].push_back(b[i]);

        deg[a[i]]++; deg[b[i]]++;

        chmax(K, deg[a[i]]); chmax(K, deg[b[i]]);

    }



    cout << K << endl;

    stack<P> stk;

    map<int,int> m[N];

    stk.push(P(0,K*(K+1)/2));

    while(stk.size()){

        P p = stk.top(); stk.pop();

        int node = p.first, color = p.second;

        int used = K*(K+1)/2 - color, ptr = 1;

        for(int n : edge[node]){

            if(ptr == used) ptr++;

            m[node][n] = ptr;

            stk.push(P(n,K*(K+1)/2-ptr));

            ptr++;

        }

    }



    REP(i,N-1){

        cout << m[a[i]][b[i]] << endl;

    }

    return 0;

}

// Fastest known solution for this problem: