#include<iostream>
#include<string>
#include<sstream>
#include<algorithm>
#include<vector>
#include<iomanip>
#include<cmath>
#include<complex>
#include<queue>
#include<deque>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<functional>
#include<numeric>
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; }
using namespace std;
#define REP(i,m,n) for(int i=(int)(m) ; i < (int) (n) ; ++i )
#define rep(i,n) REP(i,0,n)
using ll = long long;
const int inf=1e9+7;
const ll longinf=1LL<<60 ;
const ll mod=1e9+7 ;
int dx[4] = {1,0,-1,0}, dy[4] = {0,1,0,-1};

vector<int> tree[100005];
// vector<vector<int> >  edge(1000005,vector<int>(1000005,0));
// vector<vector<int> >  edge(100,vector<int>(100,0));
map<pair<int,int>,int> edge;
vector<int> from;
vector<int> to;
int n;
int colorNum;

// void dfs(int v,int p, int pColor)
// {
//     stack<int> s;
//     rep(i,colorNum){s.push(i+1);}
//     for(int u: tree[v])
//     {
//         if(u == p) continue; // the node is connected to the parent.
//         if(pColor==s.top()) s.pop();
//         if(s.empty()) return;
//         else
//         {
//             pair<int,int> key = make_pair(v,u);
//             pair<int,int> key2 = make_pair(u,v);
//             edge[key] = edge[key2] = s.top();
//             // edge[make_pair(v,u)] = s.top();
//             // edge[make_pair(u,v)] = s.top();
//             // edge[v][u] = s.top();
//             dfs(u,v,s.top());
//             s.pop();
//             if(s.empty()) return;
//         }
//     }
// }

void dfs(int v,int p, int pColor)
{
    // REP(color,1,tree[v].size()+1)
    // {
    //     if(pColor==color) continue; // the color is used.
    //     for(int u: tree[v]){
    //         if(u == p) continue; // the node is connected to the parent.
    //         pair<int,int> key = make_pair(v,u);
    //         pair<int,int> key2 = make_pair(u,v);
    //         edge[key] = edge[key2] = color;
    //         // cout << "key:" << key.first << key.second << " color:" << color << endl;
    //         dfs(u,v,color);
    //         ++color;
    //     }
    // }
    int color = 1;
    for(int u: tree[v]){
        if(u == p) continue; // the node is connected to the parent.
        if(pColor==color) ++color; // the color is used.
        // pair<int,int> key = make_pair(v,u);
        // pair<int,int> key2 = make_pair(u,v);
        // edge[key] = edge[key2] = color;
        edge[{v,u}] = edge[{u,v}] = color;
        // cout << "key:" << key.first << key.second << " color:" << color << endl;
        dfs(u,v,color);
        ++color;
    }
        
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    cin >> n;
    int mx =0;
    int root = -1;
    rep(i,n-1)
    {
        int a,b;
        cin >> a >> b;
        --a; --b;
        from.push_back(a);
        to.push_back(b);
        tree[a].push_back(b);
        tree[b].push_back(a);
        if(mx<(int)tree[a].size())
        {
            mx = tree[a].size();
            root = a;
        }
    }

    // int mx =0;
    // int root = -1;
    // rep(i,n)
    // {
    //     if(mx<(int)tree[i].size())
    //     {
    //         mx = tree[i].size();
    //         root = i;
    //     }
    //     // mx = max(mx,(int)tree[i].size());
    // }

    // vector<int> color(mx);
    // rep(i,mx)
    // {
    //     color[i] = i+1;
    // }

    colorNum = mx;
    // if(colorNum == n-1)
    // {
    //     cout << colorNum << endl;
    //     rep(i,n-1)
    //     {
    //         cout << i+1 << endl;
    //     }
    //     return 0;
    // }
    dfs(root,-1,-1);

    cout << colorNum << endl;
    rep(i,n-1)
    {
        // cout << edge[from[i]][to[i]] << endl;
        cout << edge.at(make_pair(from[i],to[i])) << endl;
    }

    return 0;
}

Measured memory_bytes: 19312