#include <bits/stdc++.h>
using namespace std;
struct mat {
  int x[2][2];
  mat() { memset(x, 0, sizeof(x)); }
  void base() { x[0][0] = x[1][0] = x[0][1] = 1; }
  void operator=(const mat &R) {
    for (int i = 0; i < 2; ++i)
      for (int j = 0; j < 2; ++j) x[i][j] = R.x[i][j];
  }
  void Nurbol() {
    for (int i = 0; i < 2; i++)
      for (int j = 0; j < 2; j++) x[i][j] = (i == j);
  }
};
const int mod = 1000000007;
mat operator+(mat &a, mat &b) {
  mat res = mat();
  for (int i = 0; i < 2; ++i)
    for (int j = 0; j < 2; ++j)
      res.x[i][j] = (1ll * a.x[i][j] + b.x[i][j]) % mod;
  return res;
}
mat operator*(mat &a, mat &b) {
  mat res;
  for (int i = 0; i < 2; ++i)
    for (int j = 0; j < 2; ++j)
      for (int k = 0; k < 2; ++k)
        res.x[i][j] += (1ll * a.x[i][k] * b.x[k][j]) % mod, res.x[i][j] %= mod;
  return res;
}
mat binpow(long long x) {
  mat res;
  res.base();
  --x;
  mat base;
  base.base();
  while (x > 0) {
    if (x & 1) {
      res = res * base;
      --x;
    }
    x >>= 1;
    base = base * base;
  }
  return res;
}
mat T[(1 << 18) + 444];
mat add[(1 << 18) + 444];
int N, M;
int len;
void print(int x) {
  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < 2; ++j) printf("%d ", T[x].x[i][j]);
    printf("\n");
  }
  printf("\n");
}
void getInput() {
  scanf("%d %d", &N, &M);
  for (len = 1; len < N; len += len)
    ;
  for (int i = 0; i < N; ++i) {
    int x;
    scanf("%d", &x);
    T[i + len] = binpow(x);
    add[i + len].Nurbol();
  }
  for (int i = len - 1; i >= 1; --i) {
    T[i] = T[i + i] + T[i + i + 1];
    add[i].Nurbol();
  }
}
void push(int v) {
  if (v < len) {
    add[v + v] = add[v + v] * add[v];
    add[v + v + 1] = add[v + v + 1] * add[v];
    T[v + v] = T[v + v] * add[v];
    T[v + v + 1] = T[v + v + 1] * add[v];
  }
  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 2; j++) add[v].x[i][j] = (i == j);
  }
}
mat temp;
void upd(int l, int r, int skoka, int x, int y, int v) {
  push(v);
  if (y < l || x > r) return;
  if (l <= x && y <= r) {
    add[v] = temp;
    T[v] = T[v] * add[v];
    return;
  }
  int mid = (x + y) >> 1;
  upd(l, r, skoka, x, mid, v + v);
  upd(l, r, skoka, mid + 1, y, v + v + 1);
  T[v] = T[v + v] + T[v + v + 1];
}
mat emp;
mat sum(int l, int r, int x, int y, int v) {
  push(v);
  if (y < l || x > r) return emp;
  if (l <= x && y <= r) return T[v];
  int mid = (x + y) >> 1;
  mat lolside = sum(l, r, x, mid, v + v);
  mat darkside = sum(l, r, mid + 1, y, v + v + 1);
  return lolside + darkside;
}
void ratbek() {
  while (M-- > 0) {
    int x;
    scanf("%d", &x);
    int l, r, skoka;
    if (x == 1) {
      scanf("%d %d %d", &l, &r, &skoka);
      temp = binpow(skoka);
      upd(l, r, skoka, 1, len, 1);
    }
    if (x == 2) {
      scanf("%d %d", &l, &r);
      mat res = sum(l, r, 1, len, 1);
      printf("%d\n", res.x[0][1]);
    }
  }
}
void fox() {
  getInput();
  ratbek();
}
int main() {
  fox();
  return 0;
}
