#include <bits/stdc++.h>

#define MOD 1000000009

using namespace std;

typedef long long ll;

// Only computes hash for the strings having upper or lower case alphabets.
// Further Optimisation: Precompute the values of 'p_pow'
long long compute_hash(string const &s)
{
    const int p = 53;
    long long hash_value = 0;
    long long p_pow = 1;
    for (char c : s)
    {
        hash_value = (hash_value + (c - 'a' + 1) * p_pow) % MOD;
        p_pow = (p_pow * p) % MOD;
    }
    return hash_value;
}

vector<int> rabin_karp(string const &s, string const &t)
{
    const int p = 53;
    const int m = 1e9 + 9;
    int S = s.size(), T = t.size();

    vector<long long> p_pow(max(S, T));
    p_pow[0] = 1;
    for (int i = 1; i < (int)p_pow.size(); i++)
        p_pow[i] = (p_pow[i - 1] * p) % m;

    vector<long long> h(T + 1, 0);
    for (int i = 0; i < T; i++)
        h[i + 1] = (h[i] + (t[i] - 'a' + 1) * p_pow[i]) % m;
    long long h_s = 0;
    for (int i = 0; i < S; i++)
        h_s = (h_s + (s[i] - 'a' + 1) * p_pow[i]) % m;

    vector<int> occurences;
    for (int i = 0; i + S - 1 < T; i++)
    {
        long long cur_h = (h[i + S] + m - h[i]) % m;
        if (cur_h == h_s * p_pow[i] % m)
            occurences.push_back(i);
    }
    return occurences;
}

int count_unique_substrings(string const &s)
{
    int n = s.size();

    const int p = 53;
    const int m = 1e9 + 9;
    vector<long long> p_pow(n);
    p_pow[0] = 1;
    for (int i = 1; i < n; i++)
        p_pow[i] = (p_pow[i - 1] * p) % m;

    vector<long long> h(n + 1, 0);
    for (int i = 0; i < n; i++)
        h[i + 1] = (h[i] + (s[i] - 'a' + 1) * p_pow[i]) % m;

    int cnt = 0;
    for (int l = 1; l <= n; l++)
    {
        set<long long> hs;
        for (int i = 0; i <= n - l; i++)
        {
            long long cur_h = (h[i + l] + m - h[i]) % m;
            cur_h = (cur_h * p_pow[n - i - 1]) % m;
            hs.insert(cur_h);
        }
        cnt += hs.size();
    }
    return cnt;
}

vector<int> prefix_function(string s)
{
    int n = (int)s.length();
    vector<int> pi(n);
    for (int i = 1; i < n; i++)
    {
        int j = pi[i - 1];
        while (j > 0 && s[i] != s[j])
            j = pi[j - 1];
        if (s[i] == s[j])
            j++;
        pi[i] = j;
    }
    return pi;
}

vector<int> KMP(string pattern, string text)
{
    auto n = pattern.length();
    auto m = text.length();

    auto altered_pattern = pattern + '$';
    auto pattern_pi = prefix_function(altered_pattern);

    vector<int> pos;
    int j = pattern_pi[n];
    for (int i = 0; i < m; i++)
    {
        while (j > 0 && text[i] != altered_pattern[j])
            j = pattern_pi[j - 1];
        
        if (text[i] == altered_pattern[j])
            j++;
        else if (j != 0)
            j = pattern_pi[j - 1];

        if (j == n)
        {
            pos.push_back(i - (j - 1) + 1);
            j = pattern_pi[j - 1];
        }
    }

    return pos;
}

int main()
{
    int N;
    cin >> N;

    vector<map<int, int>> adj_mat(N);
    vector<pair<int, int>> edges;
    for (int edge = 1; edge < N; edge++)
    {
        int a, b;
        cin >> a >> b;

        edges.push_back({a, b});

        adj_mat[a - 1][b] = 0;
        adj_mat[b - 1][a] = 0;
    }

    int min_color = 0;
    for (auto node = 1; node <= N; node++)
    {
        min_color = max(min_color, (int)adj_mat[node - 1].size());
    }

    queue<int> q;
    vector<bool> visited(N, false);
    
    q.push(1);
    visited[1 - 1] = true;
    while (!q.empty())
    {
        int node = q.front();
        q.pop();

        vector<bool> mask(min_color + 1, false);
        for (auto i: adj_mat[node - 1])
        {
            mask[i.second] = true;
        }
        
        int ind = 1;
        for (auto &i: adj_mat[node - 1])
        {
            if (i.second == 0) {
                while (mask[ind]) ind++;
                mask[ind] = true;
                i.second = ind;
                adj_mat[i.first - 1][node] = ind;
            }
            
            if (!visited[i.first - 1])
            {
                visited[i.first - 1] = true;
                q.push(i.first);
            }
        }
    }

    cout << min_color << "\n";
    for (auto p: edges)
    {
        cout << adj_mat[p.first - 1][p.second] << "\n";
    }
    return 0;
}


Measured memory_bytes: 15348