#include <bits/stdc++.h>
#define REP(i, n) for(int i = 0, i##_len = (n); i < i##_len; ++i)
#define REPS(i, _s, n) for(int i = _s, i##_len = (n); i < i##_len; ++i)
#define ALL(x) (x).begin(), (x).end()
using namespace std;

#define repi(itr, ds) for(auto itr = ds.begin(); itr != ds.end(); itr++)
// vector
template <typename T>
istream &operator>>(istream &is, vector<T> &vec) {
  for(T &x : vec) is >> x;
  return is;
}
// pair
template <typename T, typename U>
ostream &operator<<(ostream &os, pair<T, U> &pair_var) {
  os << "(" << pair_var.first << ", " << pair_var.second << ")";
  return os;
}
// vector
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "{";
  for(int i = 0; i < vec.size(); i++) {
    os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
  }
  os << "}\n   ";
  return os;
}
// map
template <typename T, typename U>
ostream &operator<<(ostream &os, map<T, U> &map_var) {
  os << "{";
  repi(itr, map_var) {
    os << *itr;
    itr++;
    if(itr != map_var.end()) os << ", ";
    itr--;
  }
  os << "}";
  return os;
}
// set
template <typename T>
ostream &operator<<(ostream &os, set<T> &set_var) {
  os << "{";
  repi(itr, set_var) {
    os << *itr;
    itr++;
    if(itr != set_var.end()) os << ", ";
    itr--;
  }
  os << "}";
  return os;
}

#define DUMPOUT cerr

void dump_func() { DUMPOUT << endl; }
template <class Head, class... Tail>
void dump_func(Head &&head, Tail &&... tail) {
  DUMPOUT << head;
  if(sizeof...(Tail) > 0) {
    DUMPOUT << ", ";
  }
  dump_func(std::move(tail)...);
}
#ifdef DEBUG_
#define DEB
#define dump(...)                                                             \
  DUMPOUT << "  " << string(#__VA_ARGS__) << ": "                             \
          << "[" << to_string(__LINE__) << ":" << __FUNCTION__ << "]" << endl \
          << "    ",                                                          \
      dump_func(__VA_ARGS__)
#else
#define DEB if(false)
#define dump(...)
#endif

typedef long long int ll;

int main() {
  int N;
  cin >> N;
  vector<vector<int>> graph = vector<vector<int>>(N, vector<int>());
  vector<pair<int, int>> queries = vector<pair<int, int>>();
  REP(i, N - 1) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    queries.push_back({a, b});
    graph[a].push_back(b);
    graph[b].push_back(a);
  }

  int color_cnt = 0;
  for(auto n : graph) {
    color_cnt = max((int)n.size(), color_cnt);
  }
  cout << color_cnt << endl;

  auto color = map<pair<int, int>, int>();
  auto q = queue<int>();
  auto parent_color_queue = queue<int>();
  auto visited = vector<bool>(N, false);
  auto used = vector<vector<int>>();
  q.push(0);
  parent_color_queue.push(-1);
  while(q.size() != 0) {
    int n = q.front();
    int parent_color = parent_color_queue.front();
    visited[n] = true;
    q.pop();
    parent_color_queue.pop();
    int c = 1;
    for(auto next : graph[n]) {
      if(!visited[next]) {
        q.push(next);
        int a;
        int b;
        if(next > n) {
          a = n;
          b = next;
        } else {
          a = next;
          b = n;
        }
        if(parent_color == c) {
          c++;
        }
        parent_color_queue.push(c);
        color.insert({{a, b}, c});
        // dump(a, b, c);
        c++;
      }
    }
  }

  for(auto query : queries) {
    cout << color[query] << endl;
  }
}


Measured memory_bytes: 13044