#include <bits/stdc++.h>
using namespace std;
struct node {
  int a[2][2];
  node() { a[0][0] = a[0][1] = a[1][0] = a[1][1] = 0; }
  int *operator[](const size_t &s) { return a[s]; }
};
node segTree[400008], L[400008];
node id, M, zero;
int a[100002];
int lazy[400008];
inline node operator+(node &a, node &b) {
  node res;
  for (int i = 0; i < 2; i++)
    for (int j = 0; j < 2; j++) res[i][j] = (a[i][j] + b[i][j]) % 1000000007;
  return res;
}
inline node operator*(node &a, node &b) {
  node res;
  for (int i = 0; i < 2; i++)
    for (int j = 0; j < 2; j++)
      for (int k = 0; k < 2; k++)
        res[i][j] =
            (res[i][j] + (1ll * a[i][k] * b[k][j]) % 1000000007) % 1000000007;
  return res;
}
inline node matPower(int n) {
  node res = id;
  node m = M;
  while (n > 0) {
    if (n & 1) res = res * m;
    m = m * m;
    n >>= 1;
  }
  return res;
}
inline void buildTree(int v, int s, int e) {
  L[v] = id;
  lazy[v] = 0;
  if (s == e) {
    segTree[v] = matPower(a[s]);
    return;
  }
  int m = (s + e) / 2;
  buildTree(2 * v, s, m);
  buildTree(2 * v + 1, m + 1, e);
  segTree[v] = segTree[2 * v] + segTree[2 * v + 1];
}
inline void propogate(int v, int l, int r) {
  if (lazy[v] > 0) {
    segTree[v] = segTree[v] * L[v];
    if (l != r) {
      lazy[2 * v] = lazy[2 * v + 1] = 1;
      L[2 * v] = L[2 * v] * L[v];
      L[2 * v + 1] = L[2 * v + 1] * L[v];
    }
    lazy[v] = 0;
    L[v] = id;
  }
  return;
}
inline void update(int v, int tl, int tr, int l, int r, node x) {
  propogate(v, tl, tr);
  if (l > r) return;
  if (tl == l && tr == r) {
    lazy[v] = 1;
    L[v] = x;
    propogate(v, tl, tr);
    return;
  }
  int tm = (tl + tr) / 2;
  update(2 * v, tl, tm, l, min(tm, r), x);
  update(2 * v + 1, tm + 1, tr, max(l, tm + 1), r, x);
  segTree[v] = segTree[2 * v] + segTree[2 * v + 1];
}
inline node query(int v, int tl, int tr, int l, int r) {
  propogate(v, tl, tr);
  if (l > r) return zero;
  if (tl == l && tr == r) return segTree[v];
  int tm = (tl + tr) / 2;
  node left = query(2 * v, tl, tm, l, min(tm, r));
  node right = query(2 * v + 1, tm + 1, tr, max(l, tm + 1), r);
  return (left + right);
}
int main() {
  id[0][0] = id[1][1] = 1;
  M[0][0] = M[0][1] = M[1][0] = 1;
  ios::sync_with_stdio(false);
  int n, m, q, l, r, x;
  cin >> n >> m;
  for (int i = 0; i < n; i++) cin >> a[i];
  buildTree(1, 0, n - 1);
  while (m--) {
    cin >> q;
    if (q == 1) {
      cin >> l >> r >> x;
      node val = matPower(x);
      update(1, 0, n - 1, l - 1, r - 1, val);
    } else {
      cin >> l >> r;
      cout << query(1, 0, n - 1, l - 1, r - 1)[0][1] << endl;
    }
  }
  return 0;
}
