#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e+5;
const long long mod = 1e9 + 7;
int a[maxn], n, m;
struct Mat {
  long long v[2][2];
  Mat() { memset(v, 0, sizeof(v)); }
  friend Mat operator*(Mat g, Mat b) {
    Mat c;
    for (int i = 0; i <= 1; i++)
      for (int j = 0; j <= 1; j++)
        for (int k = 0; k <= 1; k++)
          c.v[i][j] = (c.v[i][j] + g.v[i][k] * b.v[k][j]) % mod;
    return c;
  }
  friend Mat operator+(Mat g, Mat b) {
    for (int i = 0; i <= 1; i++)
      for (int j = 0; j <= 1; j++) g.v[i][j] = (g.v[i][j] + b.v[i][j]) % mod;
    return g;
  }
  friend Mat operator^(Mat g, int b) {
    Mat ans;
    ans.v[0][0] = ans.v[1][1] = 1LL;
    for (; b; b = b >> 1, g = g * g)
      if (b & 1) ans = ans * g;
    return ans;
  }
} T, F, M[maxn], laz[maxn];
inline void build(int rt, int l, int r) {
  laz[rt] = F;
  M[rt].v[0][1] = 1LL;
  if (l == r) {
    M[rt] = M[rt] * (T ^ a[l]);
    return;
  }
  build(rt << 1, l, ((l + r) >> 1)), build(rt << 1 | 1, ((l + r) >> 1) + 1, r);
  M[rt] = M[rt << 1] + M[rt << 1 | 1];
}
inline void pushdown(int rt, int l, int r) {
  if (l == r) return;
  laz[rt << 1] = laz[rt << 1] * laz[rt],
            laz[rt << 1 | 1] = laz[rt << 1 | 1] * laz[rt];
  M[rt << 1] = M[rt << 1] * laz[rt];
  M[rt << 1 | 1] = M[rt << 1 | 1] * laz[rt];
  laz[rt] = F;
}
inline void add(int rt, int l, int r, int xl, int xr, Mat x) {
  pushdown(rt, l, r);
  if (l == xl && r == xr) {
    M[rt] = M[rt] * x;
    laz[rt] = laz[rt] * x;
    return;
  }
  if (xr <= ((l + r) >> 1))
    add(rt << 1, l, ((l + r) >> 1), xl, xr, x);
  else if (xl > ((l + r) >> 1))
    add(rt << 1 | 1, ((l + r) >> 1) + 1, r, xl, xr, x);
  else
    add(rt << 1, l, ((l + r) >> 1), xl, ((l + r) >> 1), x),
        add(rt << 1 | 1, ((l + r) >> 1) + 1, r, ((l + r) >> 1) + 1, xr, x);
  M[rt] = M[rt << 1] + M[rt << 1 | 1];
}
inline long long query(int rt, int l, int r, int xl, int xr) {
  pushdown(rt, l, r);
  if (l == xl && r == xr) return M[rt].v[0][0];
  if (xr <= ((l + r) >> 1))
    return query(rt << 1, l, ((l + r) >> 1), xl, xr);
  else if (xl > ((l + r) >> 1))
    return query(rt << 1 | 1, ((l + r) >> 1) + 1, r, xl, xr);
  else
    return (query(rt << 1, l, ((l + r) >> 1), xl, ((l + r) >> 1)) +
            query(rt << 1 | 1, ((l + r) >> 1) + 1, r, ((l + r) >> 1) + 1, xr)) %
           mod;
}
int main() {
  scanf("%d%d", &n, &m);
  T.v[0][1] = T.v[1][0] = T.v[1][1] = 1LL;
  F.v[0][0] = F.v[1][1] = 1LL;
  for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
  build(1, 1, n);
  while (m--) {
    int opt, l, r, x;
    scanf("%d%d%d", &opt, &l, &r);
    if (opt == 1)
      scanf("%d", &x), add(1, 1, n, l, r, (T ^ x));
    else
      printf("%I64d\n", query(1, 1, n, l, r));
  }
}
