#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<fstream>
#include<map>
#include<ctime>
#include<set>
#include<queue>
#include<cmath>
#include<vector>
#include<bitset>
#include<functional>
#define x first
#define y second
#define mp make_pair
#define pb push_back
#define REP(i,l,r) for((i)=(l);(i)<=(r);++(i))
#define REP2(i,l,r) for((i)=(l);(i)!=(r);++(i))
using namespace std;
typedef long long LL;
typedef double ld;
const int NUM=9;
const int NUMM=22;
const int NUMK=20;
const int P[]={1,1<<2,1<<4,1<<6,1<<8,1<<10,1<<12,1<<14,1<<16,1<<18};
int n,m,K;
char g[NUMM][NUMM];
inline int get(int a,int k)
{
return a/P[k]%4;
}
inline int revise(int a,int k,int d)
{
return a-get(a,k)*P[k]+d*P[k];
}
int ma[ 1<<16 ][NUM];
int hash[1<<16];//判断状态合法
void update(int& a,int p)//更新
{
if(p>0 && ( a==0 || p>a ) )
a=p;
}
void show(int a)//显示状态
{
int i;
REP2(i,0,n+1)
cout<<get(a,i);
cout<<endl;
}
int change(string a)//将字符串变成数
{
int ans=0;
for(int i=n;i>=0;--i)
ans=ans*4+a[i]-'0';
return ans;
}
void pre()//事先计算出所有可能的状态
{
int i,j;
int st[NUM],top;
REP2(i,0,P[n+1])
{
int num=0;
int flag=1;
top=0;
REP2(j,0,n+1)
{
int p=get(i,j);
if(p==3)
++num;
else if(p==0)
;
else if(p==2)
{
if(top<=0)
{
flag=0;
break;
}
ma[i][j]=st[--top];
ma[i][ma[i][j]]=j;
}
else st[top++]=j;
}
if(flag && num<=2 && top==0)
hash[i]=1;
}
}
vector< pair<int,int> > zhuanyi(int i,int j,int oldp,int house,int is)//看拼音知程序
{
//并没有考虑地图,仅仅返回所有的转移
//Oh No,这道题目比较神,必须保证若两个格子相连,那么这两个点之间必须连边。。。
//你只能在S或者T产生两条独立路径或者将路径封闭 用is表示
//要求独立插头在端点产生,且端点必须有独立插头
int p=oldp,np;
int p1=get(p,j-1);
int p2=get(p,j);
p=revise(p,j-1,0);
p=revise(p,j,0);
vector< pair<int,int> > ans;
int left=j>=2?get(house,j-2):3;
int up=get(house,j);
if( ( left==0 && !p1 ) || (up==0 && !p2))//有格子但不相连,否决
{
if(!p1 && !p2)//如果本身不填还是没事的
ans.pb(mp(p,0));
return ans;
}
if(p1==0 && p2==0)
{
//新增左右匹配的插头
np=revise(p,j-1,1);
np=revise(np,j,2);
if(!is)
ans.pb(mp(np,1));
//跳过
np=p;
if(!is)
ans.pb(mp(np,0));
//新增独立向下的独立插头
np=revise(p,j-1,3);
if(is)
ans.pb(mp(np,1));
//新增独立向右的独立插头
np=revise(p,j,3);
if(is)
ans.pb(mp(np,1));
}
else if(p1!=3 && p2!=3)
{
if(p1 && p2)//不可能有独立插头
{
if(p1==p2 && !is)//只能连起来
{
if(p1==2)
{
np=revise(p,ma[oldp][j-1],2);
ans.pb(mp(np,1));
}
else if(p1==1)
{
np=revise(p,ma[oldp][j],1);
ans.pb(mp(np,1));
}
}
else if(p1==2 && p2==1 && !is)//可以连起来
{
np=p;
ans.pb(mp(np,1));
}
else //1,2的话,那么就形成了回路,题目求的是路径,故否决
{
;
}
}
else
{
int u=p1?p1:p2;//两种情况似乎可以合并
//上面有东西,作为傻叉,我可以将其继续
//往下连
np=revise(p,j-1,u);
if(!is)
ans.pb(mp(np,1));
//拐了个弯
np=revise(p,j,u);
if(!is)
ans.pb(mp(np,1));
//封住
if(p2 && is)//往下的封住了
{
np=revise(p,ma[oldp][j],3);//相连的那个成了可怜的独立插头
ans.pb(mp(np,1));
}
else if(p1 && is)
{
np=revise(p,ma[oldp][j-1],3);//同上
ans.pb(mp(np,1));
}
}
}
else //现在肯定有了个独立插头,yy开始
{
if(p1==3 && p2==3 && !is)//两个独立插头,如果连起来的话就结束算法,找到答案。
{
if(!p)
ans.pb(mp(p,1));
}
else if(!p1 || !p2)//只有一个独立插头
{
//首先似乎可以更新答案
if(!p && is)//封住了
ans.pb(mp(p,1));
//然后可以往下或往右拓展
//往下连
np=revise(p,j-1,3);
if(!is)ans.pb(mp(np,1));
//拐了个弯
np=revise(p,j,3);
if(!is)ans.pb(mp(np,1));
}
else //另一个插头会与独立插头相连,于是修改另一边为独立插头
{
if(p1==3 && !is)
{
np=revise(p,ma[oldp][j],3);
ans.pb(mp(np,1));
}
else if(p2==3 && !is)
{
np=revise(p,ma[oldp][j-1],3);
ans.pb(mp(np,1));
}
}
}
return ans;
}
/*
x,y
y y+1 y+2
y-2 y-1
*/
pair<int,int> getHouse(int x,int y,int old,int what)//更新炮台安放
{
//x,y 格子从1开始标号
//what 0 路线 1 炮台 2 障碍
int num[4]={0,0,0,0};
if(y>1)
{
++num[get(old,y-2)];
++num[get(old,y-1)];
}
++num[get(old,y)];
if(y+1<=n)
++num[get(old,y+1)];
int w=what<2 ? num[!what] : 0;
/*
cout<<x<<" "<<y<<" "<<what<<endl;
show(old);
show(revise(old,y-1,what));
cout<<endl;
*/
return mp(revise(old,y-1,what),w);
}
map< pair<int,int> ,int > G[NUMK],F[NUMK];
int answer=-100000000;
int find(int x)
{
int i;
REP2(i,0,n+1)
if(get(x,i)==0)
return 1;
return 0;
}
void work(int x,int y)
{
char p='#';
if(y)
p=g[x-1][y-1];
map< pair<int,int> ,int >::iterator it;
int i,j,k;
REP(k,0,K)
{
G[k]=F[k];
F[k].clear();
}
int pp=0;
REP2(i,0,n+1)
pp=pp*4+2;
if(p!='S' && p!='T')F[0][mp(0,pp)]=1;
REP(k,0,K)
REP2(it,G[k].begin(),G[k].end())
{
if(!y)
{
if(get(it->x.x,n)==0)
update(F[k][mp(it->x.x*4,revise(it->x.y*4+2,n+1,0))],it->y);
continue;
}
vector< pair<int,int > > ans=zhuanyi(x,y,it->x.x,it->x.y,p=='S' || p=='T');
REP2(i,0,3)
{
if( ( p=='S' || p=='T' ) && i!=0)
continue;
if(p=='#' && i!=2)
continue;
REP2(j,0,ans.size())
{
if(ans[j].y && i!=0)
continue;
if(!ans[j].y && i==0)
continue;
int nk=k+(i==1);
if(nk>K)continue;
int np=ans[j].x;
//状态不合法
if(hash[np]==0)
continue;
pair<int,int> nf=getHouse(x,y,it->x.y,i);
if(!np)
{
answer=max(answer,nf.y+it->y);
if(!find(nf.x))
continue;
}
update(F[nk][mp(np,nf.x)],nf.y+it->y);
}
}
}
/*
int sum=0;
REP(k,0,K)
{
sum+=F[k].size();
REP2(it,F[k].begin(),F[k].end())
{
printf("%d %d %d\n",x,y,k);
show(it->x.x);
show(it->x.y);
printf("%d\n",it->y);
printf("\n");
}
}
*/
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);
#endif
int i,j;
scanf("%d%d%d",&m,&n,&K);
REP2(i,0,m)
{
char str[100];
scanf("%s",str);
REP2(j,0,n)
g[i][j]=str[j];
}
if(n>m)
{
int temp[NUMM][NUMM];
REP2(i,0,m)
REP2(j,0,n)
temp[j][i]=g[i][j];
swap(n,m);
REP2(i,0,m)
REP2(j,0,n)
g[i][j]=temp[i][j];
}
pre();
REP(i,1,m)
REP(j,0,n)
work(i,j);
printf("%d\n",answer-1);
return 0;
}
I2luY2x1ZGU8Y3N0ZGlvPgojaW5jbHVkZTxjc3RkbGliPgojaW5jbHVkZTxjc3RyaW5nPgojaW5jbHVkZTxhbGdvcml0aG0+CiNpbmNsdWRlPGlvc3RyZWFtPgojaW5jbHVkZTxmc3RyZWFtPgojaW5jbHVkZTxtYXA+CiNpbmNsdWRlPGN0aW1lPgojaW5jbHVkZTxzZXQ+CiNpbmNsdWRlPHF1ZXVlPgojaW5jbHVkZTxjbWF0aD4KI2luY2x1ZGU8dmVjdG9yPgojaW5jbHVkZTxiaXRzZXQ+CiNpbmNsdWRlPGZ1bmN0aW9uYWw+CiNkZWZpbmUgeCBmaXJzdAojZGVmaW5lIHkgc2Vjb25kCiNkZWZpbmUgbXAgbWFrZV9wYWlyCiNkZWZpbmUgcGIgcHVzaF9iYWNrCiNkZWZpbmUgUkVQKGksbCxyKSBmb3IoKGkpPShsKTsoaSk8PShyKTsrKyhpKSkKI2RlZmluZSBSRVAyKGksbCxyKSBmb3IoKGkpPShsKTsoaSkhPShyKTsrKyhpKSkKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnR5cGVkZWYgbG9uZyBsb25nIExMOwp0eXBlZGVmIGRvdWJsZSBsZDsKCmNvbnN0IGludCBOVU09OTsKY29uc3QgaW50IE5VTU09MjI7CmNvbnN0IGludCBOVU1LPTIwOwoKY29uc3QgaW50IFBbXT17MSwxPDwyLDE8PDQsMTw8NiwxPDw4LDE8PDEwLDE8PDEyLDE8PDE0LDE8PDE2LDE8PDE4fTsKCmludCBuLG0sSzsKY2hhciBnW05VTU1dW05VTU1dOwoKaW5saW5lIGludCBnZXQoaW50IGEsaW50IGspCnsKCXJldHVybiBhL1Bba10lNDsKfQoKaW5saW5lIGludCByZXZpc2UoaW50IGEsaW50IGssaW50IGQpCnsKCXJldHVybiBhLWdldChhLGspKlBba10rZCpQW2tdOwp9CgppbnQgbWFbIDE8PDE2IF1bTlVNXTsKaW50IGhhc2hbMTw8MTZdOy8v5Yik5pat54q25oCB5ZCI5rOVCgp2b2lkIHVwZGF0ZShpbnQmIGEsaW50IHApLy/mm7TmlrAKewoJaWYocD4wICYmICggYT09MCB8fCBwPmEgKSApCgkJYT1wOwp9Cgp2b2lkIHNob3coaW50IGEpLy/mmL7npLrnirbmgIEKewoJaW50IGk7CglSRVAyKGksMCxuKzEpCgkJY291dDw8Z2V0KGEsaSk7Cgljb3V0PDxlbmRsOwp9CgppbnQgY2hhbmdlKHN0cmluZyBhKS8v5bCG5a2X56ym5Liy5Y+Y5oiQ5pWwCnsKCWludCBhbnM9MDsKCWZvcihpbnQgaT1uO2k+PTA7LS1pKQoJCWFucz1hbnMqNCthW2ldLScwJzsKCXJldHVybiBhbnM7Cn0KCnZvaWQgcHJlKCkvL+S6i+WFiOiuoeeul+WHuuaJgOacieWPr+iDveeahOeKtuaAgQp7CglpbnQgaSxqOwoJaW50IHN0W05VTV0sdG9wOwoJUkVQMihpLDAsUFtuKzFdKQoJewoJCWludCBudW09MDsKCQlpbnQgZmxhZz0xOwoJCXRvcD0wOwoJCVJFUDIoaiwwLG4rMSkKCQl7CgkJCWludCBwPWdldChpLGopOwoJCQlpZihwPT0zKQoJCQkJKytudW07CgkJCWVsc2UgaWYocD09MCkKCQkJCTsKCQkJZWxzZSBpZihwPT0yKQoJCQl7CgkJCQlpZih0b3A8PTApCgkJCQl7CgkJCQkJZmxhZz0wOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJbWFbaV1bal09c3RbLS10b3BdOwoJCQkJbWFbaV1bbWFbaV1bal1dPWo7CgkJCX0KCQkJZWxzZSBzdFt0b3ArK109ajsKCQl9CgkJaWYoZmxhZyAmJiBudW08PTIgJiYgdG9wPT0wKQoJCQloYXNoW2ldPTE7Cgl9Cn0KCnZlY3RvcjwgcGFpcjxpbnQsaW50PiA+IHpodWFueWkoaW50IGksaW50IGosaW50IG9sZHAsaW50IGhvdXNlLGludCBpcykvL+eci+aLvOmfs+efpeeoi+W6jwp7CgkvL+W5tuayoeacieiAg+iZkeWcsOWbvizku4Xku4Xov5Tlm57miYDmnInnmoTovaznp7sKCS8vT2ggTm8s6L+Z6YGT6aKY55uu5q+U6L6D56We77yM5b+F6aG75L+d6K+B6Iul5Lik5Liq5qC85a2Q55u46L+e77yM6YKj5LmI6L+Z5Lik5Liq54K55LmL6Ze05b+F6aG76L+e6L6544CC44CC44CCCgkvL+S9oOWPquiDveWcqFPmiJbogIVU5Lqn55Sf5Lik5p2h54us56uL6Lev5b6E5oiW6ICF5bCG6Lev5b6E5bCB6ZetIOeUqGlz6KGo56S6CgkvL+imgeaxgueLrOeri+aPkuWktOWcqOerr+eCueS6p+eUn++8jOS4lOerr+eCueW/hemhu+acieeLrOeri+aPkuWktAoJaW50IHA9b2xkcCxucDsKCWludCBwMT1nZXQocCxqLTEpOwoJaW50IHAyPWdldChwLGopOwoJcD1yZXZpc2UocCxqLTEsMCk7CglwPXJldmlzZShwLGosMCk7Cgl2ZWN0b3I8IHBhaXI8aW50LGludD4gPiBhbnM7IAoJaW50IGxlZnQ9aj49Mj9nZXQoaG91c2Usai0yKTozOwoJaW50IHVwPWdldChob3VzZSxqKTsKCWlmKCAoIGxlZnQ9PTAgJiYgIXAxICkgfHwgKHVwPT0wICYmICFwMikpLy/mnInmoLzlrZDkvYbkuI3nm7jov57vvIzlkKblhrMKCXsKCQlpZighcDEgJiYgIXAyKS8v5aaC5p6c5pys6Lqr5LiN5aGr6L+Y5piv5rKh5LqL55qECgkJCWFucy5wYihtcChwLDApKTsKCQlyZXR1cm4gYW5zOwoJfQoJaWYocDE9PTAgJiYgcDI9PTApCgl7CgkJLy/mlrDlop7lt6blj7PljLnphY3nmoTmj5LlpLQKCQlucD1yZXZpc2UocCxqLTEsMSk7CgkJbnA9cmV2aXNlKG5wLGosMik7CgkJaWYoIWlzKQoJCQlhbnMucGIobXAobnAsMSkpOwoJCS8v6Lez6L+HCgkJbnA9cDsKCQlpZighaXMpCgkJCWFucy5wYihtcChucCwwKSk7CgkJLy/mlrDlop7ni6znq4vlkJHkuIvnmoTni6znq4vmj5LlpLQKCQlucD1yZXZpc2UocCxqLTEsMyk7CgkJaWYoaXMpCgkJCWFucy5wYihtcChucCwxKSk7CgkJLy/mlrDlop7ni6znq4vlkJHlj7PnmoTni6znq4vmj5LlpLQKCQlucD1yZXZpc2UocCxqLDMpOwoJCWlmKGlzKQoJCQlhbnMucGIobXAobnAsMSkpOwoJfQoJZWxzZSBpZihwMSE9MyAmJiBwMiE9MykKCXsKCQlpZihwMSAmJiBwMikvL+S4jeWPr+iDveacieeLrOeri+aPkuWktAoJCXsKCQkJaWYocDE9PXAyICYmICFpcykvL+WPquiDvei/nui1t+adpQoJCQl7CgkJCQlpZihwMT09MikKCQkJCXsKCQkJCQlucD1yZXZpc2UocCxtYVtvbGRwXVtqLTFdLDIpOwoJCQkJCWFucy5wYihtcChucCwxKSk7CgkJCQl9CgkJCQllbHNlIGlmKHAxPT0xKQoJCQkJewoJCQkJCW5wPXJldmlzZShwLG1hW29sZHBdW2pdLDEpOwoJCQkJCWFucy5wYihtcChucCwxKSk7CgkJCQl9CgkJCX0KCQkJZWxzZSBpZihwMT09MiAmJiBwMj09MSAmJiAhaXMpLy/lj6/ku6Xov57otbfmnaUKCQkJewoJCQkJbnA9cDsKCQkJCWFucy5wYihtcChucCwxKSk7CgkJCX0KCQkJZWxzZSAvLzEsMueahOivne+8jOmCo+S5iOWwseW9ouaIkOS6huWbnui3r++8jOmimOebruaxgueahOaYr+i3r+W+hCzmlYXlkKblhrMKCQkJewoJCQkJOwoJCQl9CgkJfQoJCWVsc2UKCQl7CgkJCWludCB1PXAxP3AxOnAyOy8v5Lik56eN5oOF5Ya15Ly85LmO5Y+v5Lul5ZCI5bm2CgkJCS8v5LiK6Z2i5pyJ5Lic6KW/77yM5L2c5Li65YK75Y+J77yM5oiR5Y+v5Lul5bCG5YW257un57utCgkJCS8v5b6A5LiL6L+eCgkJCW5wPXJldmlzZShwLGotMSx1KTsKCQkJaWYoIWlzKQoJCQkJYW5zLnBiKG1wKG5wLDEpKTsKCQkJLy/mi5DkuobkuKrlvK8KCQkJbnA9cmV2aXNlKHAsaix1KTsKCQkJaWYoIWlzKQoJCQkJYW5zLnBiKG1wKG5wLDEpKTsKCQkJLy/lsIHkvY8KCQkJaWYocDIgJiYgaXMpLy/lvoDkuIvnmoTlsIHkvY/kuoYKCQkJewoJCQkJbnA9cmV2aXNlKHAsbWFbb2xkcF1bal0sMyk7Ly/nm7jov57nmoTpgqPkuKrmiJDkuoblj6/mgJznmoTni6znq4vmj5LlpLQKCQkJCWFucy5wYihtcChucCwxKSk7CgkJCX0KCQkJZWxzZSBpZihwMSAmJiBpcykKCQkJewoJCQkJbnA9cmV2aXNlKHAsbWFbb2xkcF1bai0xXSwzKTsvL+WQjOS4igoJCQkJYW5zLnBiKG1wKG5wLDEpKTsKCQkJfQoJCX0KCX0KCWVsc2UgLy/njrDlnKjogq/lrprmnInkuobkuKrni6znq4vmj5LlpLQseXnlvIDlp4sKCXsKCQlpZihwMT09MyAmJiBwMj09MyAmJiAhaXMpLy/kuKTkuKrni6znq4vmj5LlpLTvvIzlpoLmnpzov57otbfmnaXnmoTor53lsLHnu5PmnZ/nrpfms5XvvIzmib7liLDnrZTmoYjjgIIKCQl7CgkJCWlmKCFwKQoJCQkJYW5zLnBiKG1wKHAsMSkpOwoJCX0KCQllbHNlIGlmKCFwMSB8fCAhcDIpLy/lj6rmnInkuIDkuKrni6znq4vmj5LlpLQKCQl7CgkJCS8v6aaW5YWI5Ly85LmO5Y+v5Lul5pu05paw562U5qGICgkJCWlmKCFwICYmIGlzKS8v5bCB5L2P5LqGCgkJCQlhbnMucGIobXAocCwxKSk7CgkJCS8v54S25ZCO5Y+v5Lul5b6A5LiL5oiW5b6A5Y+z5ouT5bGVCgkJCS8v5b6A5LiL6L+eCgkJCW5wPXJldmlzZShwLGotMSwzKTsKCQkJaWYoIWlzKWFucy5wYihtcChucCwxKSk7CgkJCS8v5ouQ5LqG5Liq5byvCgkJCW5wPXJldmlzZShwLGosMyk7CgkJCWlmKCFpcylhbnMucGIobXAobnAsMSkpOwoJCX0KCQllbHNlIC8v5Y+m5LiA5Liq5o+S5aS05Lya5LiO54us56uL5o+S5aS055u46L+e77yM5LqO5piv5L+u5pS55Y+m5LiA6L655Li654us56uL5o+S5aS0CgkJewoJCQlpZihwMT09MyAmJiAhaXMpCgkJCXsKCQkJCW5wPXJldmlzZShwLG1hW29sZHBdW2pdLDMpOwoJCQkJYW5zLnBiKG1wKG5wLDEpKTsKCQkJfQoJCQllbHNlIGlmKHAyPT0zICYmICFpcykKCQkJewoJCQkJbnA9cmV2aXNlKHAsbWFbb2xkcF1bai0xXSwzKTsKCQkJCWFucy5wYihtcChucCwxKSk7CgkJCX0KCQl9Cgl9CglyZXR1cm4gYW5zOwp9CgovKgogICB4LHkKICAgICAgIHkgICB5KzEgeSsyCiAgIHktMiB5LTEKICAgKi8KCnBhaXI8aW50LGludD4gZ2V0SG91c2UoaW50IHgsaW50IHksaW50IG9sZCxpbnQgd2hhdCkvL+abtOaWsOeCruWPsOWuieaUvgp7CgkvL3gseSDmoLzlrZDku44x5byA5aeL5qCH5Y+3CgkvL3doYXQgMCDot6/nur8gMSDngq7lj7AgMiDpmpznoo0KCWludCBudW1bNF09ezAsMCwwLDB9OwoJaWYoeT4xKQoJewoJCSsrbnVtW2dldChvbGQseS0yKV07CgkJKytudW1bZ2V0KG9sZCx5LTEpXTsKCX0KCSsrbnVtW2dldChvbGQseSldOwoJaWYoeSsxPD1uKQoJCSsrbnVtW2dldChvbGQseSsxKV07CglpbnQgdz13aGF0PDIgPyBudW1bIXdoYXRdIDogMDsKCS8qCgljb3V0PDx4PDwiICI8PHk8PCIgIjw8d2hhdDw8ZW5kbDsKCXNob3cob2xkKTsKCXNob3cocmV2aXNlKG9sZCx5LTEsd2hhdCkpOwoJY291dDw8ZW5kbDsKCSovCglyZXR1cm4gbXAocmV2aXNlKG9sZCx5LTEsd2hhdCksdyk7Cn0KCm1hcDwgcGFpcjxpbnQsaW50PiAsaW50ID4gR1tOVU1LXSxGW05VTUtdOwppbnQgYW5zd2VyPS0xMDAwMDAwMDA7CgppbnQgZmluZChpbnQgeCkKewoJaW50IGk7CglSRVAyKGksMCxuKzEpCgkJaWYoZ2V0KHgsaSk9PTApCgkJCXJldHVybiAxOwoJcmV0dXJuIDA7Cn0KCnZvaWQgd29yayhpbnQgeCxpbnQgeSkKewoJY2hhciBwPScjJzsKCWlmKHkpCgkJcD1nW3gtMV1beS0xXTsKCW1hcDwgcGFpcjxpbnQsaW50PiAsaW50ID46Oml0ZXJhdG9yIGl0OwoJaW50IGksaixrOwoJUkVQKGssMCxLKQoJewoJCUdba109RltrXTsKCQlGW2tdLmNsZWFyKCk7Cgl9CglpbnQgcHA9MDsKCVJFUDIoaSwwLG4rMSkKCQlwcD1wcCo0KzI7CglpZihwIT0nUycgJiYgcCE9J1QnKUZbMF1bbXAoMCxwcCldPTE7CglSRVAoaywwLEspCgkJUkVQMihpdCxHW2tdLmJlZ2luKCksR1trXS5lbmQoKSkKCQl7CgkJCWlmKCF5KQoJCQl7CgkJCQlpZihnZXQoaXQtPngueCxuKT09MCkKCQkJCQl1cGRhdGUoRltrXVttcChpdC0+eC54KjQscmV2aXNlKGl0LT54LnkqNCsyLG4rMSwwKSldLGl0LT55KTsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCXZlY3RvcjwgcGFpcjxpbnQsaW50ID4gPiBhbnM9emh1YW55aSh4LHksaXQtPngueCxpdC0+eC55LHA9PSdTJyB8fCBwPT0nVCcpOwoJCQlSRVAyKGksMCwzKQoJCQl7CgkJCQlpZiggKCBwPT0nUycgfHwgcD09J1QnICkgJiYgaSE9MCkKCQkJCQljb250aW51ZTsKCQkJCWlmKHA9PScjJyAmJiBpIT0yKQoJCQkJCWNvbnRpbnVlOwoJCQkJUkVQMihqLDAsYW5zLnNpemUoKSkKCQkJCXsKCQkJCQlpZihhbnNbal0ueSAmJiBpIT0wKQoJCQkJCQljb250aW51ZTsKCQkJCQlpZighYW5zW2pdLnkgJiYgaT09MCkKCQkJCQkJY29udGludWU7CgkJCQkJaW50IG5rPWsrKGk9PTEpOwoJCQkJCWlmKG5rPkspY29udGludWU7CgkJCQkJaW50IG5wPWFuc1tqXS54OwoJCQkJCS8v54q25oCB5LiN5ZCI5rOVCgkJCQkJaWYoaGFzaFtucF09PTApCgkJCQkJCWNvbnRpbnVlOwoJCQkJCXBhaXI8aW50LGludD4gbmY9Z2V0SG91c2UoeCx5LGl0LT54LnksaSk7CgkJCQkJaWYoIW5wKQoJCQkJCXsKCQkJCQkJYW5zd2VyPW1heChhbnN3ZXIsbmYueStpdC0+eSk7CgkJCQkJCWlmKCFmaW5kKG5mLngpKQoJCQkJCQkJY29udGludWU7CgkJCQkJfQoJCQkJCXVwZGF0ZShGW25rXVttcChucCxuZi54KV0sbmYueStpdC0+eSk7CgkJCQl9CgkJCX0KCQl9CgkvKgoJaW50IHN1bT0wOwoJUkVQKGssMCxLKQoJewoJCXN1bSs9RltrXS5zaXplKCk7CgkJUkVQMihpdCxGW2tdLmJlZ2luKCksRltrXS5lbmQoKSkKCQl7CgkJCXByaW50ZigiJWQgJWQgJWRcbiIseCx5LGspOwoJCQlzaG93KGl0LT54LngpOwoJCQlzaG93KGl0LT54LnkpOwoJCQlwcmludGYoIiVkXG4iLGl0LT55KTsKCQkJcHJpbnRmKCJcbiIpOwoJCX0KCX0KCSovCn0KCmludCBtYWluKCkKewojaWZuZGVmIE9OTElORV9KVURHRQoJZnJlb3BlbigiaW5wdXQudHh0IiwiciIsc3RkaW4pO2ZyZW9wZW4oIm91dHB1dC50eHQiLCJ3IixzdGRvdXQpOwojZW5kaWYKCWludCBpLGo7CglzY2FuZigiJWQlZCVkIiwmbSwmbiwmSyk7CglSRVAyKGksMCxtKQoJewoJCWNoYXIgc3RyWzEwMF07CgkJc2NhbmYoIiVzIixzdHIpOwoJCVJFUDIoaiwwLG4pCgkJCWdbaV1bal09c3RyW2pdOwoJfQoJaWYobj5tKQoJewoJCWludCB0ZW1wW05VTU1dW05VTU1dOwoJCVJFUDIoaSwwLG0pCgkJCVJFUDIoaiwwLG4pCgkJCQl0ZW1wW2pdW2ldPWdbaV1bal07CgkJc3dhcChuLG0pOwoJCVJFUDIoaSwwLG0pCgkJCVJFUDIoaiwwLG4pCgkJCQlnW2ldW2pdPXRlbXBbaV1bal07Cgl9CglwcmUoKTsKCVJFUChpLDEsbSkKCQlSRVAoaiwwLG4pCgkJCXdvcmsoaSxqKTsKCXByaW50ZigiJWRcbiIsYW5zd2VyLTEpOwoJcmV0dXJuIDA7Cn0K