#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;

  }
  
}