#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, T = 1 << 18, L = 2, mod = 1e9 + 7;
int raw[N];
int n, m;
struct matrix {
  int a[L][L];
  matrix() { memset(a, 0, sizeof a); }
  void init() {
    for (int i = 0; i < L; ++i)
      for (int j = 0; j < L; ++j) a[i][j] = (i == j ? 1 : 0);
  }
  matrix operator*(const matrix &b) {
    matrix ans;
    long long tmp;
    for (int i = 0; i < L; ++i)
      for (int j = 0; j < L; ++j) {
        tmp = 0;
        for (int k = 0; k < L; ++k) tmp += (long long)a[i][k] * b.a[k][j];
        ans.a[i][j] = tmp % mod;
      }
    return ans;
  }
  matrix operator+(const matrix &b) {
    matrix ans;
    for (int i = 0; i < L; ++i)
      for (int j = 0; j < L; ++j) {
        ans.a[i][j] = a[i][j] + b.a[i][j];
        if (ans.a[i][j] >= mod) ans.a[i][j] -= mod;
      }
    return ans;
  }
} sum[T], flag[T], fib;
bool used[T];
matrix qpow(matrix x, long long y) {
  matrix re;
  re.init();
  while (y > 0) {
    if (y & 1) re = re * x;
    x = x * x;
    y >>= 1;
  }
  return re;
}
void build(int x, int L, int R) {
  flag[x].init();
  if (L == R) {
    sum[x] = qpow(fib, raw[L]);
    return;
  }
  int mid = (L + R) >> 1;
  build(x << 1, L, mid);
  build(x << 1 | 1, mid + 1, R);
  sum[x] = sum[x << 1] + sum[x << 1 | 1];
}
void update(int x, int L, int R, int tl, int tr, matrix y) {
  if (L <= tl && tr <= R) {
    sum[x] = sum[x] * y;
    flag[x] = flag[x] * y;
    used[x] = 1;
    return;
  }
  int mid = (tl + tr) >> 1;
  if (used[x]) {
    update(x << 1, tl, mid, tl, mid, flag[x]);
    update(x << 1 | 1, mid + 1, tr, mid + 1, tr, flag[x]);
    flag[x].init();
    used[x] = 0;
  }
  if (L <= mid) update(x << 1, L, R, tl, mid, y);
  if (mid < R) update(x << 1 | 1, L, R, mid + 1, tr, y);
  sum[x] = sum[x << 1] + sum[x << 1 | 1];
}
int query(int x, int L, int R, int tl, int tr) {
  if (L <= tl && tr <= R) return sum[x].a[1][0];
  int mid = (tl + tr) >> 1;
  if (used[x]) {
    update(x << 1, tl, mid, tl, mid, flag[x]);
    update(x << 1 | 1, mid + 1, tr, mid + 1, tr, flag[x]);
    flag[x].init();
    used[x] = 0;
  }
  int re = 0;
  if (L <= mid) re += query(x << 1, L, R, tl, mid);
  if (mid < R) re += query(x << 1 | 1, L, R, mid + 1, tr);
  if (re >= mod) re -= mod;
  return re;
}
int main() {
  fib.a[0][0] = fib.a[0][1] = fib.a[1][0] = 1;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; ++i) scanf("%d", &raw[i]);
  build(1, 1, n);
  int op, l, r, x;
  while (m--) {
    scanf("%d", &op);
    if (op == 1) {
      scanf("%d%d%d", &l, &r, &x);
      update(1, l, r, 1, n, qpow(fib, x));
    } else {
      scanf("%d%d", &l, &r);
      printf("%d\n", query(1, l, r, 1, n));
    }
  }
  return 0;
}
