#include <bits/stdc++.h>
using namespace std;
char readc() {
  static char buf[100000], *p1 = buf, *p2 = buf;
  if (p1 == p2) p2 = (p1 = buf) + fread(buf, 1, 100000, stdin);
  if (p1 == p2) return EOF;
  return *p1++;
}
long long read() {
  long long x = 0, f = 1;
  char ch = readc();
  while (!isdigit(ch)) {
    if (ch == '0') f = -1;
    ch = readc();
  }
  while (isdigit(ch)) {
    x = x * 10 + ch - '0';
    ch = readc();
  }
  return x * f;
}
void write(long long x) {
  static int num[25], c = 0;
  if (x == 0) {
    putchar('0');
    return;
  }
  if (x < 0) {
    putchar('-');
    x = -x;
  }
  while (x) num[++c] = x % 10, x /= 10;
  while (c) putchar(num[c] + '0'), c--;
}
const long long mod = 1e9 + 7;
int N, M;
long long A[100050];
struct matrix {
  int a[3][3];
  matrix() { memset(a, 0, sizeof(a)); }
} E, X;
void init() {
  for (int i = 1; i < 3; i++) E.a[i][i] = 1;
  X.a[1][1] = 1, X.a[1][2] = 1, X.a[2][1] = 1;
}
matrix operator*(matrix a, matrix b) {
  matrix res;
  for (int i = 1; i < 3; i++) {
    for (int j = 1; j < 3; j++) {
      for (int h = 1; h < 3; h++) {
        res.a[i][j] += (long long)a.a[i][h] * b.a[h][j] % mod;
        res.a[i][j] %= mod;
      }
    }
  }
  return res;
}
matrix operator+(matrix a, matrix b) {
  matrix res;
  for (int i = 1; i < 3; i++) {
    for (int j = 1; j < 3; j++) {
      res.a[i][j] = a.a[i][j] + b.a[i][j];
      res.a[i][j] %= mod;
    }
  }
  return res;
}
matrix power(matrix x, long long y) {
  matrix res = E;
  while (y) {
    if (y & 1) res = res * x;
    x = x * x, y >>= 1;
  }
  return res;
}
void print(matrix x) {
  for (int i = 1; i < 3; i++) {
    for (int j = 1; j < 3; j++) {
      cerr << x.a[i][j] << ' ';
    }
    cerr << endl;
  }
}
struct node {
  matrix a, tag;
} seg[400050];
inline void pushup(int u) { seg[u].a = seg[u << 1].a + seg[u << 1 | 1].a; }
inline void change(int u, matrix d) {
  seg[u].a = seg[u].a * d;
  seg[u].tag = seg[u].tag * d;
}
inline void pushdown(int u) {
  change(u << 1, seg[u].tag);
  change(u << 1 | 1, seg[u].tag);
  seg[u].tag = E;
}
void build(int u, int l, int r) {
  seg[u].tag = E;
  if (l == r) {
    seg[u].a = power(X, A[l]);
    return;
  }
  int mid = (l + r) >> 1;
  build(u << 1, l, mid);
  build(u << 1 | 1, mid + 1, r);
  pushup(u);
}
matrix update_k;
void update(int u, int l, int r, int a, int b) {
  if (l == a && r == b) {
    change(u, update_k);
    return;
  }
  int mid = (l + r) >> 1;
  pushdown(u);
  if (b <= mid)
    update(u << 1, l, mid, a, b);
  else if (a > mid)
    update(u << 1 | 1, mid + 1, r, a, b);
  else {
    update(u << 1, l, mid, a, mid);
    update(u << 1 | 1, mid + 1, r, mid + 1, b);
  }
  pushup(u);
}
matrix query(int u, int l, int r, int a, int b) {
  if (l == a && r == b) return seg[u].a;
  int mid = (l + r) >> 1;
  pushdown(u);
  if (b <= mid)
    return query(u << 1, l, mid, a, b);
  else if (a > mid)
    return query(u << 1 | 1, mid + 1, r, a, b);
  else {
    matrix L = query(u << 1, l, mid, a, mid);
    matrix R = query(u << 1 | 1, mid + 1, r, mid + 1, b);
    return L + R;
  }
}
int main(int argc, char* argv[]) {
  init();
  N = read(), M = read();
  for (int i = 1; i <= N; i++) A[i] = read();
  build(1, 1, N);
  for (int i = 1; i <= M; i++) {
    int tp = read(), l = read(), r = read();
    if (tp == 1) {
      long long x = read();
      update_k = power(X, x);
      update(1, 1, N, l, r);
    }
    if (tp == 2) {
      matrix ans = query(1, 1, N, l, r);
      write(ans.a[2][1]);
      putchar('\n');
    }
  }
  return 0;
}
