大概是刚才那题的升级版。。。。思
想非常得神。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<map>
#include<queue>
using namespace std;
#define forup(i,a,b) for(int i=a;i<=b;i++)
#define fordown(i,a,b) for(int i=a;i>=b;i--)
#define For(i,n) for(int i=1;i<=n;i++)
#define For0(i,n) for(int i=0;i<n;i++)
#define Rep(i,l,r) for(int i=l;i<=r;i++)
#define Down(i,r,l) for(int i=r;i>=l;i--)
#define MOD 100000
#define SONS 4
const char Hash[5]={' ','A','C','T','G'};
int n,m,ans;
struct trie
{ int ch[200][5],fail[400],fn[400];
int sz;
trie(){sz=0;}
void insert(char *s){
int cur=0,len=strlen(s),id;
For0(i,len){
For(j,4) if(s[i]==Hash[j]){id=j-1;break;}
if(!ch[cur][id]) ch[cur][id]=++sz;
cur=ch[cur][id];
}
fn[cur]=1;
}
void BuildAC(){
queue<int> q;
For0(i,SONS)
if(ch[0][i]) q.push(ch[0][i]);
while(!q.empty()){
int cur=q.front(); q.pop();
For0(i,SONS){
if(ch[cur][i]){
q.push(ch[cur][i]);
fail[ch[cur][i]]=ch[fail[cur]][i];
if(fn[fail[ch[cur][i]]]) fn[ch[cur][i]]=1;
}
else ch[cur][i]=ch[fail[cur]][i];
}
}
}
}ac;
struct Matrix{
int A[11*11][11*11];
Matrix(){memset(A,0,sizeof(A));}
}Unit,Ans;
Matrix operator * (Matrix A,Matrix B){
Matrix C;
For0(i,ac.sz+1)
For0(j,ac.sz+1)
For0(k,ac.sz+1)
C.A[i][j]=(C.A[i][j]+(long long)A.A[i][k]*B.A[k][j])%MOD;
return C;
}
void DP(){
For0(i,ac.sz+1)
if(!ac.fn[i])
For0(k,SONS){
int cur=ac.ch[i][k];
if(!ac.fn[cur]) Unit.A[i][cur]++;
}
For0(i,ac.sz+1) Ans.A[i][i]=1;
while(n){
if(n&1) Ans=Ans*Unit;
Unit=Unit*Unit;
n>>=1;
}
For0(i,ac.sz+1) ans=(ans+Ans.A[0][i])%MOD;
printf("%d\n",ans%MOD);
}
int main(){
scanf("%d%d",&m,&n);
forup(i,1,m){
char st[100];
scanf("%s",&st);
ac.insert(st);
}
ac.BuildAC();
DP();
return 0;
}