#include <bits/stdc++.h>
using namespace std;
int read() {
  char ch = getchar();
  int x = 0, pd = 0;
  while (ch < '0' || ch > '9') pd ^= ch == '-', ch = getchar();
  while ('0' <= ch && ch <= '9') x = x * 10 + (ch ^ 48), ch = getchar();
  return pd ? -x : x;
}
const int mod = 1000000007;
int add(int x, int y) { return x + y < mod ? x + y : x + y - mod; }
int mul(int x, int y) { return 1ll * x * y % mod; }
const int maxn = 100005;
const int B = 50;
int n, m;
struct Matrix {
  int a[2][2];
  void clear() { memset(a, 0, sizeof(a)); }
  void init() {
    clear();
    a[0][0] = a[1][1] = 1;
  }
  void trans() { a[0][0] = a[0][1] = a[1][0] = 1, a[1][1] = 0; }
  Matrix operator+(const Matrix &oth) const {
    Matrix t;
    t.clear();
    for (int i = 0; i < 2; i++)
      for (int j = 0; j < 2; j++) t.a[i][j] = add(a[i][j], oth.a[i][j]);
    return t;
  }
  Matrix operator*(const Matrix &oth) const {
    Matrix t;
    t.clear();
    for (int i = 0; i < 2; i++)
      for (int k = 0; k < 2; k++)
        if (a[i][k])
          for (int j = 0; j < 2; j++)
            t.a[i][j] = add(t.a[i][j], mul(a[i][k], oth.a[k][j]));
    return t;
  }
};
Matrix p[B + 2];
void pre() {
  p[0].trans();
  for (int i = 1; i <= B; i++) p[i] = p[i - 1] * p[i - 1];
}
Matrix quickpow(long long x) {
  Matrix res;
  res.init();
  for (int y = 0; x; x >>= 1, ++y)
    if (x & 1) res = res * p[y];
  return res;
}
Matrix sum[maxn << 2];
long long tag[maxn << 2];
void pushup(int o) { sum[o] = sum[(o << 1)] + sum[(o << 1 | 1)]; }
void pushdown(int o) {
  Matrix t = quickpow(o[tag]);
  sum[(o << 1)] = sum[(o << 1)] * t, (o << 1)[tag] += o[tag];
  sum[(o << 1 | 1)] = sum[(o << 1 | 1)] * t, (o << 1 | 1)[tag] += o[tag];
  o[tag] = 0;
}
void build(int o, int l, int r) {
  if (l == r) {
    sum[o].a[0][0] = 1;
    sum[o] = sum[o] * quickpow(read() - 1);
    return;
  }
  int mid = (l + r) >> 1;
  build((o << 1), l, mid), build((o << 1 | 1), mid + 1, r);
  pushup(o);
}
int k;
Matrix tmp;
void upd(int o, int l, int r, int L, int R) {
  if (L <= l && r <= R) {
    sum[o] = sum[o] * tmp, tag[o] += k;
    return;
  }
  int mid = (l + r) >> 1;
  if (o[tag]) pushdown(o);
  if (L <= mid) upd((o << 1), l, mid, L, R);
  if (R > mid) upd((o << 1 | 1), mid + 1, r, L, R);
  pushup(o);
}
Matrix query(int o, int l, int r, int L, int R) {
  if (L <= l && r <= R) return sum[o];
  int mid = (l + r) >> 1;
  if (o[tag]) pushdown(o);
  if (R <= mid) return query((o << 1), l, mid, L, R);
  if (L > mid) return query((o << 1 | 1), mid + 1, r, L, R);
  return query((o << 1), l, mid, L, R) + query((o << 1 | 1), mid + 1, r, L, R);
}
int main() {
  pre();
  n = read(), m = read();
  build(1, 1, n);
  while (m--) {
    int opt = read(), x = read(), y = read();
    if (opt == 1) {
      tmp = quickpow(k = read());
      upd(1, 1, n, x, y);
    } else
      printf("%d\n", query(1, 1, n, x, y).a[0][0]);
  }
  return 0;
}
