#include <bits/stdc++.h>
using namespace std;
struct Mat {
  int a[2][2];
  void clear() { memset(a, 0, sizeof(a)); }
  void one() {
    a[0][0] = a[1][1] = 1;
    a[0][1] = a[1][0] = 0;
  }
  const Mat operator*(const Mat &b) const {
    Mat temp;
    temp.clear();
    for (int i = 0; i < 2; i++) {
      for (int j = 0; j < 2; j++) {
        for (int k = 0; k < 2; k++) {
          temp.a[i][j] += (long long)a[i][k] * b.a[k][j] % 1000000007;
          if (temp.a[i][j] >= 1000000007) temp.a[i][j] -= 1000000007;
        }
      }
    }
    return temp;
  }
  const Mat operator+(const Mat &b) const {
    Mat temp;
    temp.clear();
    for (int i = 0; i < 2; i++) {
      for (int j = 0; j < 2; j++) {
        temp.a[i][j] = a[i][j] + b.a[i][j];
        if (temp.a[i][j] >= 1000000007) temp.a[i][j] -= 1000000007;
      }
    }
    return temp;
  }
  Mat pw(int x) {
    Mat temp, num = *this;
    temp.one();
    while (x != 0) {
      if (x & 1) temp = temp * num;
      num = num * num;
      x >>= 1;
    }
    return temp;
  }
};
struct Tree {
  int l, r;
  Mat mult;
  Mat sum;
};
Tree seg[4 * 100000 + 5];
Mat tmp, fibo;
int a[100000 + 5];
void Down(int p) {
  seg[2 * p + 1].sum = seg[2 * p + 1].sum * seg[p].mult;
  seg[2 * p + 1].mult = seg[2 * p + 1].mult * seg[p].mult;
  seg[2 * p + 2].sum = seg[2 * p + 2].sum * seg[p].mult;
  seg[2 * p + 2].mult = seg[2 * p + 2].mult * seg[p].mult;
  seg[p].mult.one();
}
void build(int p, int l, int r) {
  seg[p].sum.clear();
  seg[p].mult.one();
  if (l == r) {
    seg[p].sum = fibo.pw(a[l]);
    return;
  }
  int mid = (l + r) >> 1;
  build(2 * p + 1, l, mid);
  build(2 * p + 2, mid + 1, r);
  seg[p].sum = seg[2 * p + 1].sum + seg[2 * p + 2].sum;
}
void update(int p, int l, int r, int ql, int qr) {
  if (l > qr || r < ql) return;
  if (l >= ql && r <= qr) {
    seg[p].sum = seg[p].sum * tmp;
    seg[p].mult = seg[p].mult * tmp;
    return;
  }
  Down(p);
  int mid = (l + r) >> 1;
  update(2 * p + 1, l, mid, ql, qr);
  update(2 * p + 2, mid + 1, r, ql, qr);
  seg[p].sum = seg[2 * p + 1].sum + seg[2 * p + 2].sum;
}
Mat query(int p, int l, int r, int ql, int qr) {
  if (l > qr || r < ql) {
    Mat emp;
    emp.clear();
    return emp;
  }
  if (l >= ql && r <= qr) return seg[p].sum;
  Down(p);
  int mid = (l + r) >> 1;
  Mat A = query(2 * p + 1, l, mid, ql, qr);
  Mat B = query(2 * p + 2, mid + 1, r, ql, qr);
  return A + B;
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  int i, j, n, m, ty, l, r, x;
  fibo.a[0][0] = fibo.a[0][1] = fibo.a[1][0] = 1;
  fibo.a[1][1] = 0;
  cin >> n >> m;
  for (i = 1; i <= n; i++) cin >> a[i];
  build(0, 1, n);
  while (m--) {
    cin >> ty;
    if (ty == 1) {
      cin >> l >> r >> x;
      tmp = fibo;
      tmp = tmp.pw(x);
      update(0, 1, n, l, r);
    } else {
      cin >> l >> r;
      Mat A = query(0, 1, n, l, r);
      cout << A.a[0][1] << '\n';
    }
  }
  return 0;
}
