#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
typedef long long ll;
using namespace std;
using namespace __gnu_pbds;
#define ld long double
#define int long long
#define F first
#define S second
#define Lnode 2*node+1
#define Rnode 2*node+2
#define MID (l+r>>1)
#define el '\n'
#define coutf(x) for(auto v:(x)) cout<<v<<' '; cout<<el
#define coutp(x) for(auto v:(x)) cout<<v.F<<' '<<v.S<<el
#define cinl(x) for(auto &v:(x)) cin>>v;
#define all(x)  x.begin(),x.end()
#define ll long long
#define sz(x)  (int)x.size()
#define pi pair<ll,ll>
#define pii pair<ll,pair<ll,ll>>
#define vi vector<ll>
#define ordered_set tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update>
const int N=5005,mod=1e9+7;
using ull = unsigned long long;
// order_of_key (k) : Number of items strictly smaller than k .
// find_by_order(k) : K-th element in a set (counting from zero).
struct aho_corasick {
    struct trie_node {
        vector<int> pIdxs; //probably take memory limit
        map<char, int> next;
        int fail;
        trie_node() :  fail(0) {}
        bool have_next(char ch) {
            return next.find(ch) != next.end();
        }
        int& operator[](char ch) {
            return next[ch];
        }
    };
    vector<trie_node> t;
    vector<string> patterns;
    vector<int> end_of_pattern;
    vector<bool>found;

    vector<vector<int>> adj;
    int insert(const string &s, int patternIdx) {
        int root = 0;
        for (const char &ch : s) {
            if (!t[root].have_next(ch)) {
                t.push_back(trie_node());
                t[root][ch] = t.size() - 1;
            }
            root = t[root][ch];
        }
        t[root].pIdxs.push_back(patternIdx);
        return root;
    }
    int next_state(int cur, char ch) {
        while (cur > 0 && !t[cur].have_next(ch))
            cur = t[cur].fail;
        if (t[cur].have_next(ch))
            return t[cur][ch];
        return 0;
    }
    void buildAhoTree() {
        queue<int> q;
        for (auto &child : t[0].next)
            q.push(child.second);

        while (!q.empty()) {
            int cur = q.front();
            q.pop();
            for (auto &child : t[cur].next) {
                int k = next_state(t[cur].fail, child.first);
                t[child.second].fail = k;
                vector<int> &idxs = t[child.second].pIdxs;
                //dp[child.second] = max(dp[child.second],dp[k]);
                idxs.insert(idxs.end(), all(t[k].pIdxs));
                q.push(child.second);
            }
        }
    }


    void buildFailureTree() {
        adj = vector<vector<int>>(t.size());
        for (int i = 1; i < t.size(); i++)
            adj[t[i].fail].push_back(i);
    }
    aho_corasick(const vector<string> &_patterns) {
        t.push_back(trie_node());
        patterns = _patterns;
        end_of_pattern = vector<int>(patterns.size());
        found=vector<bool>(patterns.size(),false);
        for (int i = 0; i < patterns.size(); i++)
            end_of_pattern[i] = insert(patterns[i], i);
        buildAhoTree();
        //buildFailureTree();
    }
    vector<bool> match(const string &str) {
        int k = 0;
        int sum=0;

        vector<vector<int>> rt(patterns.size());
        for (int i = 0; i < str.size(); i++) {
            k = next_state(k, str[i]);
            for (auto &it : t[k].pIdxs)
                found[it]=1;
        }
       return found;
    }
};
ll n,k;
ll dp[55][1005][2][2];
string s1,s2;
string s;
vector<ll>num;
ll digit(ll i,ll node,bool found,bool f,aho_corasick &ac)
{
    if (i==n)return (found>0);
    ll &ret=dp[i][node][found][f];
    if (~ret)return ret;
    ll res=0;
    int LMT;
    if (f==0)LMT=num[i];
    else LMT=9;
    for (int dgt=0;dgt<=LMT;dgt++)
    {
        int nf=f;
        if (f==0&&dgt<LMT)nf=1;
        char ch=char('0'+dgt);
        int nnode=ac.next_state(node,ch);
        bool nfound =found;
        if (!ac.t[nnode].pIdxs.empty())nfound=1;
            res+=digit(i+1,nnode,nfound,nf,ac);
        if (res>=mod)res-=mod;
    }
    return ret=res;
}
ll fun(string s,aho_corasick &ac){
    num.clear();
    for (auto it:s)
    {
        num.push_back(it-'0');
    }

    n=s.size();

    memset(dp,-1,sizeof dp);
    ll ans=digit(0,0,0,0,ac);
    return ans;
}
string minus1(string s)
{
    int n=s.size();
    int i=n-1;

    while (i>=0&&s[i]=='0')s[i]='9',i--;
    if (i>=0)s[i]--;
    else
    {
        for (int j=0;j<n;j++)s[j]='9';
    }
    return s;
}

void solve()
{
    cin>>s;
    cin>>s1>>s2;

    vector<string>pat;
    k=(int)(s2.size()+1)/2;
    for (int i=0;i+k<=(int)s.size();i++){
        pat.push_back(s.substr(i,k));
    }
    aho_corasick ac(pat);

    bool zero=1;
    for (int i=0;i<s1.size();i++)
    {
        if (s1[i]!='0')
        {
            zero=0;
            break;
        }
    }
    ll a,b;
    if (zero==0)
    {

    s1=minus1(s1);
    b=fun(s1,ac);

    }
    else b=0;
    a=fun(s2,ac);
    ll ans=(a-b)%mod;
    if (ans<0)ans+=mod;
    cout<<ans<<"\n";
}

int32_t main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int tc=1;
    //cin>>tc;
    for (int i=1;i<=tc;i++){solve();}
    return 0;
}
/*

 */