#include <bits/stdc++.h>
using namespace std;
struct Tree {
  struct Edge {
    long long dest, weight;
    Edge(long long _dest = -1, long long _weight = 1) {
      dest = _dest;
      weight = _weight;
    }
  };
  int root;
  vector<vector<Edge>> adj;
  int nodesCount;
  vector<int> parent;
  Tree(int _nodes = 0, int _root = 1) {
    nodesCount = _nodes;
    adj.resize(nodesCount + 1);
    parent.resize(nodesCount + 1, -1);
    root = 1;
  }
  void addEdgeDirected(int u, int v, int w = 1) {
    adj[u].push_back(Edge(v, w));
  }
  void addEdgeUndirected(int u, int v, int w = 1) {
    adj[u].push_back(Edge(v, w));
    adj[v].push_back(Edge(u, w));
  }
  vector<int> getSubtreeNodesCount() {
    vector<int> result(nodesCount + 1, -1);
    for (int i = 1; i <= nodesCount; i++) {
      if (result[i] == -1) {
        getSubtreeNodesCountRec(-1, i, result);
      }
    }
    return result;
  }
  long long getDiameter() { return getDiameterRec(-1, root).first; }
  vector<int> getParents() {
    stack<int> st;
    st.push(root);
    while (!st.empty()) {
      int cur = st.top();
      st.pop();
      for (auto it : adj[cur]) {
        if (it.dest == parent[cur]) continue;
        parent[it.dest] = cur;
        st.push(it.dest);
      }
    }
    return parent;
  }

 private:
  int getSubtreeNodesCountRec(int par, int cur,
                              vector<int> &subtreeNodesCount) {
    int mySize = 1;
    for (auto it : adj[cur]) {
      if (it.dest == par) continue;
      mySize += getSubtreeNodesCountRec(cur, it.dest, subtreeNodesCount);
    }
    return subtreeNodesCount[cur] = mySize;
  }
  pair<long long, long long> getDiameterRec(int par, int cur) {
    long long diam = 0;
    long long maxHeight[3] = {0, 0, 0};
    for (auto it : adj[cur]) {
      if (it.dest == par) continue;
      pair<long long, long long> subtreeDiam = getDiameterRec(cur, it.dest);
      diam = max(diam, subtreeDiam.first);
      maxHeight[0] = subtreeDiam.second + it.weight;
      sort(maxHeight, maxHeight + 3);
    }
    diam = max(diam, maxHeight[1] + maxHeight[2]);
    return {diam, maxHeight[2]};
  }
};
Tree tree;
set<int> ans;
vector<int> subtreeNodesCount;
int n;
void compute(int cur) {
  for (auto it : tree.adj[cur]) {
    if (it.dest != tree.parent[cur]) {
      compute(it.dest);
    }
  }
  bitset<5005> reachable = 1;
  int parentSize = n - 1;
  for (auto it : tree.adj[cur]) {
    if (it.dest != tree.parent[cur]) {
      reachable |= (reachable << subtreeNodesCount[it.dest]);
      parentSize -= subtreeNodesCount[it.dest];
    }
  }
  reachable |= (reachable << parentSize);
  for (int i = 1; i <= n - 2; i++) {
    if (reachable[i]) ans.insert(i);
  }
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0), cout.tie(0);
  cin >> n;
  tree = Tree(n);
  for (int i = 0; i < n - 1; i++) {
    int xi, yi;
    cin >> xi >> yi;
    tree.addEdgeUndirected(xi, yi);
  }
  tree.getParents();
  subtreeNodesCount = tree.getSubtreeNodesCount();
  compute(1);
  cout << ans.size() << "\n";
  for (auto it : ans) cout << it << " " << n - it - 1 << "\n";
}
