#include <bits/stdc++.h>
using namespace std;
const int MOD = (int)1e9 + 7;
const int N = (int)1e6 + 7;
int sum(int a, int b) { return (a + b) % MOD; }
void add(int& a, int b) { a = sum(a, b); }
int mul(int a, int b) { return (a * 1ll * b) % MOD; }
struct matrix {
  int f[2][2];
  int n, m;
  matrix() {
    f[0][0] = 0, f[0][1] = 0;
    f[1][0] = 0, f[1][1] = 0;
  }
  matrix(int fx, int fy, int sx, int sy, int _n, int _m) {
    f[0][0] = fx, f[0][1] = fy;
    f[1][0] = sx, f[1][1] = sy;
    n = _n, m = _m;
  }
};
matrix operator*(matrix x, matrix y) {
  matrix result;
  result.n = x.n, result.m = y.m;
  for (int i = 0; i < x.n; i++) {
    for (int j = 0; j < y.m; j++) {
      for (int k = 0; k < x.m; k++) {
        add(result.f[i][j], mul(x.f[i][k], y.f[k][j]));
      }
    }
  }
  return result;
}
matrix operator+(matrix x, matrix y) {
  matrix result;
  result.n = x.n, result.m = y.m;
  for (int i = 0; i < x.n; i++) {
    for (int j = 0; j < y.m; j++) {
      add(result.f[i][j], sum(x.f[i][j], y.f[i][j]));
    }
  }
  return result;
}
const matrix STEP = matrix(0, 1, 1, 1, 2, 2);
const matrix ONE = matrix(1, 0, 0, 1, 2, 2);
const matrix START = matrix(0, 0, 1, 0, 2, 1);
const matrix ZERO = matrix(0, 0, 0, 0, 2, 2);
matrix bin_pow(matrix x, int n) {
  matrix result = x;
  n--;
  while (n) {
    if (n & 1) {
      result = result * x;
      n--;
    } else {
      x = x * x;
      n >>= 1;
    }
  }
  return result;
}
int a[N];
matrix t[N * 4], z[N * 4];
int n, m;
void build(int v, int tl, int tr) {
  if (tl == tr) {
    t[v] = bin_pow(STEP, a[tl]);
  } else {
    int tm = (tl + tr) >> 1;
    build(v + v, tl, tm);
    build(v + v + 1, tm + 1, tr);
    t[v] = t[v + v] + t[v + v + 1];
  }
}
void push(int v, int tl, int tr) {
  if (v + v + 1 < N * 4) {
    z[v + v] = z[v + v] * z[v];
    z[v + v + 1] = z[v + v + 1] * z[v];
    t[v + v] = t[v + v] * z[v];
    t[v + v + 1] = t[v + v + 1] * z[v];
    z[v] = ONE;
  }
}
void update(int v, int tl, int tr, int l, int r, matrix x) {
  if (l <= tl && r >= tr) {
    t[v] = t[v] * x;
    z[v] = z[v] * x;
    return;
  }
  if (l > tr || r < tl) {
    return;
  }
  int tm = (tl + tr) >> 1;
  push(v, tl, tr);
  update(v + v, tl, tm, l, r, x);
  update(v + v + 1, tm + 1, tr, l, r, x);
  t[v] = t[v + v] + t[v + v + 1];
}
matrix get(int v, int tl, int tr, int l, int r) {
  if (l <= tl && r >= tr) return t[v];
  if (l > tr || r < tl) return ZERO;
  int tm = (tl + tr) >> 1;
  push(v, tl, tr);
  return get(v + v, tl, tm, l, r) + get(v + v + 1, tm + 1, tr, l, r);
}
int extract(int l, int r) {
  matrix result = get(1, 1, n, l, r);
  result = result * START;
  return result.f[0][0];
}
int main() {
  for (int i = 0; i < N * 4; i++) z[i] = ONE;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
  build(1, 1, n);
  for (int i = 1; i <= m; ++i) {
    int tp;
    scanf("%d", &tp);
    if (tp == 1) {
      int l, r, x;
      scanf("%d%d%d", &l, &r, &x);
      matrix cur = bin_pow(STEP, x);
      update(1, 1, n, l, r, cur);
    } else {
      int l, r;
      scanf("%d%d", &l, &r);
      printf("%d\n", extract(l, r));
    }
  }
  return 0;
}
