#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
const long long mod = 1e9 + 7;
int n;
vector<long long> arr;
vector<pair<vector<long long>, vector<long long> > > segTree;
vector<long long> source(4, 1);
vector<long long> e(4);
vector<long long> multVec(const vector<long long>& vec,
                          const vector<long long>& mat) {
  vector<long long> result(2);
  result[0] = (vec[0] * mat[0] + vec[1] * mat[2]) % mod;
  result[1] = (vec[0] * mat[1] + vec[1] * mat[3]) % mod;
  return result;
}
vector<long long> multMat(const vector<long long>& a,
                          const vector<long long>& b) {
  vector<long long> result(4);
  result[0] = (a[0] * b[0] + a[1] * b[2]) % mod;
  result[1] = (a[0] * b[1] + a[1] * b[3]) % mod;
  result[2] = (a[2] * b[0] + a[3] * b[2]) % mod;
  result[3] = (a[2] * b[1] + a[3] * b[3]) % mod;
  return result;
}
vector<long long> binPow(vector<long long> a, long long b) {
  if (b == 0) {
    return e;
  }
  return multMat(binPow(multMat(a, a), b / 2), (b % 2 ? a : e));
}
vector<long long> fib(int idx) {
  vector<long long> res(2, 1);
  return multVec(res, binPow(source, idx - 1));
}
vector<long long> operator+(const vector<long long>& a,
                            const vector<long long>& b) {
  vector<long long> result(2);
  for (int i = 0; i < 2; i++) {
    result[i] = (a[i] + b[i]) % mod;
  }
  return result;
}
void build(int lf, int rg, int cell) {
  segTree[cell].second = e;
  if (lf + 1 == rg) {
    segTree[cell].first = fib(arr[lf]);
    return;
  }
  int middle = (lf + rg) >> 1;
  build(lf, middle, (cell << 1) + 1);
  build(middle, rg, (cell << 1) + 2);
  segTree[cell].first =
      segTree[(cell << 1) + 1].first + segTree[(cell << 1) + 2].first;
}
void push(int cell) {
  if (segTree[cell].second != e) {
    segTree[(cell << 1) + 1].first =
        multVec(segTree[(cell << 1) + 1].first, segTree[cell].second);
    segTree[(cell << 1) + 1].second =
        multMat(segTree[(cell << 1) + 1].second, segTree[cell].second);
    segTree[(cell << 1) + 2].first =
        multVec(segTree[(cell << 1) + 2].first, segTree[cell].second);
    segTree[(cell << 1) + 2].second =
        multMat(segTree[(cell << 1) + 2].second, segTree[cell].second);
    segTree[cell].second = e;
  }
}
void update(int lf, int rg, int a, int b, const vector<long long>& mat,
            int cell) {
  if (a >= b) {
    return;
  }
  if (lf == a && rg == b) {
    segTree[cell].first = multVec(segTree[cell].first, mat);
    segTree[cell].second = multMat(segTree[cell].second, mat);
    return;
  }
  push(cell);
  int middle = (lf + rg) >> 1;
  update(lf, middle, a, min(b, middle), mat, (cell << 1) + 1);
  update(middle, rg, max(a, middle), b, mat, (cell << 1) + 2);
  segTree[cell].first =
      segTree[(cell << 1) + 1].first + segTree[(cell << 1) + 2].first;
}
vector<long long> require(int lf, int rg, int a, int b, int cell) {
  if (a >= b) {
    return vector<long long>(2, 0);
  }
  if (lf == a && rg == b) {
    return segTree[cell].first;
  }
  push(cell);
  int middle = (lf + rg) >> 1;
  return require(lf, middle, a, min(b, middle), (cell << 1) + 1) +
         require(middle, rg, max(a, middle), b, (cell << 1) + 2);
}
void solve() {
  int m;
  cin >> n >> m;
  arr.resize(n);
  for (int i = 0; i < n; i++) {
    scanf("%I64d", &arr[i]);
  }
  source[0] = 0;
  e[0] = e[3] = 1;
  segTree.resize(4 * n);
  build(0, n, 0);
  for (int i = 0; i < m; i++) {
    int type;
    scanf("%d", &type);
    if (type == 1) {
      int lf, rg;
      long long x;
      scanf("%d%d%I64d", &lf, &rg, &x);
      update(0, n, lf - 1, rg, binPow(source, x), 0);
    } else {
      int lf, rg;
      scanf("%d%d", &lf, &rg);
      printf("%I64d\n", require(0, n, lf - 1, rg, 0)[0]);
    }
  }
}
int main() {
  solve();
  return 0;
}
