#include <bits/stdc++.h>
using namespace std;
long long MOD = 1000000007;
struct matrix {
  long long mat[2][2];
  int row, col;
  matrix() { row = 2, col = 2; }
  inline void setzero() { mat[0][0] = mat[0][1] = mat[1][0] = mat[1][1] = 0; }
  inline void setidentity() {
    mat[0][0] = mat[1][1] = 1;
    mat[0][1] = mat[1][0] = 0;
  }
  matrix(int a, int b) { row = a, col = b; }
  inline matrix operator*(const matrix &p) const {
    assert(col == p.row);
    matrix temp;
    temp.row = row;
    temp.col = p.col;
    temp.mat[0][0] =
        ((mat[0][0] * p.mat[0][0]) % MOD + (mat[0][1] * p.mat[1][0]) % MOD);
    temp.mat[0][1] =
        ((mat[0][0] * p.mat[0][1]) % MOD + (mat[0][1] * p.mat[1][1]) % MOD);
    temp.mat[1][0] =
        ((mat[1][0] * p.mat[0][0]) % MOD + (mat[1][1] * p.mat[1][0]) % MOD);
    temp.mat[1][1] =
        ((mat[1][0] * p.mat[0][1]) % MOD + (mat[1][1] * p.mat[1][1]) % MOD);
    if (temp.mat[0][0] >= MOD) temp.mat[0][0] -= MOD;
    if (temp.mat[0][1] >= MOD) temp.mat[0][1] -= MOD;
    if (temp.mat[1][0] >= MOD) temp.mat[1][0] -= MOD;
    if (temp.mat[1][1] >= MOD) temp.mat[1][1] -= MOD;
    return temp;
  }
  inline matrix operator+(const matrix &p) const {
    assert(row == p.row && col == p.col);
    matrix temp;
    temp.row = row;
    temp.col = col;
    temp.mat[0][0] = (mat[0][0] + p.mat[0][0]) % MOD;
    temp.mat[0][1] = (mat[0][1] + p.mat[0][1]) % MOD;
    temp.mat[1][0] = (mat[1][0] + p.mat[1][0]) % MOD;
    temp.mat[1][1] = (mat[1][1] + p.mat[1][1]) % MOD;
    return temp;
  }
  inline matrix pow(long long pow) {
    matrix temp = (*this);
    matrix ret;
    ret.setidentity();
    while (pow) {
      if (pow % 2 == 1) ret = ret * temp;
      temp = temp * temp;
      pow /= 2;
    }
    return ret;
  }
};
matrix base(2, 2);
struct data {
  matrix sum, mul;
  long long prop;
};
int ara[100005];
data tree[3 * 100005];
matrix faka(2, 2);
matrix check;
inline void init(int idx, int b, int e) {
  tree[idx].sum.setzero();
  tree[idx].mul.setidentity();
  if (b == e) {
    tree[idx].sum = base.pow(ara[b]);
    tree[idx].prop = 0;
    return;
  }
  int mid = (b + e) >> 1;
  int l = idx * 2;
  int r = l + 1;
  init(l, b, mid);
  init(r, mid + 1, e);
  tree[idx].sum = tree[l].sum + tree[r].sum;
  tree[idx].prop = 0;
}
inline void push_down(int idx, int b, int e) {
  if (tree[idx].prop != 0) {
    int l = idx * 2;
    int r = l + 1;
    tree[l].sum = tree[l].sum * tree[idx].mul;
    tree[r].sum = tree[r].sum * tree[idx].mul;
    tree[l].prop += tree[idx].prop;
    tree[r].prop += tree[idx].prop;
    tree[idx].prop = 0;
    tree[l].mul = tree[l].mul * tree[idx].mul;
    tree[r].mul = tree[r].mul * tree[idx].mul;
    tree[idx].mul.setidentity();
  }
}
inline void update(int idx, int b, int e, int i, int j, long long x) {
  if (b > j || e < i) return;
  if (b >= i && e <= j) {
    tree[idx].mul = tree[idx].mul * check;
    tree[idx].sum = tree[idx].sum * check;
    tree[idx].prop += x;
    return;
  }
  push_down(idx, b, e);
  int mid = (b + e) >> 1;
  int l = idx * 2;
  int r = l + 1;
  update(l, b, mid, i, j, x);
  update(r, mid + 1, e, i, j, x);
  tree[idx].sum = tree[l].sum + tree[r].sum;
}
inline long long query(int idx, int b, int e, int i, int j) {
  if (b > j || e < i) return 0;
  if (b >= i && e <= j) {
    return tree[idx].sum.mat[0][1];
  }
  push_down(idx, b, e);
  int mid = (b + e) >> 1;
  int l = idx * 2;
  int r = l + 1;
  long long p = query(l, b, mid, i, j);
  long long q = query(r, mid + 1, e, i, j);
  tree[idx].sum = tree[l].sum + tree[r].sum;
  if (p >= MOD) p -= MOD;
  if (q >= MOD) q -= MOD;
  p += q;
  if (p >= MOD) p -= MOD;
  return p;
}
int main() {
  base.mat[0][1] = base.mat[1][0] = base.mat[1][1] = 1;
  int n, m;
  scanf("%d %d\n", &n, &m);
  for (int i = 1; i <= n; i++) scanf("%d", &ara[i]);
  init(1, 1, n);
  while (m--) {
    int a, l, r, x;
    scanf("%d", &a);
    if (a == 1) {
      scanf("%d %d %d", &l, &r, &x);
      check = (base.pow(x));
      update(1, 1, n, l, r, x);
    } else {
      scanf("%d %d", &l, &r);
      printf("%lld\n", query(1, 1, n, l, r));
    }
  }
  return 0;
}
