# 2017 10 08 NOIP2017模拟赛

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

#define FOR(i,a,b) for(int i=(a),i##_end_=(b);i<=i##_end_;++i)
#define DOR(i,a,b) for(int i=(a),i##_end_=(b);i>=i##_end_;--i)
#define INF 0x3f3f3f3f
#define LL long long
#define N 105
#define P 1000000007

void chkmx(int &a,int b){if(a<b)a=b;}
void chkmi(int &a,int b){if(a>b)a=b;}
int MAX(int a,int b){return a>b?a:b;}
int MIN(int a,int b){return a<b?a:b;}

int Num[N][1<<13],l[N];
LL ans,dp[N][1<<13],A[N],Sum[N][1<<13];
int n;

void Init(){
FOR(i,0,n){
LL t=A[i];
while(t) Num[i][l[i]++]=t%10,t/=10;
FOR(j,1,(1<<l[i])-1){
LL &sum=Sum[i][j],h=1;
FOR(k,0,l[i]-1) if(j&(1<<k)) sum+=Num[i][k]*h,h*=10;
}
}
FOR(i,0,n) sort(Sum[i]+1,Sum[i]+(1<<l[i]));
}
LL Find(int i,LL sum){
int L=0,R=(1<<l[i])-1,mid,tmp=0;
while(L<=R){
mid=L+R>>1;
if(Sum[i][mid]<=sum) tmp=mid,L=mid+1;
else R=mid-1;
}
return dp[i][tmp];
}
int main(){
//  freopen("num.in","r",stdin);
//  freopen("num.out","w",stdout);
cin>>A[0]>>n;
FOR(i,1,n) A[i]=A[i-1]+1;
Init();
FOR(i,1,(1<<l[0])-1) dp[0][i]=1+dp[0][i-1];
FOR(i,1,n) FOR(j,1,(1<<l[i])-1){
dp[i][j]=Find(i-1,Sum[i][j]);
dp[i][j]=(dp[i][j]+dp[i][j-1])%P;
}
cout<<dp[n][(1<<l[n])-1]<<endl;
return 0;
}

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

#define FOR(i,a,b) for(int i=(a),i##_end_=(b);i<=i##_end_;++i)
#define DOR(i,a,b) for(int i=(a),i##_end_=(b);i>=i##_end_;--i)
#define INF 0x3f3f3f3f
#define LL long long
#define N 105
#define P 1000000007

void chkmx(int &a,int b){if(a<b)a=b;}
void chkmi(int &a,int b){if(a>b)a=b;}
int MAX(int a,int b){return a>b?a:b;}
int MIN(int a,int b){return a<b?a:b;}

int Num[N][1<<13],l[N];
LL ans,dp[N][1<<13],A[N],Sum[N][1<<13];
int n;

void Init(){
FOR(i,0,n){
LL t=A[i];
while(t) Num[i][l[i]++]=t%10,t/=10;
FOR(j,1,(1<<l[i])-1){
LL &sum=Sum[i][j],h=1;
FOR(k,0,l[i]-1) if(j&(1<<k)) sum+=Num[i][k]*h,h*=10;
}
}
FOR(i,0,n) sort(Sum[i]+1,Sum[i]+(1<<l[i]));
}
void Add(LL &a,LL b){
a=(a+b)%P;
}
void Merge(int i){
int s=1;
FOR(j,1,(1<<l[i])-1){
dp[i][j]=dp[i][j-1];
while(s<(1<<l[i-1])&&Sum[i][j]>=Sum[i-1][s]) Add(dp[i][j],dp[i-1][s++]);
}
}
int main(){
//  freopen("num.in","r",stdin);
//  freopen("num.out","w",stdout);
cin>>A[0]>>n;
FOR(i,1,n) A[i]=A[i-1]+1;
Init();
FOR(i,1,(1<<l[0])-1) dp[0][i]=1;
FOR(i,1,n) Merge(i);
FOR(i,1,(1<<l[n])-1) Add(ans,dp[n][i]);
cout<<ans<<endl;
return 0;
}

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;

#define FOR(i,a,b) for(int i=(a),i##_end_=(b);i<=i##_end_;++i)
#define DOR(i,a,b) for(int i=(a),i##_end_=(b);i>=i##_end_;--i)
#define INF 0x3f3f3f3f
#define LL long long
#define M 2005
#define N 5005
#define P 1000000007

void chkmx(int &a,int b){if(a<b)a=b;}
void chkmi(int &a,int b){if(a>b)a=b;}
int MAX(int a,int b){return a>b?a:b;}
int MIN(int a,int b){return a<b?a:b;}

int d[M][M];
struct node{int maxl[2],s[2],cnt[2];}A[M];
vector<int>es[N];
struct W {int x,v;};
int n,m,ans;
queue<W> Q;
void bfs(int s){
Q.push((W){s,0});
while(!Q.empty()){
W q=Q.front();Q.pop();
int x=q.x;
if(d[s][x]!=INF) continue;
d[s][x]=q.v;
FOR(i,0,es[x].size()-1){
int y=es[x][i];
if(d[s][y]!=INF) continue;
Q.push((W){y,q.v+1});
}
}
}
int main(){
//  freopen("four.in","r",stdin);
//  freopen("four.out","w",stdout);
memset(d,INF,sizeof(d));
cin>>n>>m;
FOR(i,1,m){
int a,b;
scanf("%d%d",&a,&b);
es[a].push_back(b);
}
FOR(i,1,n) bfs(i);

FOR(i,1,n)FOR(j,1,n){
if(d[i][j]==INF||i==j)continue;
if(d[i][j]>A[i].maxl[0])
A[i].s[0]=j,A[i].cnt[0]=1,A[i].maxl[0]=d[i][j];
else if(d[i][j]==A[i].maxl[0]) A[i].cnt[0]++;
if(d[i][j]>A[j].maxl[1])
A[j].s[1]=i,A[j].cnt[1]=1,A[j].maxl[1]=d[i][j];
else if(d[i][j]==A[j].maxl[1]) A[j].cnt[1]++;
}

FOR(i,1,n)FOR(j,1,n){
if(d[i][j]==INF||!A[i].cnt[1]||!A[j].cnt[0]||i==j)continue;
if(A[i].s[0]==A[j].s[1]&&A[i].cnt[0]==1&&A[j].cnt[1]==1) continue;
chkmx(ans,A[i].maxl[1]+d[i][j]+A[j].maxl[0]);
}
cout<<ans<<endl;
return 0;
}