#include <bits/stdc++.h>
using namespace std;
template <class T>
inline void read(T &x) {
  x = 0;
  char c = getchar();
  int f = 1;
  while (!isdigit(c)) {
    if (c == '-') f = -1;
    c = getchar();
  }
  while (isdigit(c)) x = x * 10 - '0' + c, c = getchar();
  x *= f;
}
template <class T>
void wrt(T x) {
  if (x >= 10) wrt(x / 10);
  putchar(x % 10 + '0');
}
const int mod = 1e9 + 7, N = 100010;
struct mat {
  int a[2][2];
  friend mat operator*(mat A, mat B) {
    mat res;
    res.a[0][0] = (A.a[0][0] * (long long)B.a[0][0] % mod +
                   A.a[0][1] * (long long)B.a[1][0]) %
                  mod;
    res.a[0][1] = (A.a[0][0] * (long long)B.a[0][1] % mod +
                   A.a[0][1] * (long long)B.a[1][1]) %
                  mod;
    res.a[1][0] = (A.a[1][0] * (long long)B.a[0][0] % mod +
                   A.a[1][1] * (long long)B.a[1][0]) %
                  mod;
    res.a[1][1] = (A.a[1][0] * (long long)B.a[0][1] % mod +
                   A.a[1][1] * (long long)B.a[1][1]) %
                  mod;
    return res;
  }
  friend mat operator+(mat A, mat B) {
    mat res;
    res.a[0][0] = (A.a[0][0] + B.a[0][0]) % mod;
    res.a[0][1] = (A.a[0][1] + B.a[0][1]) % mod;
    res.a[1][0] = (A.a[1][0] + B.a[1][0]) % mod;
    res.a[1][1] = (A.a[1][1] + B.a[1][1]) % mod;
    return res;
  }
} sum[N << 2], tag[N << 2], D, E, F;
mat Pow(mat x, int y) {
  mat res = E;
  while (y) {
    if (y & 1) res = res * x;
    x = x * x;
    y >>= 1;
  }
  return res;
}
int ql, qr, an, n, a[N];
void push_up(int c) { sum[c] = sum[c << 1] + sum[c << 1 | 1]; }
void push_down(int c) {
  sum[c << 1] = sum[c << 1] * tag[c], tag[c << 1] = tag[c << 1] * tag[c];
  sum[c << 1 | 1] = sum[c << 1 | 1] * tag[c],
               tag[c << 1 | 1] = tag[c << 1 | 1] * tag[c];
  tag[c] = E;
}
void build(int l, int r, int c) {
  tag[c] = E;
  if (l == r) {
    sum[c] = Pow(F, a[l]);
    return;
  }
  int mid = l + r >> 1;
  build(l, mid, c << 1), build(mid + 1, r, c << 1 | 1);
  push_up(c);
}
void add(int l, int r, int c) {
  if (ql <= l && qr >= r) {
    tag[c] = tag[c] * D, sum[c] = sum[c] * D;
    return;
  }
  int mid = l + r >> 1;
  push_down(c);
  if (ql <= mid) add(l, mid, c << 1);
  if (qr > mid) add(mid + 1, r, c << 1 | 1);
  push_up(c);
}
void query(int l, int r, int c) {
  if (ql <= l && qr >= r) {
    an = (an + sum[c].a[1][0]) % mod;
    return;
  }
  int mid = l + r >> 1;
  push_down(c);
  if (ql <= mid) query(l, mid, c << 1);
  if (qr > mid) query(mid + 1, r, c << 1 | 1);
}
int main() {
  int q, op, l, r, x;
  read(n), read(q);
  for (int i = 1; i <= n; ++i) read(a[i]);
  memset(E.a, 0, sizeof(E.a)), E.a[0][0] = E.a[1][1] = 1;
  memset(F.a, 0, sizeof(F.a)), F.a[0][0] = F.a[0][1] = F.a[1][0] = 1;
  build(1, n, 1);
  while (q--) {
    read(op), read(l), read(r);
    if (op == 1) {
      read(x), D = Pow(F, x);
      ql = l, qr = r;
      add(1, n, 1);
    } else {
      ql = l, qr = r, an = 0;
      query(1, n, 1);
      wrt(an), putchar('\n');
    }
  }
  return 0;
}
