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

using namespace std;



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

#define ALL(a) (a).begin(), (a).end()

#define SZ(x) ((int)(x).size())



template <class T>inline bool chmin(T &a, const T b)

{

  if (a > b)

  {

    a = b;

    return true;

  }

  return false;

}

template <class T>inline bool chmax(T &a, const T b)

{

  if (a < b)

  {

    a = b;

    return true;

  }

  return false;

}



using ll = long long;

using ld = long double;

using P = pair<int, int>;

using DoP = pair<double, double>;



const int di[] = {0, 1, 0, -1, 1, 1, -1, -1};

const int dj[] = {1, 0, -1, 0, 1, -1, 1, -1};

const int INF = 1 << 29;

const ll INF64 = 1ll << 45;

const int mod = 1000000007;

//const int mod = 10007;



struct mint

{

  ll x; // typedef long long ll;

  mint(ll x = 0) : x((x % mod + mod) % mod) {}

  mint operator-() const { return mint(-x); }

  mint &operator+=(const mint a)

  {

    if ((x += a.x) >= mod)

      x -= mod;

    return *this;

  }

  mint &operator-=(const mint a)

  {

    if ((x += mod - a.x) >= mod)

      x -= mod;

    return *this;

  }

  mint &operator*=(const mint a)

  {

    (x *= a.x) %= mod;

    return *this;

  }

  mint operator+(const mint a) const

  {

    mint res(*this);

    return res += a;

  }

  mint operator-(const mint a) const

  {

    mint res(*this);

    return res -= a;

  }

  mint operator*(const mint a) const

  {

    mint res(*this);

    return res *= a;

  }

  mint pow(ll t) const

  {

    if (!t)

      return 1;

    mint a = pow(t >> 1);

    a *= a;

    if (t & 1)

      a *= *this;

    return a;

  }



  // for prime mod

  mint inv() const

  {

    return pow(mod - 2);

  }

  mint &operator/=(const mint a)

  {

    return (*this) *= a.inv();

  }

  mint operator/(const mint a) const

  {

    mint res(*this);

    return res /= a;

  }

};

struct edge {int to; int index;};



vector<vector<edge>> e(100001);

vector<int> ans(100000);

int n, k = 0;



void dfs(int now, int par, int pre_c) {

  int c = 1;

  for(auto next : e[now]) {

    if(next.to == par) continue;

    if(c == pre_c) ++c;

    ans[next.index] = c;

    dfs(next.to, now, c);

    ++c;

  }

}



int main()

{

  cin >> n;

  rep(i, n-1) {

    int a, b; cin >> a >> b;

    edge x = {b, i};

    edge y = {a, i};

    e[a].push_back(x);

    e[b].push_back(y);

  }

  for(int i = 1; i <= n; ++i) chmax(k, SZ(e[i]));

  dfs(1, 0, 0);

  cout << k << endl;

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

}

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

using namespace std;



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

#define ALL(a) (a).begin(), (a).end()

#define rALL(a) (a).rbegin(), (a).rend()

#define SZ(x) ((int)(x).size())

using ll = long long;

using ull = unsigned long long;

using P = pair<int, int>;

using llP = pair<ll, ll>;

using DoP = pair<double, double>;

const int di[] = {0, 1, 0, -1, 1, 1, -1, -1};

const int dj[] = {1, 0, -1, 0, 1, -1, 1, -1};

const int INF = 1 << 28;

const ll INF64 = 1ll << 55;

const int mod = 1000000007;

//const int mod = 998244353;



template <class T>inline bool chmin(T &a, const T b)

{

  if (a > b)

  {

    a = b;

    return true;

  }

  return false;

}

template <class T>inline bool chmax(T &a, const T b)

{

  if (a < b)

  {

    a = b;

    return true;

  }

  return false;

}

template <class T>inline void line_out(const vector<T> vec) {

  int n = SZ(vec);

  rep(i, n) {

    cout << vec[i];

    if(i < n-1) cout << " ";

  }

  cout << endl;

  return;

}



struct mint

{

  ll x; // typedef long long ll;

  mint(ll x = 0) : x((x % mod + mod) % mod) {}

  mint operator-() const { return mint(-x); }

  mint &operator+=(const mint a)

  {

    if ((x += a.x) >= mod)

      x -= mod;

    return *this;

  }

  mint &operator-=(const mint a)

  {

    if ((x += mod - a.x) >= mod)

      x -= mod;

    return *this;

  }

  mint &operator*=(const mint a)

  {

    (x *= a.x) %= mod;

    return *this;

  }

  mint operator+(const mint a) const

  {

    mint res(*this);

    return res += a;

  }

  mint operator-(const mint a) const

  {

    mint res(*this);

    return res -= a;

  }

  mint &operator++()

  {

    if ((x += 1) >= mod)

      x -= mod;

    return *this;

  }

  mint &operator--()

  {

    if ((x += mod - 1) >= mod)

      x -= mod;

    return *this;

  }

  mint operator*(const mint a) const

  {

    mint res(*this);

    return res *= a;

  }

  mint pow(ll t) const

  {

    if (!t)

      return 1;

    mint a = pow(t >> 1);

    a *= a;

    if (t & 1)

      a *= *this;

    return a;

  }



  // for prime mod

  mint inv() const

  {

    return pow(mod - 2);

  }

  mint &operator/=(const mint a)

  {

    return (*this) *= a.inv();

  }

  mint operator/(const mint a) const

  {

    mint res(*this);

    return res /= a;

  }

};

struct edge {int to; int index;};



vector<vector<edge>> g(100000+1);

int c = 0;

vector<int> ans;



void dfs(int now = 1, int par_c = 0, int par = 0) {

  int cc = 1;

  for(auto next : g[now]) {

    if(next.to == par) continue;

    if(cc == par_c) ++cc;

    ans[next.index] = cc;

    dfs(next.to, cc, now);

    ++cc;

  }

}



int main()

{

  int n; cin >> n;

  ans.resize(n-1);

  rep(i, n-1) {

    int a, b; cin >> a >> b;

    edge x = {b, i};

    edge y = {a, i};

    g[a].push_back(x);

    g[b].push_back(y);

  }

  for(int i = 1; i <= n; ++i) chmax(c, SZ(g[i]));



  dfs();

  cout << c << endl;

  for(auto x : ans) cout << x << endl;

}