#include <bits/stdc++.h>
using namespace std;
#define M 1000000007
#define ll long long
#define pb push_back
#define fo(i,N) for(int i = 0 ; i < N ; i++)
#define foo(i,x,N) for (int i = x; i < N ; i++)
#define fill(a,val) memset(a,val,sizeof(a))
#define fastio() ios_base::sync_with_stdio(false); cin.tie(NULL);
#define endl '\n'
#define ff first
#define ss second
int lazy[800005];
struct treeNode
{
int size;
int number;
}tree[800005];
ll power(ll x,ll y)
{
if ( y == 0)
return 1;
ll temp = power(x,y/2)%M;
temp = (temp*temp)%M;
if ( y&1) return (1ll*x%M*temp)%M;
return temp;
}
void update(int s,int e,int l,int r,int index,int bit)
{
if ( lazy[index] != -1)
{
if ( lazy[index])
{
tree[index].number = power(2,tree[index].size)-1;
}
else
tree[index].number = 0;
if ( s != e)
{
lazy[2*index] = lazy[index];
lazy[2*index+1] = lazy[index];
}
lazy[index] = -1;
}
if ( s > r|| e < l)
{
return;
}
if ( s >= l && e <= r)
{ tree[index].size = e-s+1;
if ( bit)
{
tree[index].number = power(2,tree[index].size)-1;
}
else
tree[index].number = 0;
if ( s != e)
{
lazy[2*index] = bit;
lazy[2*index+1] = bit;
}
return;
}
int mid = (s+e)/2;
update(s,mid,l,r,2*index,bit);
update(mid+1,e,l,r,2*index+1,bit);
tree[index].size = tree[2*index].size + tree[2*index+1].size;
tree[index].number = (tree[2*index+1].number%M+ (1ll*power(2,tree[2*index+1].size)*tree[2*index].number%M)%M)%M;
return;
}
treeNode query(int s,int e,int l,int r,int index)
{
if ( lazy[index] != -1)
{
if ( lazy[index])
{
tree[index].number = power(2,tree[index].size)-1;
}
else
tree[index].number = 0;
if ( s != e)
{
lazy[2*index] = lazy[index];
lazy[2*index+1] = lazy[index];
}
lazy[index] = -1;
}
if ( s > r|| e < l)
{
return (treeNode){0,0};
}
if ( s >= l && e <= r)
return tree[index];
int mid = (s+e)/2;
treeNode left = query(s,mid,l,r,2*index);
treeNode right = query(mid+1,e,l,r,2*index+1);
treeNode temp;
temp.size = left.size + right.size;
temp.number = (right.number%M+ (1ll*power(2,right.size)*left.number%M)%M)%M;
return temp;
}
int main()
{
int N,Q;
cin >> N >> Q;
int a,b,c;
foo(i,1,4*N+1)
tree[i] = {1,0},lazy[i] = -1;
while ( Q--)
{
cin >> a >> b >> c;
if ( a == 0)
update(0,N-1,b,c,1,0);
else if ( a == 1)
update(0,N-1,b,c,1,1);
else
cout << query(0,N-1,b,c,1).number << endl;
}
}