#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
const int mo = 1e9 + 7;
struct mat {
  int n, m, a[2][2];
  mat operator+(const mat &b) {
    mat ans;
    ans.n = n;
    ans.m = m;
    for (int i = 0; i < ans.n; i++) {
      for (int j = 0; j < ans.m; j++) {
        ans.a[i][j] = (a[i][j] + b.a[i][j]) % mo;
      }
    }
    return ans;
  }
  mat operator*(const mat &b) {
    mat ans;
    ans.n = n;
    ans.m = b.m;
    for (int i = 0; i < ans.n; i++) {
      for (int j = 0; j < ans.m; j++) {
        ans.a[i][j] = 0;
        for (int k = 0; k < m; k++) {
          (ans.a[i][j] += a[i][k] * 1ll * b.a[k][j] % mo) %= mo;
        }
      }
    }
    return ans;
  }
  void operator+=(const mat &b) { *this = *this + b; }
  void operator*=(const mat &b) { *this = *this * b; }
  bool ise() {
    return n == 2 && m == 2 && a[0][0] == 1 && a[1][1] == 1 && !a[2][1] &&
           !a[1][2];
  }
} e, t;
static mat s[N << 2], tag[N << 2];
mat mpow(mat x, long long y) {
  static mat ans;
  ans = e;
  for (; y >= 1; y >>= 1, x *= x)
    if (y & 1) ans *= x;
  return ans;
}
int n, q, a[N];
void build(int u, int l, int r) {
  tag[u] = e;
  if (l == r) {
    s[u].n = 1;
    s[u].m = 2;
    s[u].a[0][0] = 1;
    s[u].a[0][1] = 0;
    if (a[l] > 1) {
      s[u] *= mpow(t, a[l] - 1);
    }
    return;
  }
  int mid = (l + r) >> 1;
  build(u << 1, l, mid);
  build(u << 1 | 1, mid + 1, r);
  s[u] = s[u << 1] + s[u << 1 | 1];
}
void pd(int u) {
  if (tag[u].ise()) return;
  tag[u << 1] *= tag[u];
  tag[u << 1 | 1] *= tag[u];
  s[u << 1] *= tag[u];
  s[u << 1 | 1] *= tag[u];
  tag[u] = e;
}
mat now;
void upd(int u, int l, int r, int ql, int qr) {
  if (l != r) pd(u);
  if (l == ql && r == qr) {
    tag[u] = now;
    s[u] *= now;
    return;
  }
  int mid = (l + r) >> 1;
  if (qr <= mid)
    upd(u << 1, l, mid, ql, qr);
  else if (ql > mid)
    upd(u << 1 | 1, mid + 1, r, ql, qr);
  else {
    upd(u << 1, l, mid, ql, mid);
    upd(u << 1 | 1, mid + 1, r, mid + 1, qr);
  }
  s[u] = s[u << 1] + s[u << 1 | 1];
}
int qry(int u, int l, int r, int ql, int qr) {
  if (l == ql && r == qr) return s[u].a[0][0];
  int mid = (l + r) >> 1;
  pd(u);
  if (qr <= mid) return qry(u << 1, l, mid, ql, qr);
  if (ql > mid) return qry(u << 1 | 1, mid + 1, r, ql, qr);
  return (qry(u << 1, l, mid, ql, mid) +
          qry(u << 1 | 1, mid + 1, r, mid + 1, qr)) %
         mo;
}
int main() {
  e.n = e.m = 2;
  e.a[0][0] = e.a[1][1] = 1;
  e.a[0][1] = e.a[1][0] = 0;
  t.n = t.m = 2;
  t.a[0][0] = t.a[1][0] = t.a[0][1] = 1;
  t.a[1][1] = 0;
  scanf("%d%d", &n, &q);
  for (int i = 1; i <= n; i++) scanf("%d", a + i);
  build(1, 1, n);
  int op, l, r, x;
  for (int i = 1; i <= q; i++) {
    scanf("%d%d%d", &op, &l, &r);
    if (op == 1) {
      scanf("%d", &x);
      now = mpow(t, x);
      upd(1, 1, n, l, r);
    }
    if (op == 2) {
      printf("%d\n", qry(1, 1, n, l, r));
    }
  }
  return 0;
}
