#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;
struct mat {
  int A[2][2];
  mat() { memset(A, 0, sizeof(A)); }
};
int h;
int n, m;
int a[100055];
mat dat[200055];
mat lazy[200055];
bool updated[200055];
inline mat mul(mat &A, mat B) {
  mat C;
  for (int i = 0; i < 2; i++) {
    for (int k = 0; k < 2; k++) {
      for (int j = 0; j < 2; j++) {
        C.A[i][j] = (1ll * C.A[i][j] + 1ll * A.A[i][k] * B.A[k][j]) % MOD;
      }
    }
  }
  return C;
}
inline mat pow(int k) {
  mat A, B;
  A.A[0][0] = A.A[0][1] = 1;
  A.A[1][0] = 1, A.A[1][1] = 0;
  for (int i = 0; i < 2; i++) B.A[i][i] = 1;
  while (k > 0) {
    if (k & 1) B = mul(A, B);
    A = mul(A, A);
    k >>= 1;
  }
  return B;
}
inline mat add(mat &A, mat &B) {
  mat res;
  for (int i = 0; i < 2; i++)
    for (int j = 0; j < 2; j++) {
      res.A[i][j] = (A.A[i][j] + B.A[i][j]) % MOD;
    }
  return res;
}
void apply(int id, mat &A) {
  dat[id] = mul(dat[id], A);
  if (id < n) {
    updated[id] = true;
    lazy[id] = mul(lazy[id], A);
  }
}
void construct() {
  for (int id = n - 1; id > 0; id--) {
    dat[id] = add(dat[id + id], dat[id + id + 1]);
  }
}
void build(int id) {
  while (id > 1) {
    id >>= 1;
    dat[id] = mul(lazy[id], add(dat[id + id], dat[id + id + 1]));
  }
}
void push(int id) {
  for (int s = h; s > 0; s--) {
    int cur = id >> s;
    if (updated[cur]) {
      apply(cur + cur, lazy[cur]);
      apply(cur + cur + 1, lazy[cur]);
      updated[cur] = false;
      lazy[cur].A[0][0] = lazy[cur].A[1][1] = 1;
      lazy[cur].A[0][1] = lazy[cur].A[1][0] = 0;
    }
  }
}
void update(int l, int r, mat val) {
  l += n, r += n;
  int l_ = l, r_ = r;
  for (; l < r; l >>= 1, r >>= 1) {
    if (l & 1) apply(l++, val);
    if (r & 1) apply(--r, val);
  }
  build(l_);
  build(r_ - 1);
}
int query(int l, int r) {
  l += n, r += n;
  push(l);
  push(r - 1);
  int res = 0;
  for (; l < r; l >>= 1, r >>= 1) {
    if (l & 1) res = (res + dat[l++].A[1][0]) % MOD;
    if (r & 1) res = (res + dat[--r].A[1][0]) % MOD;
  }
  return res;
}
int main() {
  scanf("%d %d", &n, &m);
  h = sizeof(int) * 8 - __builtin_clz(n);
  for (int i = 0; i < n; i++) {
    scanf("%d", &a[i]);
    dat[n + i] = pow(a[i]);
  }
  for (int i = 0; i < n + n; i++) {
    lazy[i].A[0][0] = lazy[i].A[1][1] = 1;
  }
  construct();
  while (m--) {
    int ope, l, r;
    scanf("%d %d %d", &ope, &l, &r);
    l--;
    if (ope == 1) {
      int x;
      scanf("%d", &x);
      update(l, r, pow(x));
    } else {
      printf("%d\n", query(l, r));
    }
  }
  return 0;
}
