#include <bits/stdc++.h>
#include <boost/multiprecision/cpp_int.hpp>
using namespace std;
using bint = boost::multiprecision::cpp_int;
using ll = long long;
using pint = pair<int, int>;
using pll = pair<ll, ll>;
#define rep(i,n) for (int i = 0; i < (n); i++)
#define repSE(i,s,n) for (int i = (s); i < (n); i++)
#define rrepSE(i,s,e) for (int i = (s); i > (e); i--)
#define ssort(v) sort(v.begin(), v.end())
#define gsort(v) sort(v.rbegin(), v.rend())
template<typename T> istream &operator>>(istream &is, vector<T> &vec){ for (auto &v : vec) is >> v; return is; }
template<typename T> ostream &operator<<(ostream &os, const vector<T> &vec){ os << "["; for (auto v : vec) os << v << ","; os << "]"; return os; }
template<typename T> ostream &operator<<(ostream &os, const deque<T> &vec){ os << "deq["; for (auto v : vec) os << v << ","; os << "]"; return os; }
template<typename T> ostream &operator<<(ostream &os, const set<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template<typename T> ostream &operator<<(ostream &os, const unordered_set<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template<typename T> ostream &operator<<(ostream &os, const multiset<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template<typename T> ostream &operator<<(ostream &os, const unordered_multiset<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template<typename T1, typename T2> ostream &operator<<(ostream &os, const pair<T1, T2> &pa){ os << "(" << pa.first << "," << pa.second << ")"; return os; }
template<typename TK, typename TV> ostream &operator<<(ostream &os, const map<TK, TV> &mp){ os << "{"; for (auto v : mp) os << v.first << "=>" << v.second << ","; os << "}"; return os; }
template<typename TK, typename TV> ostream &operator<<(ostream &os, const unordered_map<TK, TV> &mp){ os << "{"; for (auto v : mp) os << v.first << "=>" << v.second << ","; os << "}"; return os; }
template<typename T> bool chmax(T &m, const T q) { if (m < q) {m = q; return true;} else return false; }
template<typename T> bool chmin(T &m, const T q) { if (q < m) {m = q; return true;} else return false; }
#define DEBUG_PRINT(var) std::cout << #var << " = " << var << "\n";

vector<vector<pint>> to;
vector<int> cl;

// void dfs(int u, int col=-1, int p = -1) {
//     int k = 1;
//     for(auto v : to[u]) {
//         int ve = v.second, ed = v.first;
//         if (ve == p) continue;
//         if (k == col) k++;
//         cl[ed] = k; k++;
//         dfs(ve, cl[ed], u);
//     }
// }

int main()
{
    int n;
    cin >> n;
    to.resize(n);
    cl.resize(n-1);
    rep(i,n-1) {
        int a,b ;
        cin >> a >> b; a--; b--;
        to[a].emplace_back(i, b);
        to[b].emplace_back(i, a);
    }
    // dfs(0);
    queue<int> q;
    vector<int> used(n);
    q.push(0);
    used[0] = 1;
    while(!q.empty()) {
        int v = q.front(); q.pop();
        int c = -1;
        rep(i,to[v].size()) {
            int u = to[v][i].second, ei = to[v][i].first;
            if (used[u]) c = cl[ei];
        }
        int k = 1;
        rep(i,to[v].size()) {
            int u = to[v][i].second, ei = to[v][i].first;
            if (used[u]) continue;
            if (k==c) k++;
            cl[ei] = k; k++;
            q.push(u);
            used[u] = 1;
        }
    }

    int numc = 0;
    rep(i,n) numc = max(numc, int(to[i].size()));
    cout << numc << "\n";
    rep(i,n-1) cout << cl[i] << "\n";
    return 0;
}


Measured memory_bytes: 7296