#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5;
struct matrix {
  int val[3][3];
  matrix() { memset(val, 0, sizeof(val)); }
  matrix operator+(const matrix& x) {
    matrix res;
    for (int i = 1; i <= 2; i++)
      for (int j = 1; j <= 2; j++)
        res.val[i][j] = 1LL * (val[i][j] + x.val[i][j]) % 1000000007;
    return res;
  }
  matrix operator*(const matrix& x) {
    matrix res;
    for (int i = 1; i <= 2; i++)
      for (int j = 1; j <= 2; j++)
        for (int k = 1; k <= 2; k++)
          res.val[i][j] = 1LL *
                          (res.val[i][j] + 1LL * val[i][k] * x.val[k][j]) %
                          1000000007;
    return res;
  }
};
matrix F, T, IT[4 * maxn + 1], D[4 * maxn + 1], ans;
int n, m;
bool ok[4 * maxn + 1];
matrix Pow(matrix A, int k) {
  matrix B = T;
  for (; k; k /= 2, A = A * A)
    if (k & 1) B = B * A;
  return B;
}
void built(int k, int l, int r) {
  if (l == r) {
    int x;
    cin >> x;
    IT[k] = Pow(F, x - 1);
    D[k] = T;
    return;
  }
  int mid = (l + r) / 2;
  built(k * 2, l, mid);
  built(k * 2 + 1, mid + 1, r);
  IT[k] = IT[k * 2] + IT[k * 2 + 1];
  D[k] = T;
}
void Update(int k, int l, int r, int i, int j, matrix x) {
  if (i > r || j < l) return;
  if (i <= l && r <= j) {
    IT[k] = IT[k] * x;
    D[k] = D[k] * x;
    return;
  }
  int mid = (l + r) / 2;
  Update(k * 2, l, mid, i, j, x);
  Update(k * 2 + 1, mid + 1, r, i, j, x);
  IT[k] = IT[k * 2] + IT[k * 2 + 1];
  IT[k] = IT[k] * D[k];
}
void Query(int k, int l, int r, int i, int j, matrix x) {
  if (i > r || j < l) return;
  if (i <= l && r <= j) {
    ans = ans + IT[k] * x;
    return;
  }
  int mid = (l + r) / 2;
  Query(k * 2, l, mid, i, j, x * D[k]);
  Query(k * 2 + 1, mid + 1, r, i, j, x * D[k]);
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(NULL);
  cin >> n >> m;
  F.val[1][1] = F.val[1][2] = F.val[2][1] = 1;
  T.val[1][1] = T.val[2][2] = 1;
  built(1, 1, n);
  while (m--) {
    int type, l, r, X;
    cin >> type >> l >> r;
    if (type == 1) {
      cin >> X;
      matrix x = Pow(F, X);
      Update(1, 1, n, l, r, x);
    } else {
      memset(ans.val, 0, sizeof(ans.val));
      Query(1, 1, n, l, r, T);
      cout << ans.val[1][1] << "\n";
    }
  }
  return 0;
}
