#include<bits/stdc++.h>
using namespace std;

//----------------------------------------------------------------------------------------------------------------------
typedef signed long long ll;

#define FOR(x,to) for(x=0;x<(to);x++)
#define FORR(x,arr) for(auto& x:arr)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ALL(a) (a.begin()),(a.end())
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------
template<class T,class U>
ostream& operator<<(ostream& os,const pair<T,U>& p){
    os<<"("<<p.first<<": "<<p.second<<")";
    return os;
}

template<class T>
ostream& operator <<(ostream& os,const vector<T>& v){
    os<<"{";
    for(int i = 0;i < (int)v.size(); i++){
        if(i)os<<", ";
        os<<v[i];
    }
    os<<"}";
    return os;
}


//#define TRACE

#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
    cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
    const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif
//----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------

void solve()
{
    
}

void colorEdges(int ptr, vector<vector<pair<int, int> > >& gra,
                vector<int>& edgeColors, bool isVisited[])
{
    queue<int> q;
    int c = 0;

    set<int> colored;

    // return if isVisited[ptr] is true
    if (isVisited[ptr])
        return;

    // Mark the current node visited
    isVisited[ptr] = 1;

    // Traverse all edges of current vertex
    for (int i = 0; i < gra[ptr].size(); i++) {
        // if already colored, insert it into the set
        if (edgeColors[gra[ptr][i].second] != -1)
            colored.insert(edgeColors[gra[ptr][i].second]);
    }

    for (int i = 0; i < gra[ptr].size(); i++) {
        // if not visited, inset into the queue
        if (!isVisited[gra[ptr][i].first])
            q.push(gra[ptr][i].first);

        if (edgeColors[gra[ptr][i].second] == -1) {
            // if col vector -> negative
            while (colored.find(c) != colored.end())

                // increment the color
                c++;

            // copy it in the vector
            edgeColors[gra[ptr][i].second] = c;

            // then add it to the set
            colored.insert(c);
            c++;
        }
    }

    // while queue's not empty
    while (!q.empty()) {
        int temp = q.front();
        q.pop();

        colorEdges(temp, gra, edgeColors, isVisited);
    }

    return;
}

int main()
{
    set<int> empty;

    // declaring vector of vector of pairs, to define Graph
    vector<vector<pair<int, int> > > gra;

    vector<int> edgeColors;

    bool isVisited[100009] = { 0 };

    // Enter the Number of Vertices
    // and the number of edges
    int ver = 4;
    int edge = 4;
    cin >> ver;
    edge = ver-1;

    gra.resize(ver);
    edgeColors.resize(edge, -1);

    // Enter edge & vertices of edge
    // x--; y--;
    // Since graph is undirected, push both pairs
    // (x, y) and (y, x)
    // graph[x].push_back(make_pair(y, i));
    // graph[y].push_back(make_pair(x, i));
    long x, y;
    for (long i = 0; i< edge; i++)
    {
        cin >> x >> y;
        gra[x-1].push_back(make_pair(y-1, i));
        gra[y-1].push_back(make_pair(x-1, i));
    }


    colorEdges(0, gra, edgeColors, isVisited);
    int ans= -1;
    // printing all the edge colors
    for (int i = 0; i < edge; i++)
        ans = max(ans, edgeColors[i] + 1);
    cout << ans<<'\n';
    for (int i = 0; i< edge; i++)
        cout << edgeColors[i] + 1 << '\n';
    return 0;
}

Measured memory_bytes: 60416