// Original C++ solution (slower):
/**

 * code generated by JHelper

 * More info: https://github.com/AlexeyDmitriev/JHelper

 * @author champon

 */



#include <iostream>

#include <fstream>



#include <bits/stdc++.h>

using namespace std;

#define ll long long

#define inf 9e18

#define ceill(a, b) (a+b-1)/b

#define ok cout << "ok" << endl;

#define sp << " " <<

ll mod = 1e9+7;

void ans(bool b, ostream& out=cout){ out << (b ? "Yes" : "No") << endl; }

void ans2(bool b, ostream& out=cout){ out << (b ? "YES" : "NO") << endl; }

template<typename T> inline bool chmax(T &a, T b){ if(a<b){a=b; return true;} return false; }

template<typename T> inline bool chmin(T &a, T b){ if(b<a){a=b; return true;} return false; }

template<typename A, size_t N, typename T> void Fill(A (&array)[N], const T &val){fill((T*)array, (T*)(array+N), val);}

int dx[] = {1, 0, -1, 0, 1, -1, 1, -1};

int dy[] = {0, 1, 0, -1, 1, -1, -1, 1};



#ifndef INCLUDE_DEBUG_HPP

#define INCLUDE_DEBUG_HPP



class debug

{

public:

    template<typename T> void vdeb(T vec);

    template<typename T1, typename T2> void adeb(T1 *arr, T2 n);

    template<typename T> void mdeb(T mp);

};



#endif //INCLUDE_DEBUG_HPP



template<typename T> void debug::vdeb(T vec)

{

    cout << "#vector set debug" << endl;

    for(auto vv : vec) cout << vv << " ";

    cout << endl;

}



template<typename T1, typename T2> void debug::adeb(T1 *arr, T2 n)

{

    cout << "#adebug" << endl;

    for(int i=0; i<=n; i++) cout << arr[i] << " ";

    cout << endl;

}



template<typename T> void debug::mdeb(T mp)

{

    cout << "#map pair debug" << endl;

    for(auto const& m : mp) cout << m.first sp m.second << endl;

}

debug dbg;



class DColoringEdgesOnTree {

public:

    vector<int> g[200010];

    int k = 0;

    int n;

    map<pair<int, int>, int> visit;

    map<pair<int, int>, int> res;



    void dfs(int u, int pu){

        int color = 1;

        for(auto e : g[u]){

            if(visit[make_pair(e, u)]) continue;

            visit[make_pair(e, u)] = 1;

            visit[make_pair(u, e)] = 1;



            if(color == res[make_pair(u, pu)]) color++;

            res[make_pair(e, u)] = color;

            res[make_pair(u, e)] = color;

            color++;

            dfs(e, u);

        }

    }



	void solve(std::istream& in, std::ostream& out)

	{

	    in >> n;

        vector<int> a(n), b(n);

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

            in >> a[i] >> b[i];

            a[i]--; b[i]--;

            g[a[i]].push_back(b[i]);

            g[b[i]].push_back(a[i]);

        }



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

            if(k < g[i].size()){

                k = g[i].size();

            }

        }



        out << k << endl;

        dfs(0, 0);

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

            out << res[make_pair(a[i], b[i])] << endl;

        }

	}

};





int main() {

	DColoringEdgesOnTree solver;

	std::istream& in(std::cin);

	std::ostream& out(std::cout);

	solver.solve(in, out);

	return 0;

}


// Optimized solution to the same problem (faster):
/**

 * code generated by JHelper

 * More info: https://github.com/AlexeyDmitriev/JHelper

 * @author champon

 */



#include <iostream>

#include <fstream>

//<editor-fold desc="definitions">

#include <bits/stdc++.h>

#define se cout << "test ok" << endl;

#define sp << " " <<

#define enl "\n"

using namespace std;

using ll=long long;

using ld=long double;

using vi = vector<int>;

using vii = vector<vector<int>>;

using viii = vector<vector<vector<int>>>;

using vl = vector<ll>;

using vll = vector<vector<ll>>;

using vlll = vector<vector<vector<ll>>>;

using vc = vector<char>;

using vcc = vector<vector<char>>;

using pi = pair<int, int>;

using pl = pair<ll, ll>;

ll mod = ll(1e9)+7;

ll inf = ll(1e18);

void bl(bool b, ostream& out=cout){ out << (b ? "Yes" : "No") << endl; }

void bl2(bool b, ostream& out=cout){ out << (b ? "YES" : "NO") << endl; }

template<typename T> inline bool chmax(T &a, T b){ if(a<b){a=b; return true;} return false; }

template<typename T> inline bool chmin(T &a, T b){ if(a>b){a=b; return true;} return false; }

