#include <iostream>
#include <fstream>
#include <deque>
using namespace std;
const int nmax=75005;
int d[nmax];
int dp[2][nmax],f1[nmax],f2[nmax];
int ap[205],opt[205];
int lim=200005;
int use,n,G,i,ans,x,j,p,u;
void recu(int lin,int cat)
{
for(int rest=0; rest<min(lin,cat+1); rest++)
{
p=1;u=0;
for(int i=rest; i<=cat; i+=lin)
{
if(p<=u&&i-d[p]>lin*ap[lin])
p++;
while(p<=u&&dp[1-use][i]-(i-rest)/lin<=dp[1-use][d[u]]-(d[u]-rest)/lin)
u--;
d[++u]=i;
dp[use][i]=(i-d[p])/lin+dp[1-use][d[p]];
}
}
use=1-use;
}
void get_best(int l,int r,int cat)
{
for(int i=0;i<=cat;i++)
dp[0][i]=lim;
dp[0][0]=0;
use=1;
for(int lin=l;lin<=r;lin++)
recu(lin,cat);
for(int i=0;i<=cat;i++)
f1[i]=dp[1-use][i];
}
void get_best_rev(int l,int r,int cat)
{
for(int i=0;i<=cat;i++)
dp[0][i]=lim;
dp[0][0]=0;
use=1;
for(int lin=r;lin>=l;lin--)
recu(lin,cat);
for(int i=0;i<=cat;i++)
f2[i]=dp[1-use][i];
}
void divide(int l,int r,int ost,int odr,int expected)
{
int m=(l+r)/2;
if(l>r)
return;
if(l==r)
{
opt[m]=odr;
return;
}
get_best(l,m,odr-ost);
get_best_rev(m+1,r,odr-ost);
for(int i=0;i<=odr-ost;i++)
{
if(f1[i]+f2[odr-ost-i]==expected)
opt[m]=i+ost;
}
int v1=f1[opt[m]-ost],v2=f2[odr-opt[m]];
divide(l,m,ost,opt[m],v1);
divide(m+1,r,opt[m],odr,v2);
}
int main()
{
ifstream f("ghiozdan.in");
ofstream g("ghiozdan.out");
f>>n>>G;
for(i=1;i<=n;i++)
{
f>>x;
ap[x]+=1;
}
get_best(1,200,G);
for(i=0;i<=G;i++)
if(dp[1-use][i]<=n)
ans=i;
g<<ans<<' '<<dp[1-use][ans]<<'\n';
divide(1,200,0,ans,dp[1-use][ans]);
for(i=1;i<=200;i++)
for(j=opt[i-1]+i;j<=opt[i];j+=i)
g<<i<<'\n';
return 0;
}