#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <map>
#include <vector>
#include <stack>
#include <queue>
#include <string>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn = 2e5+5;
const int inf = 0x3f3f3f3f;
const ll INF = 0x7f7f7f7f7f7f7f7f;
const int mod = 1e9+7;
ll k[maxn],b[maxn],ans;
struct node
{
int l,r;
ll sum;
}t1[maxn*4],t2[maxn*4];//t1对应加号左侧,t2对应加号右侧
void build1(int p,int l,int r)
{
t1[p].l = l,t1[p].r = r;
if(l == r)
{
t1[p].sum = k[l];
return;
}
int mid = (l+r)/2;
build1(p*2,l,mid);
build1(p*2+1,mid+1,r);
t1[p].sum = (t1[p*2].sum * t1[p*2+1].sum)%mod;
}
void build2(int p,int l,int r)
{
t2[p].l = l,t2[p].r = r;
if(l == r)
{
t2[p].sum = b[l]%mod;
return;
}
int mid = (l+r)/2;
build2(p*2,l,mid);
build2(p*2+1,mid+1,r);
t2[p].sum = ((t2[p*2].sum*t1[p*2+1].sum)%mod+t2[p*2+1].sum)%mod;
}
void update1(int p,int pos,ll v)
{
if(t1[p].l == t1[p].r)
{
t1[p].sum = v%mod;
return;
}
int mid = (t1[p].l+t1[p].r)/2;
if(mid>=pos)
update1(p*2,pos,v);
else
update1(p*2+1,pos,v);
t1[p].sum = (t1[p*2].sum * t1[p*2+1].sum)%mod;
}
void update2(int p,int pos,ll v)
{
if(t2[p].l == t2[p].r)
{
t2[p].sum = v%mod;
return;
}
int mid = (t2[p].l+t2[p].r)/2;
if(mid>=pos)
update2(p*2,pos,v);
else
update2(p*2+1,pos,v);
t2[p].sum = ((t2[p*2].sum*t1[p*2+1].sum)%mod+t2[p*2+1].sum)%mod;
}
void query(int p,int l,int r)
{
if(t1[p].l >= l && t1[p].r <= r)
{
ans = ((ans*t1[p].sum)%mod+t2[p].sum)%mod;
return;
}
int mid = (t1[p].r+t1[p].l)/2;
if(mid>=l)
query(p*2,l,r);
if(mid<r)
query(p*2+1,l,r);
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
{
scanf("%lld",&k[i]);
}
for(int i=1; i<=n; i++)
{
scanf("%lld",&b[i]);
}
build1(1,1,n);
build2(1,1,n);
while(m--)
{
int opt,x,l,r;
ll v1,v2;
scanf("%d",&opt);
if(opt == 1)
{
scanf("%d%lld%lld",&x,&v1,&v2);
update1(1,x,v1);
update2(1,x,v2);
}
else
{
ans = 1;
scanf("%d%d",&l,&r);
query(1,l,r);
printf("%lld\n",ans);
}
}
}