int dx[] = {1, 0, -1, 0, 1, -1, 1, -1};

int dy[] = {0, 1, 0, -1, 1, -1, -1, 1};



#ifndef INCLUDE_DEBUG_HPP

#define INCLUDE_DEBUG_HPP



#define TO_STRING(varName) # varName

#include <iostream>

#include <vector>

#include <map>

using namespace std;



namespace dbg {

    using ll = long long;



    class Debug {

        void prefix(string s){

            cout << "\033[7m\033[35m" << " DEBUG " << "\033[0m\033[35m"

            << " " << s << "\033[0m" << endl;

        }

    public:

        Debug(){}

        // vector d1

        template<typename T>

        void print(vector<T> &vec);



        // vector tuple

        template<typename T1, typename T2>

        void print(vector<pair<T1, T2>>& vec, int idx = 0);



        // vector d2

        template<typename T>

        void print(vector<vector<T>>& vec);



        // vector d2

        template<typename T>

        void print(vector<vector<vector<T>>>& vec);



        // vector array d1

        template<typename T>

        void print(T *arr, ll n);



        // vector array d2

        template<typename T>

        void print(T *arr, int n, int m);



        // set

        template<typename T>

        void print(set<T>& st);



        // vector map or set

        template<typename T>

        void print(T cont);

    };



    template<typename T>

    void Debug::print(vector<T>& vec) {

        prefix("vector");

        for (auto& v : vec) cout << v << " ";

        cout << endl;

    }



    template<typename T1, typename T2>

    void Debug::print(vector<pair<T1, T2>>& vec, int idx) {

        prefix("vector pair");

        for (auto& v : vec) cout << (!idx ? get<0>(v) : get<1>(v)) << " ";

        cout << endl;

    }



    template<typename T>

    void Debug::print(vector<vector<T>>& vec) {

        prefix("vector d2");

        for (auto& vv : vec) {

            for (auto& v : vv) cout << v << " ";

            cout << endl;

        }

    }



    template<typename T>

    void Debug::print(vector<vector<vector<T>>>& vec) {

        prefix("vector d3");

        for(auto& vvv : vec) {

            cout << "[";

            for(int i=0; i<vvv.size(); i++) {

                if(i) cout << " ";

                for(int j=0; j<vvv[i].size(); j++) {

                    if(j) cout << " ";

                    cout << vvv[i][j];

                }

                if(i != vvv.size()-1) cout << endl;

            }

            cout << "]" << endl;

        }

    }



    template<typename T>

    void Debug::print(T *arr, ll n) {

        prefix("array");

        for (int i = 0; i < n; i++) cout << arr[i] << " ";

        cout << endl;

    }



    template<typename T>

    void Debug::print(T *arr, int n, int m) {

        prefix("array d2");

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

            for (int j = 0; j < m; j++) {

                cout << arr[i][j] << " ";

            }

            cout << endl;

        }

    }



    template<typename T>

    void Debug::print(set<T>& st) {

        prefix("set");

        for(auto& e : st) cout << e << " ";

        cout << endl;

    }



    template<typename T>

    void Debug::print(T cont) {

        prefix("key value");

        for (auto& e : cont)

            cout << e.first << " : " << e.second << endl;

        cout << endl;

    }



}



#endif //INCLUDE_DEBUG_HPP



dbg::Debug debug;

//</editor-fold>



class DColoringEdgesOnTree {

public:

    vii g;

    vi res;

    map<pi, int> mp;



    void dfs(int u, int p) {

        int c = 1;

        for(auto& to : g[u]){

            if(p != -1 && c == res[mp[make_pair(u, p)]]) c++;

            if(to == p) continue;

            res[mp[make_pair(u, to)]] = c;

            dfs(to, u);

            c++;

        }

    }



	void solve(std::istream& in, std::ostream& out) {

	    int n;

	    in >> n;

	    g = vii(n);

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

	        int a, b;

	        in >> a >> b;

	        --a; --b;

	        g[a].push_back(b);

	        g[b].push_back(a);

	        mp[make_pair(a, b)] = mp[make_pair(b, a)] = i;

	    }



        res = vi(n-1);

        dfs(0, -1);



        out << *max_element(res.begin(), res.end()) << enl;

        for(int i=0; i<n-1; i++) out << res[i] << enl;

	}

};





int main() {

    cin.tie(nullptr);

    ios_base::sync_with_stdio(false);

	DColoringEdgesOnTree solver;

	std::istream& in(std::cin);

	std::ostream& out(std::cout);

	solver.solve(in, out);

	return 0;

}


// Fastest known solution for this problem: