#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
struct matrix {
  long long a[4][4];
  matrix() { memset(a, 0, sizeof(a)); }
} m1, tag[400100], f[400100], init[100100];
int n, m;
bool yes[400100];
matrix operator*(matrix x, matrix y) {
  matrix res;
  for (int i = 1; i <= 2; i++)
    for (int j = 1; j <= 2; j++)
      for (int k = 1; k <= 2; k++)
        res.a[i][j] = (res.a[i][j] + x.a[i][k] * y.a[k][j]) % mod;
  return res;
}
matrix operator+(matrix x, matrix y) {
  matrix res;
  res.a[1][1] = (x.a[1][1] + y.a[1][1]) % mod;
  res.a[2][1] = (x.a[2][1] + y.a[2][1]) % mod;
  return res;
}
matrix ksm(matrix m, int y) {
  matrix res;
  res.a[1][1] = res.a[2][2] = 1;
  while (y) {
    if (y & 1) res = m * res;
    m = m * m;
    y >>= 1;
  }
  return res;
}
void build(int l, int r, int num) {
  tag[num].a[1][1] = tag[num].a[2][2] = 1;
  tag[num].a[1][2] = tag[num].a[2][1] = 0;
  if (l == r) {
    f[num] = init[l];
    return;
  }
  int mid = (l + r) >> 1;
  build(l, mid, num << 1);
  build(mid + 1, r, num << 1 | 1);
  f[num] = f[num << 1] + f[num << 1 | 1];
}
void pushdown(int num) {
  if (yes[num]) {
    yes[num << 1] = yes[num << 1 | 1] = 1;
    tag[num << 1] = tag[num << 1] * tag[num];
    tag[num << 1 | 1] = tag[num << 1 | 1] * tag[num];
    f[num << 1] = tag[num] * f[num << 1];
    f[num << 1 | 1] = tag[num] * f[num << 1 | 1];
    tag[num].a[1][1] = tag[num].a[2][2] = 1;
    tag[num].a[1][2] = tag[num].a[2][1] = 0;
    yes[num] = 0;
  }
}
void change(int l, int r, int num, int cl, int cr, matrix m) {
  if ((cl <= l) && (r <= cr)) {
    f[num] = m * f[num];
    tag[num] = tag[num] * m;
    yes[num] = 1;
    return;
  }
  pushdown(num);
  int mid = (l + r) >> 1;
  if (cl <= mid) change(l, mid, num << 1, cl, cr, m);
  if (cr > mid) change(mid + 1, r, num << 1 | 1, cl, cr, m);
  f[num] = f[num << 1] + f[num << 1 | 1];
}
long long query(int l, int r, int num, int ql, int qr) {
  if ((ql <= l) && (r <= qr)) return f[num].a[1][1];
  pushdown(num);
  int mid = (l + r) >> 1;
  long long ans = 0;
  if (ql <= mid) ans = query(l, mid, num << 1, ql, qr);
  if (qr > mid) ans = (ans + query(mid + 1, r, num << 1 | 1, ql, qr)) % mod;
  f[num] = f[num << 1] + f[num << 1 | 1];
  return ans;
}
int main() {
  int i, j, k, x, y, op, z;
  scanf("%d%d", &n, &m);
  for (i = 1; i <= n; i++) {
    scanf("%d", &x);
    m1.a[1][1] = m1.a[1][2] = m1.a[2][1] = 1;
    m1.a[2][2] = 0;
    m1 = ksm(m1, x - 1);
    init[i].a[1][1] = m1.a[1][1];
    init[i].a[2][1] = m1.a[2][1];
  }
  build(1, n, 1);
  for (i = 1; i <= m; i++) {
    scanf("%d%d%d", &op, &x, &y);
    if (op == 1) {
      scanf("%d", &z);
      m1.a[1][1] = m1.a[1][2] = m1.a[2][1] = 1;
      m1.a[2][2] = 0;
      m1 = ksm(m1, z);
      change(1, n, 1, x, y, m1);
    } else
      printf("%I64d\n", query(1, n, 1, x, y));
  }
  return 0;
}
