#include <bits/stdc++.h>
using namespace std;
struct matrix {
  unsigned long long a, b, c, d;
  matrix() { a = b = c = d = 0; }
  bool operator!=(matrix other) const {
    if (a != other.a || b != other.b || c != other.c || d != other.d)
      return true;
    return false;
  }
  bool operator==(matrix other) const {
    if (a == other.a && b == other.b && c == other.c && d == other.d)
      return true;
    return false;
  }
};
matrix ans;
unsigned long long ar[400004];
matrix segtree[400004];
matrix lpar[400004];
matrix cotamax;
matrix id;
inline matrix MultMatrix(matrix M, matrix N) {
  matrix res;
  res.a = ((M.a) * (N.a) + (M.b) * (N.c)) % 1000000007;
  res.b = ((M.a) * (N.b) + (M.b) * (N.d)) % 1000000007;
  res.c = ((M.c) * (N.a) + (M.d) * (N.c)) % 1000000007;
  res.d = ((M.c) * (N.b) + (M.d) * (N.d)) % 1000000007;
  return res;
}
inline matrix sqrMatrix(matrix M) {
  matrix res;
  res.a = ((M.a) * (M.a) + (M.b) * (M.c)) % 1000000007;
  res.b = ((M.a) * (M.b) + (M.b) * (M.d)) % 1000000007;
  res.c = ((M.c) * (M.a) + (M.d) * (M.c)) % 1000000007;
  res.d = ((M.c) * (M.b) + (M.d) * (M.d)) % 1000000007;
  return res;
}
matrix binpow(unsigned long long n) {
  if (n == 1)
    return ans;
  else if (!(n & 1))
    return sqrMatrix(binpow(n / 2));
  else if (n & 1)
    return MultMatrix(ans, binpow(n - 1));
}
inline matrix sum(matrix N, matrix M) {
  matrix res;
  res.a = ((M.a) + (N.a)) % 1000000007;
  res.b = ((M.b) + (N.b)) % 1000000007;
  res.c = ((M.c) + (N.c)) % 1000000007;
  res.d = ((M.d) + (N.d)) % 1000000007;
  return res;
}
void ctree(int lw, int hi, int pos) {
  if (lw == hi) {
    segtree[pos] = binpow(ar[lw] + 1);
    return;
  }
  int mid = (lw + hi) >> 1;
  ctree(lw, mid, (pos << 1));
  ctree(mid + 1, hi, ((pos << 1) | 1));
  segtree[pos] = sum(segtree[pos << 1], segtree[(pos << 1) | 1]);
}
inline void lpsegtree(int ini, int fin, unsigned long long pes, int lw, int hi,
                      int pos) {
  if (lpar[pos] != id) {
    segtree[pos] = MultMatrix(segtree[pos], lpar[pos]);
    if (lw != hi) {
      lpar[pos << 1] = MultMatrix(lpar[pos << 1], lpar[pos]);
      lpar[pos << 1 | 1] = MultMatrix(lpar[pos << 1 | 1], lpar[pos]);
    }
    lpar[pos] = id;
  }
  if (ini > hi || fin < lw) return;
  if (ini <= lw && fin >= hi) {
    matrix tmp = binpow(pes);
    segtree[pos] = MultMatrix(segtree[pos], tmp);
    if (lw != hi) {
      lpar[pos << 1] = MultMatrix(lpar[pos << 1], tmp);
      lpar[pos << 1 | 1] = MultMatrix(lpar[pos << 1 | 1], tmp);
    }
    return;
  }
  int mid = (lw + hi) >> 1;
  lpsegtree(ini, fin, pes, lw, mid, pos << 1);
  lpsegtree(ini, fin, pes, mid + 1, hi, (pos << 1) | 1);
  segtree[pos] = sum(segtree[pos << 1], segtree[(pos << 1) | 1]);
}
matrix minlprange(int plw, int phi, int lw, int hi, int pos) {
  if (plw > hi || phi < lw) return cotamax;
  if (lpar[pos] != id) {
    segtree[pos] = MultMatrix(segtree[pos], lpar[pos]);
    if (lw != hi) {
      lpar[pos << 1] = MultMatrix(lpar[pos << 1], lpar[pos]);
      lpar[(pos << 1) | 1] = MultMatrix(lpar[pos << 1 | 1], lpar[pos]);
    }
    lpar[pos] = id;
  }
  if (plw <= lw && phi >= hi) return segtree[pos];
  int mid = (lw + hi) >> 1;
  return sum(minlprange(plw, phi, lw, mid, pos << 1),
             minlprange(plw, phi, mid + 1, hi, (pos << 1) | 1));
}
int main() {
  ans.a = 0;
  ans.b = 1;
  ans.c = 1;
  ans.d = 1;
  id.a = 1;
  id.b = 0;
  id.c = 0;
  id.d = 1;
  int n, m;
  scanf("%d %d", &n, &m);
  for (int(i) = (1); (i) < (n + 1); (i)++) {
    unsigned long long a;
    scanf("%I64d", &a);
    ar[i] = a;
  }
  for (int i = 0; i < 4 * n + 2; ++i) lpar[i] = id;
  ctree(1, n, 1);
  for (int(i) = (0); (i) < (m); (i)++) {
    int d;
    scanf("%d", &d);
    if (d == 1) {
      int l, r;
      unsigned long long k;
      scanf("%d %d %I64d", &l, &r, &k);
      lpsegtree(l, r, k, 1, n, 1);
    }
    if (d == 2) {
      int l, r;
      scanf("%d %d", &l, &r);
      printf("%I64d\n", minlprange(l, r, 1, n, 1).a);
    }
  }
  return 0;
}
