#include <bits/stdc++.h>
using namespace std;
int MOD = 1000000007;
struct Int {
  int x;
  Int() : x(0) {}
  Int(int _x) {
    x = _x % MOD;
    if (x < 0) x += MOD;
  }
  static Int get(int x) {
    Int a;
    a.x = x;
    return a;
  }
  Int operator+(const Int &o) const { return get(((long long)x + o.x) % MOD); }
  Int operator*(const Int &o) const { return get((long long)x * o.x % MOD); }
  Int &operator+=(const Int &o) { return (*this) = *this + o; }
  Int &operator*=(const Int &o) { return (*this) = *this * o; }
  bool operator==(const Int &o) const { return x == o.x; }
  bool operator!=(const Int &o) const { return x != o.x; }
  bool operator<(const Int &o) const { return x < o.x; }
};
typedef Int mat[2][2];
void zero(mat &a) { a[0][0] = a[0][1] = a[1][0] = a[1][1] = 0; }
void unit(mat &a) {
  a[0][0] = a[1][1] = 1;
  a[0][1] = a[1][0] = 0;
}
void multi(mat &a, mat &b, mat &c) {
  c[0][0] = a[0][0] * b[0][0] + a[0][1] * b[1][0];
  c[0][1] = a[0][0] * b[0][1] + a[0][1] * b[1][1];
  c[1][0] = a[1][0] * b[0][0] + a[1][1] * b[1][0];
  c[1][1] = a[1][0] * b[0][1] + a[1][1] * b[1][1];
}
void add(mat &a, mat &b, mat &c) {
  c[0][0] = a[0][0] + b[0][0];
  c[0][1] = a[0][1] + b[0][1];
  c[1][0] = a[1][0] + b[1][0];
  c[1][1] = a[1][1] + b[1][1];
}
void copy(mat &a, mat &b) {
  a[0][0] = b[0][0];
  a[0][1] = b[0][1];
  a[1][0] = b[1][0];
  a[1][1] = b[1][1];
}
mat temp;
void matPow(mat &a, long long e, mat &ans) {
  if (!e) {
    ans[0][0] = ans[1][1] = 1;
    ans[0][1] = ans[1][0] = 0;
    return;
  }
  matPow(a, e / 2, ans);
  multi(ans, ans, temp);
  if (e & 1)
    multi(temp, a, ans);
  else
    copy(ans, temp);
}
mat M;
int N, Q, a[110000];
mat val[110000 * 4], flag[110000 * 4];
void push_down(int u) {
  multi(val[(u << 1)], flag[u], temp);
  copy(val[(u << 1)], temp);
  multi(val[((u << 1) + 1)], flag[u], temp);
  copy(val[((u << 1) + 1)], temp);
  multi(flag[(u << 1)], flag[u], temp);
  copy(flag[(u << 1)], temp);
  multi(flag[((u << 1) + 1)], flag[u], temp);
  copy(flag[((u << 1) + 1)], temp);
  unit(flag[u]);
}
void build(int u, int L, int R) {
  unit(flag[u]);
  zero(val[u]);
  if (R == L + 1) {
    matPow(M, a[L], val[u]);
    return;
  }
  build((u << 1), L, ((L + R) >> 1));
  build(((u << 1) + 1), ((L + R) >> 1), R);
  add(val[(u << 1)], val[((u << 1) + 1)], val[u]);
}
void update(int u, int L, int R, int l, int r, mat &x) {
  l = max(L, l);
  r = min(R, r);
  if (l >= r) return;
  if (l == L && R == r) {
    multi(flag[u], x, temp);
    copy(flag[u], temp);
    multi(val[u], x, temp);
    copy(val[u], temp);
    return;
  }
  push_down(u);
  update((u << 1), L, ((L + R) >> 1), l, r, x);
  update(((u << 1) + 1), ((L + R) >> 1), R, l, r, x);
  add(val[(u << 1)], val[((u << 1) + 1)], val[u]);
}
void calc(int u, int L, int R, int l, int r, mat &ans) {
  l = max(L, l);
  r = min(R, r);
  if (l >= r) return;
  if (L == l && R == r) {
    add(ans, val[u], temp);
    copy(ans, temp);
    return;
  }
  push_down(u);
  calc((u << 1), L, ((L + R) >> 1), l, r, ans);
  calc(((u << 1) + 1), ((L + R) >> 1), R, l, r, ans);
}
int main() {
  zero(M);
  M[1][0] = M[0][1] = M[1][1] = 1;
  scanf("%d%d", &N, &Q);
  for (int i = 0; i < N; i++) scanf("%d", &a[i]);
  build(1, 0, N);
  for (int i = 0; i < Q; i++) {
    int tp, l, r, x;
    scanf("%d", &tp);
    if (tp == 1) {
      scanf("%d%d%d", &l, &r, &x);
      mat val;
      matPow(M, x, val);
      update(1, 0, N, l - 1, r, val);
    } else {
      mat ans;
      zero(ans);
      scanf("%d%d", &l, &r);
      calc(1, 0, N, l - 1, r, ans);
      printf("%d\n", ans[1][0].x);
    }
  }
  return 0;
}
