#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define
const int maxn = 2e5 + 5;
const int mod = 1e9 + 7;
int k[maxn];
int b[maxn];
struct Mat {
ll m[2][2];
int left, right;
Mat() { memset(m, 0, sizeof m); } // 注意初始化m数组,处理下随机值
friend Mat operator * (const Mat& a, const Mat& b) {
Mat res;
for (int i = 0; i < 2; ++i)
for (int j = 0; j < 2; ++j) {
for (int k = 0; k < 2; ++k)
res.m[i][j] += (a.m[i][k] * b.m[k][j]) % mod;
res.m[i][j] %= mod;
}
return res;
}
};
struct SegTree {
#define
Mat tree[maxn << 2];
void PushUp(int rt) {
int l = tree[rt].left; // 由于Mat里存储了l、r,乘法操作的时候返回新的Mat,导致l,r丢失,预先存起来,避免l、r不见了
int r = tree[rt].right;
tree[rt] = tree[rt << 1] * tree[rt << 1 | 1];
tree[rt].left = l;
tree[rt].right = r;
}
void build(int rt, int l, int r) {
tree[rt].left = l;
tree[rt].right = r;
if (l == r) {
tree[rt].m[0][0] = k[l];
tree[rt].m[1][0] = b[r];
tree[rt].m[1][1] = 1;
return;
}
build(rt << 1, l, mid);
build(rt << 1 | 1, mid + 1, r);
PushUp(rt);
}
void update(int rt, int pos) {
if (tree[rt].left == tree[rt].right) {
tree[rt].m[0][0] = k[tree[rt].left];
tree[rt].m[1][0] = b[tree[rt].right];
return;
}
int md = (tree[rt].left + tree[rt].right) >> 1;
if (pos <= md) update(rt << 1, pos);
else update(rt << 1 | 1, pos);
PushUp(rt);
}
Mat query(int rt, int l, int r) {
if (l <= tree[rt].left && tree[rt].right <= r) return tree[rt];
Mat res; res.m[0][0] = res.m[1][1] = 1; // 初始化为单位阵
int md = (tree[rt].left + tree[rt].right) >> 1;
if (l <= md) res = res * query(rt << 1, l, r);
if (r > md) res = res * query(rt << 1 | 1, l, r);
return res;
}
#undef
};
SegTree st;
int main() {
ios;
int n, m; while (cin >> n >> m) {
for (int i = 1; i <= n; ++i) cin >> k[i];
for (int i = 1; i <= n; ++i) cin >> b[i];
st.build(1, 1, n);
while (m--) {
int x, i, k, b, l, r; cin >> x;
Mat ans; ans.m[0][0] = ans.m[0][1] = 1;
if (x & 1) {
cin >> i >> k >> b;
::k[i] = k % mod, ::b[i] = b % mod;
st.update(1, i);
}
else {
cin >> l >> r;
ans = ans * st.query(1, l, r);
cout << ans.m[0][0] << endl;
}
}
}
return 0;
}