class Solution {
long MOD = (long)1e9+7;
int[] lps = lps(evil);
int m = evil.length();
int[][] to = new int[m][26];
//to[i][ch] = Longest suffix of string (evil[0, i]+ch), where ch is a character
for(int i = 0; i< m; i++){
for(char ch = 'a'; ch <= 'z'; ch++){
if(evil.charAt(i) == ch)to[i][ch-'a'] = i+1;
else if(i != 0)to[i][ch-'a'] = to[lps[i-1]][ch-'a'];
}
}
long[][] DP = new long[1+n][m];
//DP[i][j] = Number of ways to choose suffix of length i if the prefix had last j characters same as prefix of evil string
for(int i = 0; i< m; i++)DP[0][i] = 1;
for(int len = 1; len <= n; len++){
for(int prefix = 0; prefix < m; prefix++){
for(char ch = 'a'; ch <= 'z'; ch++){
int cur = to[prefix][ch-'a'];
if(cur < m){
DP[len][prefix] += DP[len-1][cur];
if(DP[len][prefix] >= MOD)DP[len][prefix] -= MOD;
}
}
}
}
Counter countingInterface = new Counter(n, s1, s2, evil, to, DP);
return (int)countingInterface.count();
}
class Counter{
int[][] to;
int n;
long[][] DP;
this.lo = lo;this.hi = hi;this.evil = evil;this.to = to;this.n = n;this.DP = DP;
}
public long count(){
return count(0, 3, 0);
}
//Digit DP styke function
private long count(int idx, int flag, int prefix){
if(idx == n)return 1;
if(flag == 0)return DP[n-idx][prefix];
//if the prefix of current string is same as string lo, flag has first bit set
char lower = (flag&1)==1?lo.charAt(idx):'a';
//if the prefix of current string is same as string hi, flag has second bit set
char upper = (flag&2)==2?hi.charAt(idx):'z';
long ans = 0;
for(char cur = lower; cur <= upper; cur++){
if(to[prefix][cur-'a'] < evil.length()){
ans += count(idx+1, (flag&(cur == lower?1:0))|(flag&(cur==upper?2:0)), to[prefix][cur-'a']);
if(ans >= MOD)ans -= MOD;
}
}
return ans;
}
}
//Prefix function
int m = pat.length();
int[] lps = new int[m];
int len = 0, pos = 1;
while(pos < m){
if(pat.charAt(pos) == pat.charAt(len))lps[pos++] = ++len;
else if(len > 0)len = lps[len-1];
else pos++;
}
return lps;
}
}
Y2xhc3MgU29sdXRpb24gewogICAgbG9uZyBNT0QgPSAobG9uZykxZTkrNzsKICAgIHB1YmxpYyBpbnQgZmluZEdvb2RTdHJpbmdzKGludCBuLCBTdHJpbmcgczEsIFN0cmluZyBzMiwgU3RyaW5nIGV2aWwpIHsKICAgICAgICBpbnRbXSBscHMgPSBscHMoZXZpbCk7CiAgICAgICAgaW50IG0gPSBldmlsLmxlbmd0aCgpOwogICAgICAgIGludFtdW10gdG8gPSBuZXcgaW50W21dWzI2XTsKICAgICAgICAvL3RvW2ldW2NoXSA9IExvbmdlc3Qgc3VmZml4IG9mIHN0cmluZyAoZXZpbFswLCBpXStjaCksIHdoZXJlIGNoIGlzIGEgY2hhcmFjdGVyCiAgICAgICAgZm9yKGludCBpID0gMDsgaTwgbTsgaSsrKXsKICAgICAgICAgICAgZm9yKGNoYXIgY2ggPSAnYSc7IGNoIDw9ICd6JzsgY2grKyl7CiAgICAgICAgICAgICAgICBpZihldmlsLmNoYXJBdChpKSA9PSBjaCl0b1tpXVtjaC0nYSddID0gaSsxOwogICAgICAgICAgICAgICAgZWxzZSBpZihpICE9IDApdG9baV1bY2gtJ2EnXSA9IHRvW2xwc1tpLTFdXVtjaC0nYSddOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGxvbmdbXVtdIERQID0gbmV3IGxvbmdbMStuXVttXTsKICAgICAgICAvL0RQW2ldW2pdID0gTnVtYmVyIG9mIHdheXMgdG8gY2hvb3NlIHN1ZmZpeCBvZiBsZW5ndGggaSBpZiB0aGUgcHJlZml4IGhhZCBsYXN0IGogY2hhcmFjdGVycyBzYW1lIGFzIHByZWZpeCBvZiBldmlsIHN0cmluZwogICAgICAgIGZvcihpbnQgaSA9IDA7IGk8IG07IGkrKylEUFswXVtpXSA9IDE7CiAgICAgICAgZm9yKGludCBsZW4gPSAxOyBsZW4gPD0gbjsgbGVuKyspewogICAgICAgICAgICBmb3IoaW50IHByZWZpeCA9IDA7IHByZWZpeCA8IG07IHByZWZpeCsrKXsKICAgICAgICAgICAgICAgIGZvcihjaGFyIGNoID0gJ2EnOyBjaCA8PSAneic7IGNoKyspewogICAgICAgICAgICAgICAgICAgIGludCBjdXIgPSB0b1twcmVmaXhdW2NoLSdhJ107CiAgICAgICAgICAgICAgICAgICAgaWYoY3VyIDwgbSl7CiAgICAgICAgICAgICAgICAgICAgICAgIERQW2xlbl1bcHJlZml4XSArPSBEUFtsZW4tMV1bY3VyXTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoRFBbbGVuXVtwcmVmaXhdID49IE1PRClEUFtsZW5dW3ByZWZpeF0gLT0gTU9EOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBDb3VudGVyIGNvdW50aW5nSW50ZXJmYWNlID0gbmV3IENvdW50ZXIobiwgczEsIHMyLCBldmlsLCB0bywgRFApOwogICAgICAgIHJldHVybiAoaW50KWNvdW50aW5nSW50ZXJmYWNlLmNvdW50KCk7CiAgICB9CiAgICBjbGFzcyBDb3VudGVyewogICAgICAgIFN0cmluZyBsbywgaGksIGV2aWw7CiAgICAgICAgaW50W11bXSB0bzsKICAgICAgICBpbnQgbjsKICAgICAgICBsb25nW11bXSBEUDsKICAgICAgICBwdWJsaWMgQ291bnRlcihpbnQgbiwgU3RyaW5nIGxvLCBTdHJpbmcgaGksIFN0cmluZyBldmlsLCBpbnRbXVtdIHRvLCBsb25nW11bXSBEUCl7CiAgICAgICAgICAgIHRoaXMubG8gPSBsbzt0aGlzLmhpID0gaGk7dGhpcy5ldmlsID0gZXZpbDt0aGlzLnRvID0gdG87dGhpcy5uID0gbjt0aGlzLkRQID0gRFA7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBsb25nIGNvdW50KCl7CiAgICAgICAgICAgIHJldHVybiBjb3VudCgwLCAzLCAwKTsKICAgICAgICB9CiAgICAgICAgLy9EaWdpdCBEUCBzdHlrZSBmdW5jdGlvbgogICAgICAgIHByaXZhdGUgbG9uZyBjb3VudChpbnQgaWR4LCBpbnQgZmxhZywgaW50IHByZWZpeCl7CiAgICAgICAgICAgIGlmKGlkeCA9PSBuKXJldHVybiAxOwogICAgICAgICAgICBpZihmbGFnID09IDApcmV0dXJuIERQW24taWR4XVtwcmVmaXhdOwogICAgICAgICAgICAvL2lmIHRoZSBwcmVmaXggb2YgY3VycmVudCBzdHJpbmcgaXMgc2FtZSBhcyBzdHJpbmcgbG8sIGZsYWcgaGFzIGZpcnN0IGJpdCBzZXQKICAgICAgICAgICAgY2hhciBsb3dlciA9IChmbGFnJjEpPT0xP2xvLmNoYXJBdChpZHgpOidhJzsKICAgICAgICAgICAgLy9pZiB0aGUgcHJlZml4IG9mIGN1cnJlbnQgc3RyaW5nIGlzIHNhbWUgYXMgc3RyaW5nIGhpLCBmbGFnIGhhcyBzZWNvbmQgYml0IHNldAogICAgICAgICAgICBjaGFyIHVwcGVyID0gKGZsYWcmMik9PTI/aGkuY2hhckF0KGlkeCk6J3onOwogICAgICAgICAgICBsb25nIGFucyA9IDA7CiAgICAgICAgICAgIGZvcihjaGFyIGN1ciA9IGxvd2VyOyBjdXIgPD0gdXBwZXI7IGN1cisrKXsKICAgICAgICAgICAgICAgIGlmKHRvW3ByZWZpeF1bY3VyLSdhJ10gPCBldmlsLmxlbmd0aCgpKXsKICAgICAgICAgICAgICAgICAgICBhbnMgKz0gY291bnQoaWR4KzEsIChmbGFnJihjdXIgPT0gbG93ZXI/MTowKSl8KGZsYWcmKGN1cj09dXBwZXI/MjowKSksIHRvW3ByZWZpeF1bY3VyLSdhJ10pOwogICAgICAgICAgICAgICAgICAgIGlmKGFucyA+PSBNT0QpYW5zIC09IE1PRDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gYW5zOwogICAgICAgIH0KICAgIH0KICAgIC8vUHJlZml4IGZ1bmN0aW9uCiAgICBpbnRbXSBscHMoU3RyaW5nIHBhdCl7CiAgICAgICAgaW50IG0gPSBwYXQubGVuZ3RoKCk7CiAgICAgICAgaW50W10gbHBzID0gbmV3IGludFttXTsKICAgICAgICBpbnQgbGVuID0gMCwgcG9zID0gMTsKICAgICAgICB3aGlsZShwb3MgPCBtKXsKICAgICAgICAgICAgaWYocGF0LmNoYXJBdChwb3MpID09IHBhdC5jaGFyQXQobGVuKSlscHNbcG9zKytdID0gKytsZW47CiAgICAgICAgICAgIGVsc2UgaWYobGVuID4gMClsZW4gPSBscHNbbGVuLTFdOwogICAgICAgICAgICBlbHNlIHBvcysrOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbHBzOwogICAgfQp9