#include <bits/stdc++.h>
using namespace std;
const long long MAXN = 1e5 + 10;
const long long Mod = 1e9 + 7;
long long A[2][2];
long long B[2][2];
long long temp[2][2];
struct node {
  long long lazy[2][2], temp[2], res[2];
  node() {
    lazy[0][0] = 1;
    lazy[0][1] = 0;
    lazy[1][0] = 0;
    lazy[1][1] = 1;
    res[0] = 0;
    res[1] = 1;
  }
  void relax(long long C[2][2]) {
    for (int i = 0; i < 2; i++) {
      temp[i] = 0;
      for (int j = 0; j < 2; j++) {
        temp[i] += C[i][j] * res[j];
        temp[i] %= Mod;
      }
    }
    for (int i = 0; i < 2; i++) {
      res[i] = temp[i];
    }
  }
};
node segt[4 * MAXN];
int a[MAXN];
void mult(long long C[2][2], long long D[2][2], long long E[2][2]) {
  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 2; j++) {
      temp[i][j] = 0;
      for (int u = 0; u < 2; u++) {
        temp[i][j] += D[i][u] * E[u][j];
        temp[i][j] %= Mod;
      }
    }
  }
  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 2; j++) {
      D[i][j] = temp[i][j];
    }
  }
}
void matrix_pw(long long k) {
  if (k == 0) {
    return;
  }
  matrix_pw(k / 2);
  mult(A, A, A);
  if (k & 1) {
    mult(A, A, B);
  }
}
node merge_node(const node& x, const node& y) {
  node res;
  res.res[0] = x.res[0] + y.res[0];
  res.res[0] %= Mod;
  res.res[1] = x.res[1] + y.res[1];
  res.res[1] %= Mod;
  return res;
}
void lzu(int id) {
  segt[2 * id + 1].relax(segt[id].lazy);
  mult(segt[2 * id + 1].lazy, segt[2 * id + 1].lazy, segt[id].lazy);
  segt[2 * id + 2].relax(segt[id].lazy);
  mult(segt[2 * id + 2].lazy, segt[2 * id + 2].lazy, segt[id].lazy);
  segt[id].lazy[0][0] = 1;
  segt[id].lazy[0][1] = 0;
  segt[id].lazy[1][0] = 0;
  segt[id].lazy[1][1] = 1;
}
void update(int id, int L, int R, int l, int r) {
  if (L > r || R < l) {
    return;
  }
  if (L >= l && R <= r) {
    segt[id].relax(A);
    mult(segt[id].lazy, segt[id].lazy, A);
    return;
  }
  lzu(id);
  int mid = (L + R) / 2;
  update(2 * id + 1, L, mid, l, r);
  update(2 * id + 2, mid + 1, R, l, r);
  segt[id] = merge_node(segt[2 * id + 1], segt[2 * id + 2]);
}
long long get_res(int id, int L, int R, int l, int r) {
  if (L > r || R < l) {
    return 0;
  }
  if (L >= l && R <= r) {
    return segt[id].res[1];
  }
  lzu(id);
  int mid = (L + R) / 2;
  return (get_res(2 * id + 1, L, mid, l, r) +
          get_res(2 * id + 2, mid + 1, R, l, r)) %
         Mod;
}
int main() {
  int n, q;
  scanf("%d%d", &n, &q);
  B[0][0] = 0;
  B[0][1] = 1;
  B[1][0] = 1;
  B[1][1] = 1;
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
    A[0][0] = 1;
    A[0][1] = 0;
    A[1][0] = 0;
    A[1][1] = 1;
    matrix_pw(a[i] - 1);
    update(0, 1, n, i, i);
  }
  for (int i = 0; i < q; i++) {
    int type;
    scanf("%d", &type);
    if (type == 1) {
      int l, r, x;
      scanf("%d%d%d", &l, &r, &x);
      A[0][0] = 1;
      A[0][1] = 0;
      A[1][0] = 0;
      A[1][1] = 1;
      matrix_pw(x);
      update(0, 1, n, l, r);
    }
    if (type == 2) {
      int l, r;
      scanf("%d%d", &l, &r);
      printf("%I64d\n", get_res(0, 1, n, l, r));
    }
  }
}
