#include<set>
#include<iostream>
#include<algorithm>
#define min _MIN
using namespace std;
class TheBrickTowerEasyDivTwo{
public:
//很巧妙的方法
int find(int n,int red,int m,int blue){
if(n>m)
swap(n,m);
cout<<"n="<<n<<"m="<<m<<endl;
if(red==blue)
return n+min(m,n+1);
else
return n+min(n,m+1)+min(m,n+1);
}
};
#include<set>
#include<iostream>
#include<algorithm>
#define min _MIN
using namespace std;
class TheBrickTowerEasyDivTwo{
public:
int find(int n,int red,int m,int blue){
int temp[5000];
int max=0;
int height=0;
if(n) temp[red]=1;
if(m) temp[blue]=1;
for(int i=1,j=1;i<=n;i++)
{
height+=red;
temp[height]=1;
if(j++<blue){
height+=blue;
temp[height]=1;
}
else break;
}
if(max<height)
max=height;
height=0;
for(int r=1,t=1;r<=m;r++){
height+=blue;
temp[height]=1;
if(t++<red){
height+=red;
temp[height]=1;
}
else break;
}
if(max<height)
max=height;
int cnt=0;
for(int s=1;s<=max;s++)
if(temp[s])
cnt++;
return cnt;
}
};
#include<set>
#include<iostream>
#include<algorithm>
#define min _MIN
using namespace std;
class TheBrickTowerEasyDivTwo{
public:
int find(int n,int red,int m,int blue){
set<int> s;
for(int i=0;i<=n;i++)
for(int j=0;j<=m;j++){
if(abs(i-j)<=1&&(i||j)){
s.insert(i*red+j*blue);
}
}
return s.size();
}
};
#include<map>
#define max _MAX
#define min _MIN
using namespace std;
class TheBrickTowerMediumDivTwo{
public:
vector <int> find(vector <int> heights){
int ans=1e9;
vector<int>v;
vector<int>vc;
for(int i=0;i<heights.size();i++)
v.push_back(i);
do{
int res=0;
for(int i=0;i<heights.size()-1;i++)
res+=max(heights[v[i]],heights[v[i+1]]);
if(res<ans){
ans=res;
vc=v;
}
}while(next_permutation(v.begin(),v.end()));
return vc;
}
};
#include<map>
#define max _MAX
#define min _MIN
using namespace std;
class TheBrickTowerMediumDivTwo{
public:
vector <int> find(vector <int> heights){
map<int,vector<int> >mp;
int n=heights.size();
vector<int> res;
for(int i=0;i<n;i++){
mp[heights[i]].push_back(i);
}
for(map<int,vector<int> >::const_iterator it=mp.begin();it!=mp.end();it++){
vector<int>v1=it->second;
vector<int>temp1=res;
temp1.insert(temp1.end(),v1.begin(),v1.end());
for(int i=0;i<(int)v1.size();i++){
vector<int>temp2=res;
temp2.insert(temp2.begin(),v1.begin(),v1.begin()+i);
temp2.insert(temp2.end(),v1.begin()+i,v1.end());
temp1=min(temp1,temp2);
}
res=temp1;
}
return res;
}
};
#include<iostream>
using namespace std;
//typedef long ll;
typedef long long ll;
const ll MOD=1234567891;
class TheBrickTowerHardDivTwo{
public:
int find(int C, int K, int H){
//Dynamic Programming
ll f[5][5][5][5][8][48];
memset(f,0,sizeof(f));
for(int h=0;h<H;h++){
for(int a=0;a<C;a++)
for(int b=0;b<C;b++)
for(int c=0;c<C;c++)
for(int d=0;d<C;d++){
int ak=0;
if(a==b) ak++;
if(b==c) ak++;
if(c==d) ak++;
if(a==d) ak++;
if(ak<=K){
if(h==0){
f[a][b][c][d][ak][h]=1;
}
else{
for(int la=0;la<C;la++)
for(int lb=0;lb<C;lb++)
for(int lc=0;lc<C;lc++)
for(int ld=0;ld<C;ld++){
int bk=0;
if(la==lb) bk++;
if(lb==lc) bk++;
if(lc==ld) bk++;
if(la==ld) bk++;
if(ak+bk<=K){
int ck=0;
if(la==a) ck++;
if(lb==b) ck++;
if(lc==c) ck++;
if(ld==d) ck++;
if(ak+bk+ck<=K){
int dk=K-ak-bk-ck;
for(int i=0;i<=dk;i++){
f[a][b][c][d][ak+bk+ck+i][h]+=f[la][lb][lc][ld][bk+i][h-1];
f[a][b][c][d][ak+bk+ck+i][h]%=MOD;
}
}
}
}
}
}
}
}
ll ans=0;
for(int k=0;k<=K;k++)
for(int h=0;h<H;h++)
for(int a=0;a<C;a++)
for(int b=0;b<C;b++)
for(int c=0;c<C;c++)
for(int d=0;d<C;d++){
ans+=f[a][b][c][d][k][h];
ans%=MOD;
}
return (int)ans;
}
};
#include<iostream>
using namespace std;
//typedef long ll;
typedef long long ll;
const ll MOD=1234567891;
class TheBrickTowerHardDivTwo{
public:
//递归
ll call(int height,int color,int a,int b,int c,int d,int C){
if(height==0)
return 1;
if(color<0)
return 0;
ll &res=f[a][b][c][d][color][height];
if(res>0)
return res;
int cnt=0;
for(int i=0;i<C;i++)
for(int j=0;j<C;j++)
for(int k=0;k<C;k++)
for(int l=0;l<C;l++){
cnt=0;
if(i==j) cnt++;
if(j==k) cnt++;
if(k==l) cnt++;
if(l==i) cnt++;
if(i==a) cnt++;
if(j==b) cnt++;
if(k==c) cnt++;
if(l==d) cnt++;
res=(res%MOD+call(height-1,color-cnt;i,j,k,l)%MOD)%MOD;
}
return res;
}
int find(int C, int K, int H){
ll ans=0;
for(int h=1;h<=H;h++){
ans=(ans%MOD+call(H,K,0,0,0,0,C))%MOD;
}
return ans;
}
};