// Slower C++ solution:
//nani?

//omo ta tori da

#include<bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp> // Common file

#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update

#include <ext/pb_ds/detail/standard_policies.hpp>

#define pi acos(-1);

#define fs first

#define sc second

#define pb push_back

#define mp make_pair

#define f(i,a,b) for( int i = a; i < b ; i++ )

#define sor(a) sort( a.begin(), a.end() )

#define rsor(a) sort( a.rbegin(), a.rend() )

#define fastio ios_base::sync_with_stdio(0);cin.tie(0)

#define inf 1LL<<62

typedef long long ll;

typedef double ld;

using namespace std;

using namespace __gnu_pbds;

//const ll inf=1e10;

const ll MOD=1e9+7;

const ll mod=998244353;

const ll N = 1e7 + 5;

// ac cmtr;

const int MAX_N = 2e5+5;

typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>ordered_set;

 

#define TRACE

#ifdef TRACE

#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)

template <typename Arg1>

void __f(const char* name, Arg1&& arg1) {

  cout << name << " : " << arg1 << endl;}

 

template <typename Arg1, typename... Args>

void __f(const char* names, Arg1&& arg1, Args&&... args) {

  const char* comma = strchr(names + 1, ',');

  cout.write(names, comma - names) << " : " << arg1<<" | ";

  __f(comma+1, args...);}

#else

#define trace(...)

#endif

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



ll dp[2005][2005];

ll cnt[MAX_N];

ll n;

vector <pair <ll,ll > > adj[MAX_N];



void dij(ll a){



    set <pair <ll,ll> > s;

    f(i,0,n+1) {dp[i][a]=inf;}

    s.insert(mp(0,a));

    dp[a][a] = 0;

    //ans[a] = 1;

    while(!s.empty()){

        ll ini  = s.begin()->sc;s.erase(s.begin());

        for(auto xd : adj[ini]){

            if(dp[xd.fs][a] > dp[ini][a] + xd.sc){

                s.erase(mp(dp[xd.fs][a],xd.fs)); 

                //ans[xd.fs] = ans[ini];

                dp[xd.fs][a] = dp[ini][a] + xd.sc;

                s.insert(mp(dp[xd.fs][a],xd.fs));

            }

        }

        

    }

  return;

}



int main(){

    fastio;

    ll x,y;

    cin>>n>>x>>y;

    f(i,1,n){

        adj[i].pb({i+1,1});

        adj[i+1].pb({i,1});

    }

    adj[x].pb({y,1});

    adj[y].pb({x,1});

    f(i,1,n+1){

        dij(i);

    }

    f(i,1,n+1){

        for(int j=1;j<=n;j++){

            cnt[dp[i][j]]++;

        }

    }

    f(i,1,n){

        cout<<cnt[i]/2<<" "<<endl;

    }





   

}

// Faster C++ solution for the same problem (measured speedup: 6.071653232432791x):
//#pragma GCC         optimize("O3")

#include            <bits/stdc++.h>

#include            <ext/pb_ds/assoc_container.hpp>

#include            <ext/pb_ds/tree_policy.hpp>

#define FastIO      ios_base::sync_with_stdio(0);cin.tie(0),cout.tie(0)

#define pb          push_back

#define mp          make_pair

#define mem(x,i)    memset(x,i,sizeof(x))

#define ff          first

#define ss          second

#define popcount(x) __builtin_popcount(x)

#define all(x)      x.begin(),x.end()

#define Case(t)     for(int ks=1;ks<=t;ks++)

#define fileout     freopen("output.txt","w",stdout)

#define filein      freopen("input.txt","r",stdin)

#define D(x)        cerr<< __LINE__ <<": "<< #x << " = "<<(x) <<'\n';

#define endl        '\n'



using namespace std;

using namespace __gnu_pbds;



using ll  = long long;

using ld  = long double;

using ull = unsigned long long;

using pii = pair<int,int>;

using pll = pair<ll,ll>;

using pil = pair<int,ll>;



const int INF    = 0x3f3f3f3f;

const ll LL_INF  = 0x3f3f3f3f3f3f3f3f;

const double PI  = acos(-1);

const double eps = 1e-4;

const int mod    = 1e9+7;

const int mx     = 2e3+5;

template <typename T>  using orderedSet =

    tree<T, null_type, less_equal<T>,

    rb_tree_tag, tree_order_statistics_node_update>;//find_by_order,order_of_key*/



/*------------------------------Graph Moves----------------------------*/

//const int fx[]= {+1,-1,+0,+0};

//const int fy[]= {+0,+0,+1,-1};

//const int fx[]={+0,+0,+1,-1,-1,+1,-1,+1};   // Kings Move

//const int fy[]={-1,+1,+0,+0,+1,+1,-1,-1};  // Kings Move

//const int fx[]={-2, -2, -1, -1,  1,  1,  2,  2};  // Knights Move

//const int fy[]={-1,  1, -2,  2, -2,  2, -1,  1}; // Knights Move

/*---------------------------------------------------------------------*/



//ll powmod(ll a,ll b){ll res=1;a%=mod;assert(b>=0);for(; b; b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}

/*----------------------BitMask-----------------------------------------*/

//inline int setBit(int N,int pos){return N=N | (1<<pos);}

//inline int resetBit(int N,int pos){return N= N & ~(1<<pos);}

//inline bool checkBit(int N,int pos){return (bool) (N& (1<<pos));}

int ans[mx];

bool vis[mx];

int dis[mx];

vector<int>adj[mx];

void bfs(int src)

{

    queue<int>q;

    q.push(src);

    vis[src]=1;

    while(!q.empty())

    {

        int u=q.front();

        q.pop();

        for(int v: adj[u])

        {

            if(!vis[v])

            {

                vis[v]=1;

                dis[v]=dis[u]+1;

                ans[dis[v]]++;

                q.push(v);

               // cout<<u<<' '<<v<<' '<<dis[v]<<endl;

            }

        }

    }

}

int main()

{

    int n,x,y;

    cin>>n>>x>>y;

    for(int i=1;i<n;i++) adj[i].pb(i+1),adj[i+1].pb(i);

    adj[x].pb(y);

    adj[y].pb(x);

    for(int i=1;i<=n;i++)

    {

        mem(vis,0);

        mem(dis,0);

        bfs(i);

    }

    for(int i=1;i<n;i++) cout<<ans[i]/2<<endl;

}