#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<math.h>
#include<iostream>
#include<string>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);}
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T> inline void gmax(T &a,T b){if(b>a)a=b;}
template <class T> inline void gmin(T &a,T b){if(b<a)a=b;}
const int N=1e6+10,M=0,Z=1e9+7,ms63=1061109567;
int n,m,g;
char s[N];
int nxt[N];
int p[N];
bool e[N];
void getnxt()
{
int j=0;nxt[1]=0;
for(int i=2;i<=m;++i)
{
while(j&&s[j+1]!=s[i])j=nxt[j];
if(s[j+1]==s[i])++j;
nxt[i]=j;
}
MS(e,0);
for(int p=m;p;p=nxt[p])e[p]=1;
}
int solve()
{
for(int i=g;i>=1;--i)
{
int dis=p[i+1]-p[i];
if(dis>=m)n-=m;
else
{
int match=m-dis;
if(!e[match])return 0;
else n-=dis;
}
}
LL ans=1;
while(n--)ans=ans*26%Z;
return ans;
}
int main()
{
while(~scanf("%d%d",&n,&g))
{
scanf("%s",s+1);m=strlen(s+1);
getnxt();
for(int i=1;i<=g;++i)scanf("%d",&p[i]);p[g+1]=n+1;
printf("%d\n",solve());
}
return 0;
}
/*
【题意】
给定一个字符串,作为匹配串但是只长度为n(1<=n<=1e6),(所有字符仅为'a'~'z')。
在这个字符串中,已知给定的子串s至少出现了g次(0<=g<=n-|s|+1),并且给你s出现的g次分别是在匹配串的什么位置。
问你匹配串有多少种构成方式。
【类型】
KMP
【分析】
难度1:如果g=0,显然答案是26^n。
难度2:如果任意两个子串的头位置相差都至少是m,显然答案是26^(n-m*g)
难度3:现在子串之间产生了位置冲突。
也就是"子串a,子串b",子串a的尾巴与子串b的头部叠在了一起。
而事实上,子串a=子串b=串s。
假设这两个串的头端点相差了dis,重叠部分的长度显然就是m-dis,设为match。
那么我们其实只需要验证,串s的最前match位与最后match位是否相同。
天哪,这就是KMP所可以简单实现的功能!
对s串做KMP,从尾巴开始沿着fail指针nxt向上跳,设一个能跳到的位置为pos,
基于KMP,那么就有,串s的最前pos位与最后pos位相同,我们打上标记即可。
我们查看标记,如果发现其不满足题目要求,那么答案就是0,
否则我们就有dis长度的串也是固定的。用总的长度n减去。
这样最后的答案就是26^n,现在这个n表示没有被s覆盖过、决定过的长度。
*/