#include <bits/stdc++.h>
#define loop(a,b) for(int i=a;i<b;i++)
#define loop2(a,b) for(int j=a;j<b;j++)
#define revloop(a,b) for(int k=a;k>=b;k--)
#define mod 1000000000
#define lli long long int
using namespace std;
struct node{
int count[40];
};
lli factorial[40];
void BuildSegTree(int arr[], node seg[], int lazy[], int low, int high, int pos)
{
loop(1,40)
{
seg[pos].count[i] = 0;
}
if(low == high)
{
if(arr[low]<40)
seg[pos].count[arr[low]]=1;
}
else
{
int mid = (low+high)/2;
BuildSegTree(arr,seg,lazy,low,mid,2*pos+1);
BuildSegTree(arr,seg,lazy,mid+1,high,2*pos+2);
loop(1,40)
{
seg[pos].count[i] = seg[2*pos+1].count[i] + seg[2*pos+2].count[i];
}
}
}
void UpdateSegTree(int arr[], node seg[], int lazy[], int low, int high, int pos, int l, int r, int val, int choice)
{
if(lazy[pos]!=0)
{
revloop(39,1)
{
if(k+lazy[pos]<40)
{
seg[pos].count[k+lazy[pos]] = seg[pos].count[k];
}
seg[pos].count[k] = 0;
}
if(low!=high)
{
lazy[2*pos+1] = lazy[pos];
lazy[2*pos+2] = lazy[pos];
}
lazy[pos] = 0;
}
if(l>high || r<low)
return;
if(l<= low && r>=high)
{
if(choice==3)
{
loop(1,40)
{
if(i==val)
seg[pos].count[val] = 1;
else
seg[pos].count[i] = 0;
}
}
else
{
revloop(39,2)
{
seg[pos].count[k] = seg[pos].count[k-1];
}
seg[pos].count[1] = 0 ;
}
if(low!=high)
{
lazy[2*pos+1] += val;
lazy[2*pos+2] += val;
}
return;
}
int mid = (low+high)/2;
UpdateSegTree(arr,seg,lazy,low,mid,2*pos+1,l,r,val,choice);
UpdateSegTree(arr,seg,lazy,mid+1,high,2*pos+2,l,r,val,choice);
loop(1,40)
{
seg[pos].count[i] = seg[2*pos+1].count[i] + seg[2*pos+2].count[i];
}
}
lli RangeQuerySegTree(int arr[], node seg[], int lazy[], int low, int high, int pos, int l, int r)
{
if(lazy[pos]!=0)
{
revloop(39,1)
{
if(k+lazy[pos]<40)
{
seg[pos].count[k+lazy[pos]] = seg[pos].count[k];
}
seg[pos].count[k] = 0;
}
if(low!=high)
{
lazy[2*pos+1] = lazy[pos];
lazy[2*pos+2] = lazy[pos];
}
lazy[pos] = 0;
}
if(l>high || r<low)
return 0;
if(l<= low && r>=high)
{
lli sum = 0;
loop(1,40)
{
sum += (seg[pos].count[i]*factorial[i]) % mod;
}
return sum;
}
int mid = (low+high)/2;
return RangeQuerySegTree(arr,seg,lazy,low,mid,2*pos+1,l,r) + RangeQuerySegTree(arr,seg,lazy,mid+1,high,2*pos+2,l,r);
}
int main()
{
int n,m;
cin>>n>>m;
factorial[0] = factorial[1] = 1;
loop(2,40)
factorial[i] = (factorial[i-1]*i )% mod;
int n2=n,n1 = n, exp=0;
while(n1)
{
n1/=2;
exp++;
}
exp--;
int seg_size;
if(pow(2,exp) == n)
seg_size = 2*n-1;
else
seg_size = 2*pow(2,exp+1) - 1;
int arr[n];
loop(0,n)
cin>>arr[i];
node seg[seg_size];
int lazy[seg_size];
int low = 0, high = n-1, pos = 0;
loop(0,seg_size)
{
loop2(1,40)
{
seg[i].count[j]=0;
}
}
BuildSegTree(arr,seg,lazy,low,high,pos);
memset(lazy,0,sizeof(lazy));
loop(0,m)
{
int n1, l, r;
cin>>n1>>l>>r;
l--;
if(n1 == 1)
{
r--;
UpdateSegTree(arr,seg,lazy,0,n-1,0,l,r,1,1);
}
else if(n1==2)
{
r--;
cout<<RangeQuerySegTree(arr,seg,lazy,0,n-1,0,l,r)<<"\n";
}
else
{
UpdateSegTree(arr,seg,lazy,0,n-1,0,l,l,r,3);
}
}
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CiNkZWZpbmUgbG9vcChhLGIpIGZvcihpbnQgaT1hO2k8YjtpKyspCiNkZWZpbmUgbG9vcDIoYSxiKSBmb3IoaW50IGo9YTtqPGI7aisrKQojZGVmaW5lIHJldmxvb3AoYSxiKSBmb3IoaW50IGs9YTtrPj1iO2stLSkKI2RlZmluZSBtb2QgMTAwMDAwMDAwMAojZGVmaW5lIGxsaSBsb25nIGxvbmcgaW50CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgoKc3RydWN0IG5vZGV7CmludCBjb3VudFs0MF07Cn07CgpsbGkgZmFjdG9yaWFsWzQwXTsKCnZvaWQgQnVpbGRTZWdUcmVlKGludCBhcnJbXSwgbm9kZSBzZWdbXSwgaW50IGxhenlbXSwgaW50IGxvdywgaW50IGhpZ2gsIGludCBwb3MpCnsKICAgIGxvb3AoMSw0MCkKICAgIHsKICAgICAgICBzZWdbcG9zXS5jb3VudFtpXSA9IDA7CiAgICB9CgogICAgaWYobG93ID09IGhpZ2gpCiAgICB7CiAgICAgICAgCiAgICAgICAgaWYoYXJyW2xvd108NDApCiAgICAgICAgICAgIHNlZ1twb3NdLmNvdW50W2Fycltsb3ddXT0xOwoKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBpbnQgbWlkID0gKGxvdytoaWdoKS8yOwogICAgICAgIEJ1aWxkU2VnVHJlZShhcnIsc2VnLGxhenksbG93LG1pZCwyKnBvcysxKTsKICAgICAgICBCdWlsZFNlZ1RyZWUoYXJyLHNlZyxsYXp5LG1pZCsxLGhpZ2gsMipwb3MrMik7CiAgICAgICAgbG9vcCgxLDQwKQogICAgICAgIHsKICAgICAgICAgICAgc2VnW3Bvc10uY291bnRbaV0gPSBzZWdbMipwb3MrMV0uY291bnRbaV0gKyBzZWdbMipwb3MrMl0uY291bnRbaV07CiAgICAgICAgfQoKICAgIH0KCn0KCnZvaWQgVXBkYXRlU2VnVHJlZShpbnQgYXJyW10sIG5vZGUgc2VnW10sIGludCBsYXp5W10sIGludCBsb3csIGludCBoaWdoLCBpbnQgcG9zLCBpbnQgbCwgaW50IHIsIGludCB2YWwsIGludCBjaG9pY2UpCnsKICAgIGlmKGxhenlbcG9zXSE9MCkKICAgIHsKICAgICAgICByZXZsb29wKDM5LDEpCiAgICAgICAgewogICAgICAgICAgICBpZihrK2xhenlbcG9zXTw0MCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc2VnW3Bvc10uY291bnRbaytsYXp5W3Bvc11dID0gc2VnW3Bvc10uY291bnRba107CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2VnW3Bvc10uY291bnRba10gPSAwOwogICAgICAgIH0KICAgICAgICBpZihsb3chPWhpZ2gpCiAgICAgICAgewogICAgICAgICAgICBsYXp5WzIqcG9zKzFdID0gbGF6eVtwb3NdOwogICAgICAgICAgICBsYXp5WzIqcG9zKzJdID0gbGF6eVtwb3NdOwogICAgICAgIH0KICAgICAgICBsYXp5W3Bvc10gPSAwOwogICAgfQoKICAgIGlmKGw+aGlnaCB8fCByPGxvdykKICAgICAgICByZXR1cm47CiAgICBpZihsPD0gbG93ICYmIHI+PWhpZ2gpCiAgICB7CiAgICAgICAgaWYoY2hvaWNlPT0zKQogICAgICAgIHsKICAgICAgICAgICAgICAgIGxvb3AoMSw0MCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZihpPT12YWwpCiAgICAgICAgICAgICAgICAgICAgICAgIHNlZ1twb3NdLmNvdW50W3ZhbF0gPSAxOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgc2VnW3Bvc10uY291bnRbaV0gPSAwOwogICAgICAgICAgICAgICAgfQoKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgcmV2bG9vcCgzOSwyKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzZWdbcG9zXS5jb3VudFtrXSA9IHNlZ1twb3NdLmNvdW50W2stMV07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2VnW3Bvc10uY291bnRbMV0gPSAwIDsKICAgICAgICB9CgogICAgICAgIGlmKGxvdyE9aGlnaCkKICAgICAgICB7CiAgICAgICAgICAgIGxhenlbMipwb3MrMV0gKz0gdmFsOwogICAgICAgICAgICBsYXp5WzIqcG9zKzJdICs9IHZhbDsKICAgICAgICB9CgogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpbnQgbWlkID0gKGxvdytoaWdoKS8yOwogICAgVXBkYXRlU2VnVHJlZShhcnIsc2VnLGxhenksbG93LG1pZCwyKnBvcysxLGwscix2YWwsY2hvaWNlKTsKICAgIFVwZGF0ZVNlZ1RyZWUoYXJyLHNlZyxsYXp5LG1pZCsxLGhpZ2gsMipwb3MrMixsLHIsdmFsLGNob2ljZSk7CiAgICBsb29wKDEsNDApCiAgICB7CiAgICAgICAgc2VnW3Bvc10uY291bnRbaV0gPSBzZWdbMipwb3MrMV0uY291bnRbaV0gKyBzZWdbMipwb3MrMl0uY291bnRbaV07CiAgICB9Cgp9CgoKbGxpIFJhbmdlUXVlcnlTZWdUcmVlKGludCBhcnJbXSwgbm9kZSBzZWdbXSwgaW50IGxhenlbXSwgaW50IGxvdywgaW50IGhpZ2gsIGludCBwb3MsIGludCBsLCBpbnQgcikKewogICAgaWYobGF6eVtwb3NdIT0wKQogICAgewogICAgICAgIHJldmxvb3AoMzksMSkKICAgICAgICB7CiAgICAgICAgICAgIGlmKGsrbGF6eVtwb3NdPDQwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzZWdbcG9zXS5jb3VudFtrK2xhenlbcG9zXV0gPSBzZWdbcG9zXS5jb3VudFtrXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzZWdbcG9zXS5jb3VudFtrXSA9IDA7CiAgICAgICAgfQogICAgICAgIGlmKGxvdyE9aGlnaCkKICAgICAgICB7CiAgICAgICAgICAgIGxhenlbMipwb3MrMV0gPSBsYXp5W3Bvc107CiAgICAgICAgICAgIGxhenlbMipwb3MrMl0gPSBsYXp5W3Bvc107CiAgICAgICAgfQogICAgICAgIGxhenlbcG9zXSA9IDA7CiAgICB9CiAgICBpZihsPmhpZ2ggfHwgcjxsb3cpCiAgICByZXR1cm4gMDsKICAgIGlmKGw8PSBsb3cgJiYgcj49aGlnaCkKICAgIHsKICAgICAgICBsbGkgc3VtID0gMDsKICAgICAgIAogICAgICAgIGxvb3AoMSw0MCkKICAgICAgICB7CiAgICAgICAgICAgCiAgICAgICAgICAgIHN1bSArPSAoc2VnW3Bvc10uY291bnRbaV0qZmFjdG9yaWFsW2ldKSAlIG1vZDsKICAgICAgICB9CiAgICAgICAKICAgICAgICByZXR1cm4gc3VtOwogICAgfQogICAgaW50IG1pZCA9IChsb3craGlnaCkvMjsKICAgIHJldHVybiBSYW5nZVF1ZXJ5U2VnVHJlZShhcnIsc2VnLGxhenksbG93LG1pZCwyKnBvcysxLGwscikgKyBSYW5nZVF1ZXJ5U2VnVHJlZShhcnIsc2VnLGxhenksbWlkKzEsaGlnaCwyKnBvcysyLGwscik7CgoKfQoKCgppbnQgbWFpbigpCnsKICAgIGludCBuLG07CiAgICBjaW4+Pm4+Pm07CgogICAgZmFjdG9yaWFsWzBdID0gZmFjdG9yaWFsWzFdID0gMTsKICAgIGxvb3AoMiw0MCkKICAgICAgICBmYWN0b3JpYWxbaV0gPSAoZmFjdG9yaWFsW2ktMV0qaSApJSBtb2Q7CgogICAgaW50IG4yPW4sbjEgPSBuLCBleHA9MDsKICAgIHdoaWxlKG4xKQogICAgewogICAgICAgIG4xLz0yOwogICAgICAgIGV4cCsrOwogICAgfQogICAgZXhwLS07CiAgICAKICAgIGludCBzZWdfc2l6ZTsKCiAgICBpZihwb3coMixleHApICA9PSBuKQogICAgICAgICAgICBzZWdfc2l6ZSA9IDIqbi0xOwogICAgZWxzZQogICAgICAgIHNlZ19zaXplID0gMipwb3coMixleHArMSkgLSAxOwogICAgCgogICAgaW50IGFycltuXTsKICAgIGxvb3AoMCxuKQogICAgICAgIGNpbj4+YXJyW2ldOwoKICAgIG5vZGUgc2VnW3NlZ19zaXplXTsKICAgIGludCBsYXp5W3NlZ19zaXplXTsKICAgIGludCBsb3cgPSAwLCBoaWdoID0gbi0xLCBwb3MgPSAwOwogICAgIGxvb3AoMCxzZWdfc2l6ZSkKICAgIHsKCiAgICAgICAgbG9vcDIoMSw0MCkKICAgICAgICB7CiAgICAgICAgICAgIHNlZ1tpXS5jb3VudFtqXT0wOwogICAgICAgIH0KICAgIH0KICAgIEJ1aWxkU2VnVHJlZShhcnIsc2VnLGxhenksbG93LGhpZ2gscG9zKTsKICAgIAogICAgbWVtc2V0KGxhenksMCxzaXplb2YobGF6eSkpOwoKICAgIGxvb3AoMCxtKQogICAgewoKICAgICAgICBpbnQgbjEsIGwsIHI7CiAgICAgICAgY2luPj5uMT4+bD4+cjsKICAgICAgICBsLS07CgogICAgICAgIGlmKG4xID09IDEpCiAgICAgICAgewogICAgICAgICAgICByLS07CiAgICAgICAgICAgIFVwZGF0ZVNlZ1RyZWUoYXJyLHNlZyxsYXp5LDAsbi0xLDAsbCxyLDEsMSk7CiAgICAgICAgICAgIAogICAgICAgIH0KICAgICAgICBlbHNlIGlmKG4xPT0yKQogICAgICAgIHsKICAgICAgICAgICAgci0tOwogICAgICAgICAgICBjb3V0PDxSYW5nZVF1ZXJ5U2VnVHJlZShhcnIsc2VnLGxhenksMCxuLTEsMCxsLHIpPDwiXG4iOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgVXBkYXRlU2VnVHJlZShhcnIsc2VnLGxhenksMCxuLTEsMCxsLGwsciwzKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIH0KICAgIH0KfQo=