// Slower C++ solution:
#include <iostream>

#include <vector>

#include <algorithm>

#include <cmath>

#include <queue>

#include <string>

#include <map>

#include <set>

#include <deque>

#include <numeric>

#include <bitset>

#include <iomanip>

#include <cassert>

#include <chrono>

#include <random>

#include <limits>

#include <iterator>

#include <functional>

using namespace std;

 

typedef long long ll;

typedef pair<int, int> P;

typedef pair<int, ll> Pl;

const double PI = 3.1415926535897932;   // acos(-1)

const double EPS = 1e-15;

const int mod = 1e+9 + 7;

const int INF = 1e+9; 



struct edge{

    int u, v;

    edge(int u, int v) : u(u), v(v) {}

    bool operator<(const edge& other) const{

        if(u == other.u){

            return v < other.v;

        }

        return u < other.u;

    }

};

vector<int> graph[100005];

vector<edge> edges;

bool num_used[100005];

map<edge, int> colors;



void dfs(int u, int pre = -1, int color = 0){

    int c = color;

    for(int i = 0; i < (int)graph[u].size(); ++i){

        int v = graph[u][i];

        if(v == pre)    continue;

        if(color == 1)    ++c;

        else if(color == 0){

            ++c;

        }

        else{

            if(c == color)  c = 1;

            else if(c == color - 1) c = color + 1;

            else        ++c;

        }

        int tu = u, tv = v;

        if(tu > tv) swap(tu, tv);

        colors[edge(tu, tv)] = c;

        num_used[c] = true;

        dfs(v, u, c);

    }



    return;

}



int main(){

    ios::sync_with_stdio(false);

    cin.tie(nullptr);



    int n;

    cin >> n;

    for(int i = 0; i < n-1; ++i){

        int a, b;

        cin >> a >> b;

        --a, --b;

        if(a > b)   swap(a, b);

        edges.push_back(edge(a, b));

        graph[a].push_back(b);

        graph[b].push_back(a);

    }

    dfs(0);

    int cnt = 0;

    for(int i = 1; i < n; ++i){

        if(num_used[i]) ++cnt;

    }

    cout << cnt << "\n";

    for(int i = 0; i < n-1; ++i){

        cout << colors[edge(edges[i].u, edges[i].v)] << "\n";

    }

}

// Faster C++ solution for the same problem (measured speedup: 3.4654598907275473x):
#include <iostream>

#include <vector>

#include <algorithm>

#include <cmath>

#include <queue>

#include <string>

#include <map>

#include <set>

#include <stack>

#include <tuple>

#include <deque>

#include <numeric>

#include <bitset>

#include <iomanip>

#include <cassert>

#include <chrono>

#include <random>

#include <limits>

#include <iterator>

#include <functional>

#include <sstream>

#include <complex>

using namespace std;



typedef long long ll;

typedef uint64_t ull;

typedef pair<int, int> P;

constexpr double EPS = 1e-9;

constexpr int INF = 1001001001;

constexpr int mod = 1000000007;

// constexpr int mod = 998244353;



#define chmax(x, y) x = max(x, y)

#define chmin(x, y) x = min(x, y)



int main(){

    ios::sync_with_stdio(false);

    cin.tie(nullptr);



    int n;

    cin >> n;

    vector<P> es(n - 1);

    map<P, int> EdgeId;

    vector<vector<int>> graph(n);

    for(int i = 0; i < n - 1; ++i){

        int u, v;

        cin >> u >> v;

        --u, --v;

        P p = minmax(u, v);

        es[i] = p;

        EdgeId[p] = i;

        graph[u].emplace_back(v);

        graph[v].emplace_back(u);

    }

    int k = 0;

    for(int i = 0; i < n; ++i)  chmax(k, (int)graph[i].size());

    vector<int> ans(n - 1);

    queue<P> que;

    que.push(P(0, -1));

    vector<bool> used(n, false);

    while(!que.empty()){

        P p = que.front();

        que.pop();

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

        used[from] = true;

        int cur = 0;

        for(int to : graph[from]){

            if(used[to])    continue;

            if(cur == color)    ++cur;

            P edge = minmax(from, to);

            ans[EdgeId[edge]] = cur;

            que.push(P(to, cur));

            ++cur;

        }

    }

    cout << k << '\n';

    for(int i = 0; i < n - 1; ++i)  cout << ans[i] + 1 << '\n';

}