A rabbit's genes can be expressed as a string whose length is l (1 ≤ l ≤ 100) containing only 'A', 'G', 'T', 'C'. There is no doubt that Dr. X had a in-depth research on the rabbits' genes. He found that if a rabbit gene contained a particular gene segment, we could consider it as a good rabbit, or sometimes a bad rabbit. And we use a value W to measure this index.
We can make a example, if a rabbit has gene segment "ATG", its W would plus 4; and if has gene segment "TGC", its W plus -3. So if a rabbit's gene string is "ATGC", its W is 1 due to ATGC contains both "ATG"(+4) and "TGC"(-3). And if another rabbit's gene string is "ATGATG", its W is 4 due to one gene segment can be calculate only once.
Because there are enough rabbits on Earth before 2012, so we can assume we can get any genes with different structure. Now Dr. X want to find a rabbit whose gene has highest W value. There are so many different genes with length l, and Dr. X is not good at programming, can you help him to figure out the W value of the best rabbit.
The next n lines each line contains a string DNAi and an integer wi (|wi| ≤ 100), indicating this gene segment and the value it can contribute to a rabbit's W.
case 1:we can find a rabbit whose gene string is ATGG(4), or ATGA(4) etc.
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <string>
using namespace std;
const int N=;
int a[],tot;
struct Node
{
Node *fail;
Node *son[];
int flag;
int id;
}node[N],*root;
queue<Node*>Q;
bool dp[][N][]; int f(char c)
{
if(c=='A') return ;
if(c=='G') return ;
if(c=='T') return ;
if(c=='C') return ;
}
void insert(string s,int id)
{
Node *now=root;
for(int i=;i<s.length();i++)
{
int x=f(s[i]);
if(now->son[x]==NULL) now->son[x]=&node[tot++];
now=now->son[x];
}
now->flag|=(<<(id-));
}
void build()
{
Q.push(root);
while(!Q.empty())
{
Node *now=Q.front(); Q.pop();
for(int i=;i<;i++)
{
if(now->son[i])
{
Node *p=now->fail;
while(p&&(!(p->son[i]))) p=p->fail;
now->son[i]->fail=(p)?(p->son[i]):root;
now->son[i]->flag|=now->son[i]->fail->flag;
Q.push(now->son[i]);
}
else now->son[i]=(now!=root)?now->fail->son[i]:root;
}
}
}
void init()
{
tot=;
root=&node[];
memset(dp,,sizeof(dp));
while(!Q.empty()) Q.pop();
for(int i=;i<N;i++)
{
node[i].fail=NULL;
node[i].flag=;
node[i].id=i;
for(int j=;j<;j++) node[i].son[j]=NULL;
}
}
int main()
{
int n,l;
while(scanf("%d%d",&n,&l)!=EOF)
{
init();
for(int i=;i<=n;i++)
{
string s; cin>>s;
insert(s,i);
scanf("%d",&a[i]);
}
build();
dp[][][]=;
int cn=;
for(int i=;i<l;i++)
{
cn^=;
memset(dp[cn],,sizeof(dp[cn]));
for(int j=;j<tot;j++)
{
for(int s=;s<(<<n);s++)
{
if(!dp[cn^][j][s]) continue;
for(int k=;k<;k++)
{
int x=node[j].son[k]->id;
int f=node[j].son[k]->flag;
dp[cn][x][s|f]=;
}
}
}
}
int ans=-;
for(int i=;i<tot;i++)
{
for(int s=;s<(<<n);s++)
{
if(!dp[cn][i][s]) continue;
int tmp=;
int x=s;
for(int k=;k<=n;k++)
{
if(x&) tmp+=a[k];
x>>=;
}
ans=max(ans,tmp);
}
}
if(ans<) puts("No Rabbit after 2012!");
else printf("%d\n",ans);
}
return ;
}