#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:1024000000,1024000000")
const long long INF = 3e18;
const int inf = 0x3f3f3f3f;
const int M = 100010;
const int N = 100010;
const int Matsize = 2;
const long long MOD = 1000000007;
const double eps = 1e-3;
const double pi = acos(-1.0);
using namespace std;
struct Mat {
  long long mat[Matsize][Matsize];
  void init() {
    for (int i = 0; i < Matsize; i++) {
      for (int j = 0; j < Matsize; j++) mat[i][j] = 0;
      mat[i][i] = 1;
    }
  }
  Mat operator*(const Mat &t) const {
    Mat ans;
    memset(ans.mat, 0, sizeof(ans.mat));
    for (int k = 0; k < Matsize; k++)
      for (int i = 0; i < Matsize; i++)
        for (int j = 0; j < Matsize; j++)
          ans.mat[i][j] = (ans.mat[i][j] + mat[i][k] * t.mat[k][j]) % MOD;
    return ans;
  }
  Mat operator+(const Mat &t) const {
    Mat ans;
    for (int i = 0; i < Matsize; i++)
      for (int j = 0; j < Matsize; j++)
        ans.mat[i][j] = (mat[i][j] + t.mat[i][j]) % MOD;
    return ans;
  }
};
int n, m, op, l, r;
Mat a[N << 2], lazy[N << 2], mt;
long long x;
Mat pow_M(long long m) {
  Mat res;
  res.init();
  mt.mat[0][0] = mt.mat[0][1] = mt.mat[1][0] = 1, mt.mat[1][1] = 0;
  while (m) {
    if (m & 1) res = res * mt;
    mt = mt * mt;
    m >>= 1;
  }
  return res;
}
void pushup(int rt) { a[rt] = a[rt << 1] + a[rt << 1 | 1]; }
void pushdown(int rt) {
  lazy[rt << 1] = lazy[rt << 1] * lazy[rt];
  lazy[rt << 1 | 1] = lazy[rt << 1 | 1] * lazy[rt];
  a[rt << 1] = a[rt << 1] * lazy[rt];
  a[rt << 1 | 1] = a[rt << 1 | 1] * lazy[rt];
  lazy[rt].init();
}
void build(int l, int r, int rt) {
  a[rt].init();
  lazy[rt].init();
  if (l == r) {
    long long t;
    scanf("%I64d", &t);
    a[rt] = pow_M(t - 1);
    return;
  }
  int m = l + r >> 1;
  build(l, m, rt << 1);
  build(m + 1, r, rt << 1 | 1);
  pushup(rt);
}
void update(int L, int R, Mat x, int l, int r, int rt) {
  if (L <= l && r <= R) {
    a[rt] = a[rt] * x;
    lazy[rt] = lazy[rt] * x;
    return;
  }
  pushdown(rt);
  int m = l + r >> 1;
  if (L <= m) update(L, R, x, l, m, rt << 1);
  if (m < R) update(L, R, x, m + 1, r, rt << 1 | 1);
  pushup(rt);
}
long long query(int L, int R, int l, int r, int rt) {
  if (L <= l && r <= R) return a[rt].mat[0][0];
  pushdown(rt);
  int m = l + r >> 1;
  long long res = 0;
  if (L <= m) res = (res + query(L, R, l, m, rt << 1)) % MOD;
  if (m < R) res = (res + query(L, R, m + 1, r, rt << 1 | 1)) % MOD;
  return res;
}
int main() {
  scanf("%d%d", &n, &m);
  build(1, n, 1);
  while (m--) {
    scanf("%d", &op);
    if (op == 1) {
      scanf("%d%d%I64d", &l, &r, &x);
      Mat t = pow_M(x);
      update(l, r, t, 1, n, 1);
    } else {
      scanf("%d%d", &l, &r);
      printf("%I64d\n", query(l, r, 1, n, 1));
    }
  }
}
