#include <bits/stdc++.h>
using namespace std;
struct Matrix {
  long long m[2][2];
  void clear() { memset(m, 0, sizeof(m)); }
  void init() {
    m[0][0] = m[1][1] = 1;
    m[0][1] = m[1][0] = 0;
  }
};
Matrix operator+(Matrix a, Matrix b) {
  int n = 2;
  Matrix ans;
  ans.clear();
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++) {
      ans.m[i][j] = a.m[i][j] + b.m[i][j];
      ans.m[i][j] %= 1000000007;
    }
  return ans;
}
Matrix operator*(Matrix a, Matrix b) {
  int n = 2;
  Matrix ans;
  ans.clear();
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
      for (int k = 0; k < n; k++) {
        ans.m[i][j] += a.m[i][k] * b.m[k][j];
        ans.m[i][j] %= 1000000007;
      }
  return ans;
}
Matrix operator^(Matrix a, int k) {
  Matrix c;
  c.init();
  for (; k; k >>= 1) {
    if (k & 1) c = c * a;
    a = a * a;
  }
  return c;
}
struct node {
  int l, r;
  Matrix x, sum;
} a[440000];
void build(int i, int l, int r) {
  a[i].l = l, a[i].r = r, a[i].x.init(), a[i].sum.clear();
  if (l == r) return;
  build(i * 2, l, l + r >> 1);
  build(i * 2 + 1, (l + r) / 2 + 1, r);
}
void update(int x) {
  a[x * 2].x = a[x * 2].x * a[x].x;
  a[x * 2].sum = a[x * 2].sum * a[x].x;
  a[x * 2 + 1].x = a[x * 2 + 1].x * a[x].x;
  a[x * 2 + 1].sum = a[x * 2 + 1].sum * a[x].x;
  a[x].x.init();
}
int flag = 0;
void change(int i, int x, int y, Matrix A) {
  int l = a[i].l, r = a[i].r, mid = l + r >> 1;
  if (x <= l && y >= r) {
    a[i].x = a[i].x * A;
    a[i].sum = a[i].sum * A;
    if (flag) a[i].sum = A;
    return;
  }
  update(i);
  if (y <= mid)
    change(i * 2, x, y, A);
  else if (x > mid)
    change(i * 2 + 1, x, y, A);
  else
    change(i * 2, x, mid, A), change(i * 2 + 1, mid + 1, y, A);
  a[i].sum = a[i * 2].sum + a[i * 2 + 1].sum;
}
Matrix query(int i, int x, int y) {
  int l = a[i].l, r = a[i].r, mid = l + r >> 1;
  if (x == l && y == r) return a[i].sum;
  update(i);
  if (y <= mid)
    return query(i * 2, x, y);
  else if (x > mid)
    return query(i * 2 + 1, x, y);
  else
    return query(i * 2, x, mid) + query(i * 2 + 1, mid + 1, y);
}
int main() {
  int n, m, x, y, z, c;
  scanf("%d%d", &n, &m);
  build(1, 1, n);
  Matrix A;
  flag = 1;
  for (int i = 1; i <= n; i++) {
    scanf("%d", &x);
    A.m[0][0] = 1, A.m[0][1] = 1, A.m[1][0] = 1, A.m[1][1] = 0;
    A = A ^ (x - 1);
    change(1, i, i, A);
  }
  flag = 0;
  while (m--) {
    scanf("%d%d%d", &z, &x, &y);
    if (z == 1) {
      scanf("%d", &c);
      A.m[0][0] = 1, A.m[0][1] = 1, A.m[1][0] = 1, A.m[1][1] = 0;
      A = A ^ c;
      change(1, x, y, A);
    } else {
      A = query(1, x, y);
      cout << A.m[0][0] % 1000000007 << '\n';
    }
  }
  return 0;
}
