#include <bits/stdc++.h>
using namespace std;
const int inf = (1 << 30) - 1;
const long long linf = (1ll << 62) - 1;
const int N = 1e5 + 100;
const int M = 1e9 + 7;
int n, m;
int a[N];
int rmq[N * 4 + 100][2];
int add[N * 4 + 100][2][2];
int result[2][2], mat[2][2];
inline void update(int i) {
  rmq[i][0] = (1ll * add[i * 2][0][0] * rmq[i * 2][0] +
               1ll * add[i * 2][0][1] * rmq[i * 2][1] +
               1ll * add[i * 2 + 1][0][0] * rmq[i * 2 + 1][0] +
               1ll * add[i * 2 + 1][0][1] * rmq[i * 2 + 1][1]) %
              M;
  rmq[i][1] = (1ll * add[i * 2][1][0] * rmq[i * 2][0] +
               1ll * add[i * 2][1][1] * rmq[i * 2][1] +
               1ll * add[i * 2 + 1][1][0] * rmq[i * 2 + 1][0] +
               1ll * add[i * 2 + 1][1][1] * rmq[i * 2 + 1][1]) %
              M;
}
void make_rmq(int i, int l, int r) {
  add[i][0][0] = add[i][1][1] = 1;
  add[i][0][1] = add[i][1][0] = 0;
  if (l == r) {
    rmq[i][0] = 0;
    rmq[i][1] = 1;
    return;
  }
  make_rmq(i * 2, l, (l + r) / 2);
  make_rmq(i * 2 + 1, (l + r) / 2 + 1, r);
  update(i);
}
inline void mult(int a[2][2], int b[2][2]) {
  static int c[2][2];
  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 2; j++) {
      long long result = 0;
      for (int z = 0; z < 2; z++) {
        result += 1ll * a[i][z] * b[z][j];
      }
      c[i][j] = result % M;
    }
  }
  memcpy(a, c, sizeof(c));
}
inline void power(int x) {
  result[0][0] = result[1][1] = 1;
  result[1][0] = result[0][1] = 0;
  mat[0][0] = mat[0][1] = mat[1][0] = 1;
  mat[1][1] = 0;
  for (; x; x >>= 1) {
    if (x & 1) {
      mult(result, mat);
    }
    mult(mat, mat);
  }
}
inline void update(int i, int ll, int rr, int l, int r) {
  if (ll > r || rr < l) {
    return;
  }
  if (l <= ll && rr <= r) {
    return void(mult(add[i], result));
  }
  update(i * 2, ll, (ll + rr) / 2, l, r);
  update(i * 2 + 1, (ll + rr) / 2 + 1, rr, l, r);
  update(i);
}
inline int madd(int a, int b) {
  if ((a += b) >= M) {
    a -= M;
  }
  return a;
}
inline void push(int i) {
  mult(add[i * 2], add[i]);
  mult(add[i * 2 + 1], add[i]);
  add[i][0][0] = add[i][1][1] = 1;
  add[i][1][0] = add[i][0][1] = 0;
  update(i);
}
inline pair<int, int> getSum(int i, int ll, int rr, int l, int r) {
  if (ll > r || rr < l) {
    return make_pair(0, 0);
  }
  if (l <= ll && rr <= r) {
    return make_pair(
        (1ll * add[i][0][0] * rmq[i][0] + 1ll * add[i][0][1] * rmq[i][1]) % M,
        (1ll * add[i][1][0] * rmq[i][1] + 1ll * add[i][1][1] * rmq[i][1]) % M);
  }
  push(i);
  auto r1 = getSum(i * 2, ll, (ll + rr) / 2, l, r);
  auto r2 = getSum(i * 2 + 1, (ll + rr) / 2 + 1, rr, l, r);
  return make_pair(madd(r1.first, r2.first), madd(r1.second, r2.second));
}
int main() {
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    scanf("%d", &a[i]);
  }
  make_rmq(1, 0, n - 1);
  for (int i = 0; i < n; i++) {
    power(a[i]);
    update(1, 0, n - 1, i, i);
  }
  for (int i = 0; i < m; i++) {
    int t, l, r;
    scanf("%d%d%d", &t, &l, &r), l--, r--;
    if (t == 1) {
      int x;
      scanf("%d", &x);
      power(x);
      update(1, 0, n - 1, l, r);
    } else {
      auto result = getSum(1, 0, n - 1, l, r);
      printf("%d\n", result.first);
    }
  }
  return 0;
}
