#include <bits/stdc++.h>
using namespace std;
const int N = 400010;
struct matrix {
  int num[2][2];
} A, B, c, la[N], e;
int s1[N], s2[N], t[N];
int n, m, ty, l, r, x, t1, t2, ans;
matrix operator*(const matrix &a, const matrix &b) {
  c.num[0][0] = ((long long)a.num[0][0] * (long long)b.num[0][0] +
                 (long long)a.num[0][1] * (long long)b.num[1][0]) %
                1000000007;
  c.num[0][1] = ((long long)a.num[0][0] * (long long)b.num[0][1] +
                 (long long)a.num[0][1] * (long long)b.num[1][1]) %
                1000000007;
  c.num[1][0] = ((long long)a.num[1][0] * (long long)b.num[0][0] +
                 (long long)a.num[1][1] * (long long)b.num[1][0]) %
                1000000007;
  c.num[1][1] = ((long long)a.num[1][0] * (long long)b.num[0][1] +
                 (long long)a.num[1][1] * (long long)b.num[1][1]) %
                1000000007;
  return c;
}
void get(long long x) {
  B.num[0][0] = 1;
  B.num[0][1] = 0;
  B.num[1][0] = 0;
  B.num[1][1] = 1;
  if (x == 0) return;
  long long l = 1;
  while (l <= x) l <<= 1;
  l >>= 1;
  while (l) {
    B = B * B;
    if (x & l) B = B * A;
    l >>= 1;
  }
}
void build(int rt, int l, int r) {
  la[rt].num[0][0] = la[rt].num[1][1] = 1;
  la[rt].num[0][1] = la[rt].num[1][0] = 0;
  if (l == r) {
    get(t[l] - 1);
    s1[rt] = B.num[1][1];
    s2[rt] = B.num[0][1];
    return;
  }
  build((rt << 1), l, ((l + r) >> 1));
  build((rt << 1 | 1), ((l + r) >> 1) + 1, r);
  s1[rt] = (s1[(rt << 1)] + s1[(rt << 1 | 1)]) % 1000000007;
  s2[rt] = (s2[(rt << 1)] + s2[(rt << 1 | 1)]) % 1000000007;
}
int ok(matrix &a) {
  return (a.num[0][0] == 1 && a.num[1][1] == 1 && a.num[0][1] == 0 &&
          a.num[1][0] == 0);
}
void down(int rt) {
  if (ok(la[rt])) return;
  la[(rt << 1)] = la[(rt << 1)] * la[rt];
  la[(rt << 1 | 1)] = la[(rt << 1 | 1)] * la[rt];
  t1 = s1[(rt << 1)];
  t2 = s2[(rt << 1)];
  s1[(rt << 1)] = ((long long)la[rt].num[0][1] * (long long)t2 +
                   (long long)la[rt].num[1][1] * (long long)t1) %
                  1000000007;
  s2[(rt << 1)] = ((long long)la[rt].num[0][0] * (long long)t2 +
                   (long long)la[rt].num[0][1] * (long long)t1) %
                  1000000007;
  t1 = s1[(rt << 1 | 1)];
  t2 = s2[(rt << 1 | 1)];
  s1[(rt << 1 | 1)] = ((long long)la[rt].num[0][1] * (long long)t2 +
                       (long long)la[rt].num[1][1] * (long long)t1) %
                      1000000007;
  s2[(rt << 1 | 1)] = ((long long)la[rt].num[0][0] * (long long)t2 +
                       (long long)la[rt].num[0][1] * (long long)t1) %
                      1000000007;
  la[rt].num[0][0] = la[rt].num[1][1] = 1;
  la[rt].num[0][1] = la[rt].num[1][0] = 0;
}
void change(int rt, int l, int r, int L, int R, matrix e) {
  if (L <= l && R >= r) {
    t1 = s1[rt];
    t2 = s2[rt];
    s1[rt] = ((long long)e.num[0][1] * (long long)t2 +
              (long long)e.num[1][1] * (long long)t1) %
             1000000007;
    s2[rt] = ((long long)e.num[0][0] * (long long)t2 +
              (long long)e.num[0][1] * (long long)t1) %
             1000000007;
    la[rt] = la[rt] * e;
    return;
  }
  down(rt);
  if (L <= ((l + r) >> 1)) change((rt << 1), l, ((l + r) >> 1), L, R, e);
  if (R > ((l + r) >> 1)) change((rt << 1 | 1), ((l + r) >> 1) + 1, r, L, R, e);
  s1[rt] = (s1[(rt << 1)] + s1[(rt << 1 | 1)]) % 1000000007;
  s2[rt] = (s2[(rt << 1)] + s2[(rt << 1 | 1)]) % 1000000007;
}
void query(int rt, int l, int r, int L, int R) {
  if (L <= l && R >= r) {
    ans = (ans + s1[rt]) % 1000000007;
    return;
  }
  down(rt);
  if (L <= ((l + r) >> 1)) query((rt << 1), l, ((l + r) >> 1), L, R);
  if (R > ((l + r) >> 1)) query((rt << 1 | 1), ((l + r) >> 1) + 1, r, L, R);
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) scanf("%d", &t[i]);
  A.num[0][0] = 0;
  A.num[0][1] = 1;
  A.num[1][0] = 1;
  A.num[1][1] = 1;
  build(1, 1, n);
  for (int i = 1; i <= m; i++) {
    scanf("%d%d%d", &ty, &l, &r);
    if (ty == 1) {
      scanf("%d", &x);
      get((long long)x);
      e = B;
      change(1, 1, n, l, r, e);
    }
    if (ty == 2) {
      ans = 0;
      query(1, 1, n, l, r);
      printf("%d\n", ans);
    }
  }
  return 0;
}
