void main() {
  problem();
}

class Node {
  static int size;
  static Node[int] all;
  static Node at(int n) { return all[n]; }

  int number;
  Node[] others = [];

  this(int number) {
    this.number = number;
    all[number] = this;
    size++;
  }

  void connect(Node other) {
    other.others ~= this;
    this.others ~= other;
    deb(this);
  }

  int minimumDistanceTo(Node goal) {
    int dfs(Node current, int walked, Node prev, Node preprev) {
      if (walked >= size) return int.max;
      if (current == goal) {
        return walked;
      }
      walked++;

      auto candidates = current.others.map!(x => x == prev || x == preprev ? int.max : dfs(x, walked, current, prev));
      int min = int.max; foreach(m; candidates) if (min > m) min = m;
      return min;
    }

    return dfs(this, 0, null, null);
  }
}

void problem() {
  const N = scan!int;
  const X = scan!int;
  const Y = scan!int;

  foreach(i; 1..N+1) {
    new Node(i);
    if (i > 1) Node.at(i-1).connect(Node.at(i));
  }
  Node.at(X).connect(Node.at(Y));

  void solve() {
    int[int] counts;

    foreach(i; 1..N) {
      foreach(j; i+1..N+1) {
        counts[Node.at(i).minimumDistanceTo(Node.at(j))]++;
      }
    }
    
    foreach(i; 1..N) {
      writeln(i in counts ? counts[i] : 0);
    }
  }

  solve();
}

// ----------------------------------------------

import std.stdio, std.conv, std.array, std.string, std.algorithm, std.container, std.range, core.stdc.stdlib, std.math, std.typecons;
T[][] combinations(T)(T[] s, in int m) {   if (!m) return [[]];   if (s.empty) return [];   return s[1 .. $].combinations(m - 1).map!(x => s[0] ~ x).array ~ s[1 .. $].combinations(m); }
string scan(){ static string[] ss; while(!ss.length) ss = readln.chomp.split; string res = ss[0]; ss.popFront; return res; }
T scan(T)(){ return scan.to!T; }
T[] scan(T)(int n){ return n.iota.map!(i => scan!T()).array; }
void deb(T ...)(T t){ debug writeln(t); }
alias Point = Tuple!(long, "x", long, "y");

// -----------------------------------------------
