#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cstring>
#include <string>
#include <queue>
#include <functional>
#include <set>
#include <map>
#include <cmath>
#include <cassert>
#define SIZE 50
#define MOD 1000000007
#define BT 1<<17
#define ALP 12

using namespace std;
typedef long long int ll;
typedef pair <ll,ll> P;

struct UF
{
	int par[SIZE],rank[SIZE];
	
	void init(int n)
	{
		for(int i=0;i<n;i++)
		{
			par[i]=i;
			rank[i]=0;
		}
	}
	int find(int x)
	{
		if(par[x]==x) return x;
		return par[x]=find(par[x]);
	}
	void unite(int x,int y)
	{
		x=find(x);
		y=find(y);
		if(x==y) return;
		if(x>y) swap(x,y);
		par[y]=x;
	}
	bool same(int x,int y)
	{
		return find(x)==find(y);
	}
}uf;
int L[SIZE],R[SIZE];
P memo[SIZE][SIZE];
ll dp[BT][ALP];
int id[SIZE];
int sz;

P merge(P p,P q)
{
	ll a=(p.first*q.first%MOD+p.second*q.second%MOD*8LL%MOD)%MOD;
	ll b=(p.first*q.second%MOD+p.second*7LL%MOD*q.second+p.second*q.first%MOD)%MOD;
	return P(a,b);
}
P solve(int len)//P(0 mod 9, else)
{
	if(len==0) return P(1,0);
	P rt=solve(len/2);
	rt=merge(rt,rt);
	if(len%2==1) rt=merge(rt,P(2,1));
	return rt;
}
ll mpow(ll n,ll t)
{
	if(t==0) return 1;
	ll ret=mpow(n,t/2);
	ret=ret*ret%MOD;
	if(t%2==1) ret=ret*n%MOD;
	return ret;
}
ll cost(int S,int T)
{
	ll ret=1;
	for(int i=0;i<sz;i++)
	{
		if(T>>i&1)
		{
			for(int j=0;j<sz;j++)
			{
				if(S>>j&1) ret=ret*memo[i][j].second%MOD;
				else if((T>>j&1)&&i<j) ret=ret*memo[i][j].first%MOD;
			}
		}
	}
	//printf("%d %d : %lld\n",S,T,ret);
	return ret;
}
int main()
{
	int n;
	scanf("%d",&n);
	int m;
	scanf("%d",&m);
	vector <int> vx;
	for(int i=0;i<m;i++)
	{
		scanf("%d %d",&L[i],&R[i]);
		L[i]--,R[i]--;
		R[i]++;
		vx.push_back(L[i]);
		vx.push_back(R[i]);
	}
	vx.push_back(0);
	sort(vx.begin(),vx.end());
	vx.erase(unique(vx.begin(),vx.end()),vx.end());
	uf.init(vx.size()+2);
	for(int i=0;i<m;i++)
	{
		L[i]=lower_bound(vx.begin(),vx.end(),L[i])-vx.begin();
		R[i]=lower_bound(vx.begin(),vx.end(),R[i])-vx.begin();
		uf.unite(L[i],R[i]);
	}
	for(int i=0;i<vx.size();i++) id[i]=-1;
	sz=0;
	for(int i=0;i<vx.size();i++) if(uf.find(i)==i) id[i]=sz++;
	for(int i=0;i<sz;i++)
	{
		for(int j=0;j<sz;j++)
		{
			memo[i][j]=P(1,1);
		}
	}
	ll ret=mpow(10,n-vx[vx.size()-1]);
	for(int i=0;i+1<vx.size();i++)
	{
		int L=vx[i+1]-vx[i];
		int s=id[uf.find(i)],t=id[uf.find(i+1)];
		P p=solve(L);
		//printf("%d %d %d : %lld %lld\n",L,vx[i],vx[i+1],p.first,p.second);
		if(s==t) ret=ret*p.first%MOD;
		else
		{
			memo[s][t].first=memo[s][t].first*p.first%MOD;
			memo[t][s].first=memo[t][s].first*p.first%MOD;
			memo[s][t].second=memo[s][t].second*p.second%MOD;
			memo[t][s].second=memo[t][s].second*p.second%MOD;
		}
	}/*
	for(int i=0;i<sz;i++)
	{
		for(int j=0;j<sz;j++) printf("[%lld %lld] ",memo[i][j].first,memo[i][j].second);
		puts("");
	}*/
	memset(dp,0,sizeof(dp));
	dp[0][0]=1;
	for(int S=0;S<1<<sz;S++)
	{
		if(S==(1<<sz)-1) break;
		for(int i=0;i<ALP;i++)
		{
			if(dp[S][i]==0) continue;
			int f=-1;
			for(int j=0;j<sz;j++)
			{
				if(!(S>>j&1))
				{
					f=j;
					break;
				}
			}
			int X=(1<<sz)-S-1-(1<<f);
			if(S==0)
			{
				dp[1<<f][1]=cost(0,1<<f);
				for(int T=X;T>0;T=(T-1)&X) dp[T|1<<f][1]=cost(0,T|1<<f);
			}
			else
			{
				dp[S|1<<f][i+1]+=dp[S][i]*cost(S,1<<f)%MOD*(ll) (9-i)%MOD;
				if(dp[S|1<<f][i+1]>=MOD) dp[S|1<<f][i+1]-=MOD;
				for(int T=X;T>0;T=(T-1)&X)
				{
					int to=T|1<<f;
					dp[S|to][i+1]+=dp[S][i]*cost(S,to)%MOD*(ll) (9-i)%MOD;
					if(dp[S|to][i+1]>=MOD) dp[S|to][i+1]-=MOD;
				}
			}
		}
	}
	ll sum=0;
	for(int i=0;i<ALP;i++) 
	{
		sum+=dp[(1<<sz)-1][i];
		if(sum>=MOD) sum-=MOD;
	}
	printf("%lld\n",ret*sum%MOD);
	return 0;
}


Measured memory_bytes: 12672