#include <bits/stdc++.h>
using namespace std;
struct matr {
  long long m[2][2];
  matr() { m[0][0] = m[0][1] = m[1][0] = m[1][1] = 0; };
  matr(int a, int b, int c, int d) {
    m[0][0] = a;
    m[0][1] = b;
    m[1][0] = c;
    m[1][1] = d;
  }
};
matr A = matr(1, 1, 1, 0);
long long MOD = 1000000007;
inline matr mul(const matr &m1, const matr &m2) {
  matr res;
  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 2; j++) {
      for (int h = 0; h < 2; h++) {
        res.m[i][j] = (res.m[i][j] + (m1.m[i][h] * m2.m[h][j]) % MOD) % MOD;
      }
    }
  }
  return res;
}
matr bin_pow(matr m, long long step) {
  if (step == 1) {
    return m;
  }
  if (step % 2 == 0) {
    matr ma = bin_pow(m, step / 2);
    return mul(ma, ma);
  } else {
    return mul(bin_pow(m, step - 1), m);
  }
}
vector<long long> num;
matr tree[400000];
matr c[400000];
void build(int v, int l, int r) {
  if (r - l == 1) {
    if (num[l] == 1) {
      tree[v].m[0][0] = 1;
      return;
    }
    tree[v] = mul(bin_pow(A, num[l] - 1), matr(1, 0, 0, 0));
    return;
  }
  int m = (l + r) / 2;
  build(v * 2 + 1, l, m);
  build(v * 2 + 2, m, r);
  tree[v].m[0][0] = (tree[v * 2 + 1].m[0][0] + tree[v * 2 + 2].m[0][0]) % MOD;
  tree[v].m[1][0] = (tree[v * 2 + 1].m[1][0] + tree[v * 2 + 2].m[1][0]) % MOD;
}
inline void push(int v) {
  if (c[v].m[0][0] == 0) return;
  tree[v * 2 + 1] = mul(c[v], tree[v * 2 + 1]);
  tree[v * 2 + 2] = mul(c[v], tree[v * 2 + 2]);
  if (c[v * 2 + 1].m[0][0] == 0)
    c[v * 2 + 1] = c[v];
  else
    c[v * 2 + 1] = mul(c[v], c[v * 2 + 1]);
  if (c[v * 2 + 2].m[0][0] == 0)
    c[v * 2 + 2] = c[v];
  else
    c[v * 2 + 2] = mul(c[v], c[v * 2 + 2]);
  c[v].m[0][0] = 0;
}
void add(int v, int l, int r, int askl, int askr, const matr &step) {
  if (askr <= l || r <= askl) return;
  if (askl <= l && r <= askr) {
    tree[v] = mul(step, tree[v]);
    if (c[v].m[0][0] == 0)
      c[v] = step;
    else
      c[v] = mul(step, c[v]);
    return;
  }
  push(v);
  int m = (l + r) / 2;
  add(v * 2 + 1, l, m, askl, askr, step);
  add(v * 2 + 2, m, r, askl, askr, step);
  tree[v].m[0][0] = (tree[v * 2 + 1].m[0][0] + tree[v * 2 + 2].m[0][0]) % MOD;
  tree[v].m[1][0] = (tree[v * 2 + 1].m[1][0] + tree[v * 2 + 2].m[1][0]) % MOD;
}
long long ask(int v, int l, int r, int askl, int askr) {
  if (askr <= l || r <= askl) return 0;
  if (askl <= l && r <= askr) {
    return tree[v].m[0][0];
  }
  push(v);
  int m = (l + r) / 2;
  long long sum =
      (ask(v * 2 + 1, l, m, askl, askr) + ask(v * 2 + 2, m, r, askl, askr)) %
      MOD;
  tree[v].m[0][0] = (tree[v * 2 + 1].m[0][0] + tree[v * 2 + 2].m[0][0]) % MOD;
  tree[v].m[1][0] = (tree[v * 2 + 1].m[1][0] + tree[v * 2 + 2].m[1][0]) % MOD;
  return sum;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int n, m;
  cin >> n >> m;
  num.resize(n);
  for (int i = 0; i < n; i++) cin >> num[i];
  build(0, 0, n);
  matr step;
  int tp, l, r;
  long long x;
  for (int i = 0; i < m; i++) {
    cin >> tp;
    if (tp == 1) {
      cin >> l >> r >> x;
      step = bin_pow(A, x);
      add(0, 0, n, l - 1, r, step);
    } else {
      cin >> l >> r;
      cout << ask(0, 0, n, l - 1, r) << endl;
    }
  }
}
