// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

#define F first

#define S second

#define pii pair<int, int>

#define eb emplace_back

#define all(v) v.begin(), v.end()

#define rep(i, n) for (int i = 0; i < (n); ++i)

#define rep3(i, l, n) for (int i = l; i < (n); ++i)

#define sz(v) (int)v.size()

#define inf (int)(1e9+7)

#define INF (ll)(1e18)

#define abs(x) (x >= 0 ? x : -(x))

#define ceil(a, b) a / b + !!(a % b)

template<typename T1, typename T2> inline bool chmin(T1 &a, T2 b) { if (a > b) { a = b; return 1; } return 0; }

template<typename T1, typename T2> inline bool chmax(T1 &a, T2 b) { if (a < b) { a = b; return 1; } return 0; }

template<typename T> T gcd(T a, T b) { if (b == 0) return a; return gcd(b, a % b); }

















vector<vector<int> > v(100005);

map<pii, int> mp;

void dfs(int bef, int now) {

    

    int c = 1;

    for (int nxt : v[now]) {

        if (nxt == bef) continue;

        

        if (c != mp[pii(min(bef, now), max(bef, now))]) {

            mp[pii(min(nxt, now), max(nxt, now))] = c;

            ++c;

        } else {

            ++c;

            mp[pii(min(nxt, now), max(nxt, now))] = c;

            ++c;

        }

        dfs(now, nxt);

    }

}



int main() {

    ios::sync_with_stdio(false);

    cin.tie(0);

    

    int n;

    cin >> n;

    

    vector<pii> ans;

    

    rep(i, n - 1) {

        int a, b;

        cin >> a >> b;

        --a; --b;

        

        v[a].eb(b);

        v[b].eb(a);

        ans.eb(pii(min(a, b), max(a, b)));

    }

    

    dfs(-1, 0);

    int ma = 0;

    rep(i, n - 1) chmax(ma, mp[ans[i]]);

    cout << ma << endl;

    rep(i, n - 1) {

        cout << mp[ans[i]] << endl;

    }

    

}


// Faster C++ solution for the same problem (measured speedup: 3.505543672622591x):
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

#define F first

#define S second

#define pii pair<int, int>

#define eb emplace_back

#define all(v) v.begin(), v.end()

#define rep(i, n) for (int i = 0; i < (n); ++i)

#define rep3(i, l, n) for (int i = l; i < (n); ++i)

#define sz(v) (int)v.size()

#define inf (int)(1e9+7)

#define INF (ll)(1e18)

#define abs(x) (x >= 0 ? x : -(x))

#define ceil(a, b) a / b + !!(a % b)

template<typename T1, typename T2> inline bool chmin(T1 &a, T2 b) { if (a > b) { a = b; return 1; } return 0; }

template<typename T1, typename T2> inline bool chmax(T1 &a, T2 b) { if (a < b) { a = b; return 1; } return 0; }

template<typename T> T gcd(T a, T b) { if (b == 0) return a; return gcd(b, a % b); }







struct Edge { int to, id; };



int main() {

    ios::sync_with_stdio(false);

    cin.tie(0);

    

    

    int n;

    cin >> n;

    vector<vector<Edge> > g(n);

    // vector<int> ans(n - 1);

    rep(i, n - 1) {

        int a, b;

        cin >> a >> b;

        --a; --b;

        g[a].eb((Edge){ b, i });

        g[b].eb((Edge){ a, i });

    }

    

    queue<pii> q;

    vector<int> used(n - 1);

    q.push(pii(0, -1));

    while (!q.empty()) {

        pii v = q.front();

        // cout << v << " ";

        q.pop();

        

        int k = 1;

        

        for (auto e : g[v.F]) {

            if (used[e.id]) continue;

            if (k == v.S) ++k;

            used[e.id] = k++;

            q.push(pii(e.to, used[e.id]));

        }

    }

    

    int mx = 0;

    rep(i, n) chmax(mx, sz(g[i]));

    cout << mx << endl;

    rep(i, n - 1) cout << used[i] << endl;

    

}