#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;
struct mat {
  int a[2][2];
  mat() { memset(a, 0, sizeof(a)); }
  mat(int) {
    memset(a, 0, sizeof(a));
    a[0][0] = a[1][1] = 1;
  }
};
mat operator+(const mat &a, const mat &b) {
  mat c = mat();
  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < 2; ++j) {
      c.a[i][j] = (a.a[i][j] + b.a[i][j]) % MOD;
    }
  }
  return c;
}
mat operator*(const mat &a, const mat &b) {
  mat c = mat();
  for (int k = 0; k < 2; ++k) {
    for (int i = 0; i < 2; ++i) {
      for (int j = 0; j < 2; ++j) {
        (c.a[i][j] += 1LL * a.a[i][k] * b.a[k][j] % MOD) %= MOD;
      }
    }
  }
  return c;
}
struct node {
  mat a, lazy;
  node() {
    a = mat();
    lazy = mat(1);
  }
  void work(mat x) {
    a = a * x;
    lazy = lazy * x;
  }
};
node operator+(const node &a, const node &b) {
  node tmp = node();
  tmp.a = a.a + b.a;
  return tmp;
}
const int N = 1e5 + 5;
node tree[N * 4];
void down(int x) {
  tree[x + x].work(tree[x].lazy);
  tree[x + x + 1].work(tree[x].lazy);
  tree[x].lazy = mat(1);
}
void add(int x, int l, int r, int ql, int qr, mat c) {
  if (l > qr || r < ql) return;
  if (l >= ql && r <= qr) {
    tree[x].work(c);
    return;
  }
  int mid = (l + r) / 2;
  down(x);
  add(x + x, l, mid, ql, qr, c);
  add(x + x + 1, mid + 1, r, ql, qr, c);
  tree[x] = tree[x + x] + tree[x + x + 1];
}
mat query(int x, int l, int r, int ql, int qr) {
  if (l > qr || r < ql) return mat();
  if (l >= ql && r <= qr) return tree[x].a;
  down(x);
  int mid = (l + r) / 2;
  return query(x + x, l, mid, ql, qr) + query(x + x + 1, mid + 1, r, ql, qr);
}
mat mpow(mat x, int n) {
  mat res = mat(1);
  while (n) {
    if (n & 1) res = res * x;
    x = x * x;
    n >>= 1;
  }
  return res;
}
int a[N];
mat unit;
void build(int x, int l, int r) {
  if (l == r) {
    tree[x] = node();
    tree[x].a = mpow(unit, a[l]);
    return;
  }
  int mid = (l + r) / 2;
  build(x + x, l, mid);
  build(x + x + 1, mid + 1, r);
  tree[x] = tree[x + x] + tree[x + x + 1];
}
int main() {
  unit.a[0][0] = unit.a[1][0] = unit.a[0][1] = 1;
  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
  build(1, 1, n);
  for (int i = 1; i <= m; ++i) {
    int type;
    scanf("%d", &type);
    if (type == 1) {
      int l, r, x;
      scanf("%d%d%d", &l, &r, &x);
      add(1, 1, n, l, r, mpow(unit, x));
    } else {
      int l, r;
      scanf("%d%d", &l, &r);
      mat res = query(1, 1, n, l, r);
      printf("%d\n", res.a[1][0]);
    }
  }
}
