#include<bits\stdc++.h>
using namespace std;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);

	int k, d, a,b;
	cin >> k >> d;
	if(d==0 && k!=1) cout << "No solution";
	else{

		d%2==0 ? b=d/2, a=d-b:b=d/2+1,a = d-b;
		if(k>=1){
			if(a!=0){cout << a; k--;}
			if(k>=1){cout << b;
			k--;
		}
		}
		while(k--)
			cout << 0;

	}

	return 0;
}


#include<bits\stdc++.h>
using namespace std;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);

	int k, d, a,b;
	cin >> k >> d;
	d%2==0 ? b=d/2, a=d-b:b=d/2+1,a = d-b;
	if(k>1){
		if(a!=0){cout << a; k--;}
		cout << b;
		k--;
	}
	while(k--)
		cout << 0;

	return 0;
}


#include<bits\stdc++.h>
using namespace std;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);

	int k, d, a,b;
	cin >> k >> d;
	if(d==0) cout << "No solution";
	else{

		d%2==0 ? b=d/2, a=d-b:b=d/2+1,a = d-b;
		if(k>1){
			if(a!=0){cout << a; k--;}
			cout << b;
			k--;
		}
		while(k--)
			cout << 0;

	}

	return 0;
}


#include<bits\stdc++.h>
using namespace std;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);

	int k, d, a,b;
	cin >> k >> d;
	if(k==1 && d<10) cout << d;

	else if(d==0 && k!=1) cout << "No solution";
	else{

		d%2==0 ? b=d/2, a=d-b:b=d/2+1,a = d-b;
		if(k>=1){
			if(a!=0){cout << a; k--;}
			if(k>=1){cout << b;
			k--;
		}
		}
		while(k--)
			cout << 0;

	}

	return 0;
}


#include<bits\stdc++.h>
using namespace std;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);

	int k, d, a,b;
	cin >> k >> d;
	if(d==0 && k!=1) cout << "No solution";
	else{

		d%2==0 ? b=d/2, a=d-b:b=d/2+1,a = d-b;
		if(k>1){
			if(a!=0){cout << a; k--;}
			cout << b;
			k--;
		}
		while(k--)
			cout << 0;

	}

	return 0;
}


#include<bits\stdc++.h>
using namespace std;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	int k, d, a,b;
	cin >> k >> d;
	if(k==1 && d<10) cout << d;
	else if(d==0 && k!=1) cout << "No solution";
	else{
		d%2==0 ? b=d/2, a=d-b:b=d/2+1,a = d-b;
		if(k>=1){
			if(a!=0){cout << a; k--;}
			if(k>=1){cout << b;k--;}
		}
		while(k--)
			cout << 0;
	}

	return 0;
}


#include<bits/stdc++.h>
#include<cmath>
#include<vector>
using namespace std;

int check(int l){
int sum=0;
while(l!=0){
    sum=sum+l%10;
    l=l/10;
}
return sum;
}

int main(){
int n,k;
cin >> n >> k;
if(k!=0){
if(n!=1){n = pow(10,n-1);
while(check(n)!=k){
    n++;
}
cout << n;
}else if(n==1){
cout << k;
}
}else cout << "No solution";
return 0;
}


#include<bits/stdc++.h>
#include<cmath>
#include<vector>
using namespace std;

int check(int l){
int sum=0;
while(l!=0){
    sum=sum+l%10;
    l=l/10;
}
return sum;
}

int main(){
int n,k;
cin >> n >> k;
if(k!=0){
if(n!=1){n = pow(10,n-1);
while(check(n)!=k){
    n++;
}
cout << n;
}else if(n==1){
cout << k;
}
}else if(n==1) cout << 0;
else cout << "No Solution";
return 0;
}


#include<bits/stdc++.h>
#include<cmath>
#include<vector>
using namespace std;

int check(int l){
int sum=0;
while(l!=0){
    sum=sum+l%10;
    l=l/10;
}
return sum;
}

int main(){
int n,k;
cin >> n >> k;
if(k!=0){
if(n!=1){n = pow(10,n-1);
while(check(n)!=k){
    n++;
}
cout << n;
}else if(n==1){
cout << k;
}
}else if(n==1) cout << 0;
else cout << "N0 Solution";
return 0;
}


#include<bits/stdc++.h>
using namespace std;

int main(){
int n,k;
cin >> n >> k;
if(k!=0 && n!=1){
if(k==1){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 0;
}
else if(k==2){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 1;
}
else if(k==3){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 2;
}
else if(k==4){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 3;
}
else if(k==5){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 4;
}
else if(k==6){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 5;
}
else if(k==7){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 6;
}
else if(k==8){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 7;
}
else if(k==9){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 8;
}
}else if(n==1)cout << k;
else cout << "No solution";
return 0;
}


#include<bits/stdc++.h>
#include<cmath>
#include<vector>
using namespace std;

int check(int l){
int sum=0;
while(l!=0){
    sum=sum+l%10;
    l=l/10;
}
return sum;
}

int main(){
int n,k;
cin >> n >> k;
if(n!=1){n = pow(10,n-1);
while(check(n)!=k){
    n++;
}
cout << n;
}else if(n==1){
cout << k;
}
return 0;
}


#include<bits/stdc++.h>
using namespace std;

int main(){
int n,k;
cin >> n >> k;
if(k!=0){
if(k==1){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 0;
}
else if(k==2){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 1;
}
else if(k==3){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 0;
}
else if(k==4){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 3;
}
else if(k==5){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 4;
}
else if(k==6){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 5;
}
else if(k==7){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 6;
}
else if(k==8){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 7;
}
else if(k==9){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 8;
}
}else if(k==0 && n==1 )  cout << 0;
else cout << "No solution";
return 0;
}


#include<bits/stdc++.h>
using namespace std;

int main(){
int n,k;
cin >> n >> k;
if(k!=0 && n!=1){
if(k==1){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 0;
}
else if(k==2){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 1;
}
else if(k==3){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 0;
}
else if(k==4){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 3;
}
else if(k==5){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 4;
}
else if(k==6){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 5;
}
else if(k==7){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 6;
}
else if(k==8){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 7;
}
else if(k==9){
    cout << 1;
    for(int i=0;i<n-2;++i) cout << 0;
    cout << 8;
}
}else if(n==1)cout << k;
else cout << "No solution";
return 0;
}


#include<bits/stdc++.h>
#include<cmath>
#include<vector>
using namespace std;

int check(int l){
int sum=0;
while(l!=0){
    sum=sum+l%10;
    l=l/10;
}
return sum;
}

int main(){
int n,k;
cin >> n >> k;
if(k!=0){
if(n!=1){n = pow(10,n-1);
while(check(n)!=k){
    n++;
}
cout << n;
}else if(n==1){
cout << k;
}
}else if(n==1) cout << 0;
else cout << "No solution";
return 0;
}


#include <bits/stdc++.h>
#include <iostream>
#include <vector>
#include <iostream>
#include <cmath>
#include <cstring>

using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    long long int k,d,i,p;
    cin>>k>>d;
    if(d==0&&k>1)
    cout<<"No solution";
    else
    {
    	for(i=k;i>=2;i--)
       {
    	   cout<<"9";
       }
       cout<<d;
    }
    return 0;
}


#include <bits/stdc++.h>
#include <iostream>
#include <vector>
#include <iostream>
#include <cmath>
#include <cstring>

using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    long long int k,d,p;
    cin>>k>>d;
    p=pow(10,k-1)+d;
    if(d>0)
    cout<<p-1;
    else if(d==0&&k==1)
    cout<<"0";
    else if(d==0&&k>1)
    cout<<"No solution";
    return 0;
}


#include <bits/stdc++.h>
#include <iostream>
#include <vector>
#include <iostream>
#include <cmath>
#include <cstring>

using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    long long int k,d,p;
    cin>>k>>d;

    if(d>0)
    cout<<pow(10,k-1)+d-1;
    else if(d==0&&k==1)
    cout<<"0";
    else if(d==0&&k>1)
    cout<<"No solution";
    return 0;
}


#include <bits/stdc++.h>
#include <iostream>
#include <vector>
#include <iostream>
#include <cmath>
#include <cstring>

using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    long long int k,d,i,p;
    cin>>k>>d;
    if(d==0&&k>1)
    cout<<"No solution";
    else
    {
    	for(i=d;i>=2;i--)
       {
    	   cout<<"9";
       }
       cout<<d;
    }
    return 0;
}


#include <bits/stdc++.h>
#include <iostream>
#include <vector>
#include <iostream>
#include <cmath>
#include <cstring>

using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    long long int k,d,p;
    cin>>k>>d;
    p=pow(10,k-1)+d;
    if(d>0)
    cout<<p-1;
    else
    cout<<"0";
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
    int k,d;
    cin>>k>>d;
       int s=d;
    if(d==0)
    if(k==1)
    {
        cout<<"0";exit(0);
    }
    else    {
            cout<<"No solution";exit(0);
        }
    if(k>d)
    {

        for(int i=1;i<=k;i++)
        {
            if(s>0)
                {cout<<"1";s-=1;}
            else
                cout<<"0";
        }
    }
    else if(d>k)
    {
        for(int i=1;i<k;i++)
        {
         cout<<"1";s-=1;

        }cout<<s;
    }
    else
    {
        for(int i=1;i<=k;i++)
            cout<<"1";
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
    int k,d;
    cin>>k>>d;
       int s=d;
    if(d==0)
        {
            cout<<"No solution";exit(0);
        }
    if(k>d)
    {

        for(int i=1;i<=k;i++)
        {
            if(s>0)
                {cout<<"1";s-=1;}
            else
                cout<<"0";
        }
    }
    else if(d>k)
    {
        for(int i=1;i<k;i++)
        {
         cout<<"1";s-=1;

        }cout<<s;
    }
    else
    {
        for(int i=1;i<=k;i++)
            cout<<"1";
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
    int k,d;
    cin>>k>>d;
       int s=d;
    if(d==0)
        {
            cout<<"0";exit(0);
        }
    if(k>d)
    {

        for(int i=1;i<=k;i++)
        {
            if(s>0)
                {cout<<"1";s-=1;}
            else
                cout<<"0";
        }
    }
    else if(d>k)
    {
        for(int i=1;i<k;i++)
        {
         cout<<"1";s-=1;

        }cout<<s;
    }
    else
    {
        for(int i=1;i<=k;i++)
            cout<<"1";
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
    int k,d;
    cin>>k>>d;
       int s=d;
    if(k>d)
    {

        for(int i=1;i<=k;i++)
        {
            if(s>0)
                {cout<<"1";s-=1;}
            else
                cout<<"0";
        }
    }
    else if(d>k)
    {
        for(int i=1;i<k;i++)
        {
         cout<<"1";s-=1;

        }cout<<s;
    }
    else
    {
        for(int i=1;i<=k;i++)
            cout<<"1";
    }
    return 0;
}


#include<algorithm>
#include<bitset>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<deque>
#include<fstream>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<utility>
#include<vector>

using namespace std;

#define dbg(x) (cout<<#x<<" = "<<(x)<<'\n')
#define inputFile "input.txt"
#define outputFile "output.txt"

typedef long long int lld;
typedef pair<int,int> PII;

const int INF = (1<<31)-1;
const lld LINF = (1LL<<63)-1;

const int NMAX = 300000+5;
const int MMAX = 100000+5;
const int KMAX = 100000+5;
const int PMAX = 100000+5;
const int LMAX = 100000+5;
const int VMAX = 100000+5;
const int MOD = 1e9+9;

struct node {
    int sum,b1,b2;
    node() {
        sum=b1=b2=0;
    }
};

int N,M,L,R;
node AI[4*NMAX];
int V[NMAX];
int F[NMAX];
int S[NMAX];

void precomputeFibonacci() {
    int i;
    F[1]=1;
    F[2]=1;
    for(i=3; i<=N+2; i++)
        F[i]=(F[i-2]+F[i-1])%MOD;
}

int term(int a1,int a2,int n) {
    if(n==0)
        return 0;
    if(n==1)
        return a1;
    if(n==2)
        return a2;

    if(a1<=a2)
        return (1LL*a1*F[n] + 1LL*F[n-1]*(a2-a1))%MOD;
    else
        return (1LL*a2*F[n] + 1LL*F[n-2]*(a1-a2))%MOD;
}

int sum(int a1,int a2,int i,int j) {
    return (term(a1,a2,j+2)-term(a1,a2,i+1)+MOD)%MOD;
}

void update(int nod,int lo,int hi,int b1,int b2) {
    if(L<=lo && hi<=R) {
        b1=(b1+F[lo-L+1])%MOD;
        b2=(b2+F[lo-L+2])%MOD;
        AI[nod].b1=(AI[nod].b1+b1)%MOD;
        AI[nod].b2=(AI[nod].b2+b2)%MOD;
        int s=sum(b1,b2,1,hi-lo+1);
        AI[nod].sum=(AI[nod].sum+s)%MOD;
        return;
    }

    if(hi<L || R<lo) {
        AI[nod].b1=(AI[nod].b1+b1)%MOD;
        AI[nod].b2=(AI[nod].b2+b2)%MOD;
        int s=sum(b1,b2,1,hi-lo+1);
        AI[nod].sum=(AI[nod].sum+s)%MOD;
        return;
    }

    int mi=(lo+hi)/2;

    update(2*nod,lo,mi,b1+AI[nod].b1,b2+AI[nod].b2);
    update(2*nod+1,mi+1,hi,term(b1+AI[nod].b1,b2+AI[nod].b2,mi+2-lo),term(b1+AI[nod].b1,b2+AI[nod].b2,mi+3-lo));

    AI[nod].b1=AI[nod].b2=0;
    AI[nod].sum=AI[2*nod].sum+AI[2*nod+1].sum;
}

int query(int nod,int lo,int hi,int b1,int b2) {
    if(L<=lo && hi<=R) {
        AI[nod].b1=(AI[nod].b1+b1)%MOD;
        AI[nod].b2=(AI[nod].b2+b2)%MOD;
        int s=sum(b1,b2,1,hi-lo+1);
        AI[nod].sum=(AI[nod].sum+s)%MOD;
        return AI[nod].sum;
    }

    if(hi<L || R<lo) {
        AI[nod].b1=(AI[nod].b1+b1)%MOD;
        AI[nod].b2=(AI[nod].b2+b2)%MOD;
        int s=sum(b1,b2,1,hi-lo+1);
        AI[nod].sum=(AI[nod].sum+s)%MOD;
        return 0;
    }

    int mi=(lo+hi)/2,q1,q2;

    q1=query(2*nod,lo,mi,b1+AI[nod].b1,b2+AI[nod].b2);
    q2=query(2*nod+1,mi+1,hi,term(b1+AI[nod].b1,b2+AI[nod].b2,mi+2-lo),term(b1+AI[nod].b1,b2+AI[nod].b2,mi+3-lo));

    AI[nod].b1=AI[nod].b2=0;
    AI[nod].sum=AI[2*nod].sum+AI[2*nod+1].sum;

    return (q1+q2)%MOD;
}

int main() {
    int i,x,op;

#ifndef ONLINE_JUDGE
    freopen(inputFile,"r",stdin);
    freopen(outputFile,"w",stdout);
#endif

    scanf("%d%d",&N,&M);

    for(i=1; i<=N; i++) {
        scanf("%d",&x);
        V[i]=(V[i-1]+x)%MOD;
    }

    precomputeFibonacci();

    while(M--) {
        scanf("%d%d%d",&op,&L,&R);

        if(op==1)
            update(1,1,N,0,0);

        if(op==2) {
            x=(query(1,1,N,0,0)+1LL*V[R]-1LL*V[L-1]+MOD)%MOD;
            printf("%d\n",x);
        }
    }

    return 0;
}


#include<algorithm>
#include<bitset>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<deque>
#include<fstream>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<utility>
#include<vector>

using namespace std;

#define dbg(x) (cout<<#x<<" = "<<(x)<<'\n')
#define inputFile "input.txt"
#define outputFile "output.txt"

typedef long long int lld;
typedef pair<int, int> PII;

const int INF = (1 << 31) - 1;
const lld LINF = (1LL << 63) - 1;

const int NMAX = 300000 + 5;
const int MMAX = 100000 + 5;
const int KMAX = 100000 + 5;
const int PMAX = 100000 + 5;
const int LMAX = 100000 + 5;
const int VMAX = 100000 + 5;
const int MOD = 1e9 + 9;

struct node {
    lld sum, b1, b2;
    node() {
        sum = b1 = b2 = 0;
    }
};

lld N, M, L, R;
node AI[4*NMAX];
lld V[NMAX];
lld F[NMAX];
lld S[NMAX];

void precomputeFibonacci() {
    lld i;
    F[1] = 1LL;
    F[2] = 1LL;
    for(i = 3; i <= N + 2; i++)
        F[i] = (F[i-2] + F[i-1]) % MOD;
}

lld term(lld a1, lld a2, lld n) {
    if(n == 0)
        return 0LL;
    if(n == 1)
        return a1;
    if(n == 2)
        return a2;

    return (a1 * F[n-2] + a2 * F[n-1]) % MOD;
}

lld sum(lld a1, lld a2, lld k) {
    return (term(a1, a2, k + 2) - term(a1, a2, 2) + MOD) % MOD;
}

void update(lld nod, lld lo, lld hi, lld b1, lld b2) {
    if(L <= lo && hi <= R) {
        b1 = (b1 + F[lo-L+1]) % MOD;
        b2 = (b2 + F[lo-L+2]) % MOD;
        AI[nod].b1 = (AI[nod].b1 + b1) % MOD;
        AI[nod].b2 = (AI[nod].b2 + b2) % MOD;
        lld s = sum(b1, b2, hi - lo + 1);
        AI[nod].sum = (AI[nod].sum + s) % MOD;
        return;
    }

    if(hi < L || R < lo) {
        AI[nod].b1 = (AI[nod].b1 + b1) % MOD;
        AI[nod].b2 = (AI[nod].b2 + b2) % MOD;
        lld s = sum(b1, b2, hi - lo + 1);
        AI[nod].sum = (AI[nod].sum + s) % MOD;
        return;
    }

    lld mi = (lo + hi) / 2;

    update(2 * nod, lo, mi, b1 + AI[nod].b1, b2 + AI[nod].b2);
    update(2 * nod + 1, mi + 1, hi, term(b1 + AI[nod].b1, b2 + AI[nod].b2, mi + 2 - lo), term(b1 + AI[nod].b1, b2 + AI[nod].b2, mi + 3 - lo));

    AI[nod].b1 = AI[nod].b2 = 0LL;
    AI[nod].sum = (AI[2*nod].sum + AI[2*nod+1].sum) % MOD;
}

lld query(lld nod, lld lo, lld hi, lld b1, lld b2) {
    if(L <= lo && hi <= R) {
        AI[nod].b1 = (AI[nod].b1 + b1) % MOD;
        AI[nod].b2 = (AI[nod].b2 + b2) % MOD;
        lld s = sum(b1, b2, hi - lo + 1);
        AI[nod].sum = (AI[nod].sum + s) % MOD;
        return AI[nod].sum;
    }

    if(hi < L || R < lo) {
        AI[nod].b1 = (AI[nod].b1 + b1) % MOD;
        AI[nod].b2 = (AI[nod].b2 + b2) % MOD;
        lld s = sum(b1, b2, hi - lo + 1);
        AI[nod].sum = (AI[nod].sum + s) % MOD;
        return 0LL;
    }

    lld mi = (lo + hi) / 2, q1, q2;

    q1 = query(2 * nod, lo, mi, b1 + AI[nod].b1, b2 + AI[nod].b2);
    q2 = query(2 * nod + 1, mi + 1, hi, term(b1 + AI[nod].b1, b2 + AI[nod].b2, mi + 2 - lo), term(b1 + AI[nod].b1, b2 + AI[nod].b2, mi + 3 - lo));

    AI[nod].b1 = AI[nod].b2 = 0LL;
    AI[nod].sum = (AI[2*nod].sum + AI[2*nod+1].sum) % MOD;

    return (q1 + q2) % MOD;
}

int main() {
    lld i, x, op;

#ifndef ONLINE_JUDGE
    freopen(inputFile, "r", stdin);
    freopen(outputFile, "w", stdout);
#endif

    scanf("%I64d%I64d", &N, &M);

    for(i = 1; i <= N; i++) {
        scanf("%I64d", &x);
        V[i] = (V[i-1] + x) % MOD;
    }

    precomputeFibonacci();

    while(M--) {
        scanf("%I64d%I64d%I64d", &op, &L, &R);

        if(op == 1)
            update(1, 1, N, 0, 0);

        if(op == 2) {
            x = (query(1, 1, N, 0, 0) + V[R] - V[L-1] + 2 * MOD) % MOD;
            printf("%I64d\n", x);
        }
    }

    return 0;
}


#include<algorithm>
#include<bitset>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<deque>
#include<fstream>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<utility>
#include<vector>

using namespace std;

#define dbg(x) (cout<<#x<<" = "<<(x)<<'\n')
#define inputFile "input.txt"
#define outputFile "output.txt"

typedef long long int lld;
typedef pair<int,int> PII;

const int INF = (1<<31)-1;
const lld LINF = (1LL<<63)-1;

const int NMAX = 300000+5;
const int MMAX = 100000+5;
const int KMAX = 100000+5;
const int PMAX = 100000+5;
const int LMAX = 100000+5;
const int VMAX = 100000+5;
const int MOD = 1e9+9;

struct node {
    lld sum,b1,b2;
    node() {
        sum=b1=b2=0;
    }
};

lld N,M,L,R;
node AI[4*NMAX];
lld V[NMAX];
lld F[NMAX];
lld S[NMAX];

void precomputeFibonacci() {
    lld i;
    F[1]=1LL;
    F[2]=1LL;
    for(i=3; i<=N+2; i++)
        F[i]=(F[i-2]+F[i-1])%MOD;
}

lld term(lld a1,lld a2,lld n) {
    if(n==0)
        return 0LL;
    if(n==1)
        return a1;
    if(n==2)
        return a2;

    return (a1*F[n-2] + a2*F[n-1])%MOD;
}

lld sum(lld a1,lld a2,lld k) {
    return (term(a1,a2,k+2)-term(a1,a2,2)+MOD)%MOD;
}

void update(lld nod,lld lo,lld hi,lld b1,lld b2) {
    if(L<=lo && hi<=R) {
        b1=(b1+F[lo-L+1])%MOD;
        b2=(b2+F[lo-L+2])%MOD;
        AI[nod].b1=(AI[nod].b1+b1)%MOD;
        AI[nod].b2=(AI[nod].b2+b2)%MOD;
        lld s=sum(b1,b2,hi-lo+1);
        AI[nod].sum=(AI[nod].sum+s)%MOD;
        return;
    }

    if(hi<L || R<lo) {
        AI[nod].b1=(AI[nod].b1+b1)%MOD;
        AI[nod].b2=(AI[nod].b2+b2)%MOD;
        lld s=sum(b1,b2,hi-lo+1);
        AI[nod].sum=(AI[nod].sum+s)%MOD;
        return;
    }

    lld mi=(lo+hi)/2;

    update(2*nod,lo,mi,b1+AI[nod].b1,b2+AI[nod].b2);
    update(2*nod+1,mi+1,hi,term(b1+AI[nod].b1,b2+AI[nod].b2,mi+2-lo),term(b1+AI[nod].b1,b2+AI[nod].b2,mi+3-lo));

    AI[nod].b1=AI[nod].b2=0LL;
    AI[nod].sum=(AI[2*nod].sum+AI[2*nod+1].sum)%MOD;
}

lld query(lld nod,lld lo,lld hi,lld b1,lld b2) {
    if(L<=lo && hi<=R) {
        AI[nod].b1=(AI[nod].b1+b1)%MOD;
        AI[nod].b2=(AI[nod].b2+b2)%MOD;
        lld s=sum(b1,b2,hi-lo+1);
        AI[nod].sum=(AI[nod].sum+s)%MOD;
        return AI[nod].sum;
    }

    if(hi<L || R<lo) {
        AI[nod].b1=(AI[nod].b1+b1)%MOD;
        AI[nod].b2=(AI[nod].b2+b2)%MOD;
        lld s=sum(b1,b2,hi-lo+1);
        AI[nod].sum=(AI[nod].sum+s)%MOD;
        return 0LL;
    }

    lld mi=(lo+hi)/2,q1,q2;

    q1=query(2*nod,lo,mi,b1+AI[nod].b1,b2+AI[nod].b2);
    q2=query(2*nod+1,mi+1,hi,term(b1+AI[nod].b1,b2+AI[nod].b2,mi+2-lo),term(b1+AI[nod].b1,b2+AI[nod].b2,mi+3-lo));

    AI[nod].b1=AI[nod].b2=0LL;
    AI[nod].sum=(AI[2*nod].sum+AI[2*nod+1].sum)%MOD;

    return (q1+q2)%MOD;
}

int main() {
    lld i,x,op;

#ifndef ONLINE_JUDGE
    freopen(inputFile,"r",stdin);
    freopen(outputFile,"w",stdout);
#endif

    scanf("%I64d%I64d",&N,&M);

    for(i=1; i<=N; i++) {
        scanf("%I64d",&x);
        V[i]=(V[i-1]+x)%MOD;
    }

    precomputeFibonacci();

    while(M--) {
        scanf("%I64d%I64d%I64d",&op,&L,&R);

        if(op==1)
            update(1,1,N,0,0);

        if(op==2) {
            x=(query(1,1,N,0,0)+V[R]-V[L-1]+2*MOD)%MOD;
            printf("%I64d\n",x);
        }
    }

    return 0;
}


#include<algorithm>
#include<bitset>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<deque>
#include<fstream>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<utility>
#include<vector>

using namespace std;

#define dbg(x) (cout<<#x<<" = "<<(x)<<'\n')
#define inputFile "input.txt"
#define outputFile "output.txt"

typedef long long int lld;
typedef pair<int,int> PII;

const int INF = (1<<31)-1;
const lld LINF = (1LL<<63)-1;

const int NMAX = 300000+5;
const int MMAX = 100000+5;
const int KMAX = 100000+5;
const int PMAX = 100000+5;
const int LMAX = 100000+5;
const int VMAX = 100000+5;
const int MOD = 1e9+9;

struct node {
    int sum,b1,b2;
    node() {
        sum=b1=b2=0;
    }
};

int N,M,L,R;
node AI[4*NMAX];
int V[NMAX];
int F[NMAX];
int S[NMAX];

void precomputeFibonacci() {
    int i;
    F[1]=1;
    F[2]=1;
    for(i=3; i<=N+2; i++)
        F[i]=(F[i-2]+F[i-1])%MOD;
}

int term(int a1,int a2,int n) {
    if(n==0)
        return 0;
    if(n==1)
        return a1;
    if(n==2)
        return a2;

    return (1LL*a1*F[n-2] + 1LL*a2*F[n-1])%MOD;
}

int sum(int a1,int a2,int i,int j) {
    return (term(a1,a2,j+2)-term(a1,a2,i+1)+MOD)%MOD;
}

void update(int nod,int lo,int hi,int b1,int b2) {
    if(L<=lo && hi<=R) {
        b1=(b1+F[lo-L+1])%MOD;
        b2=(b2+F[lo-L+2])%MOD;
        AI[nod].b1=(AI[nod].b1+b1)%MOD;
        AI[nod].b2=(AI[nod].b2+b2)%MOD;
        int s=sum(b1,b2,1,hi-lo+1);
        AI[nod].sum=(AI[nod].sum+s)%MOD;
        return;
    }

    if(hi<L || R<lo) {
        AI[nod].b1=(AI[nod].b1+b1)%MOD;
        AI[nod].b2=(AI[nod].b2+b2)%MOD;
        int s=sum(b1,b2,1,hi-lo+1);
        AI[nod].sum=(AI[nod].sum+s)%MOD;
        return;
    }

    int mi=(lo+hi)/2;

    update(2*nod,lo,mi,b1+AI[nod].b1,b2+AI[nod].b2);
    update(2*nod+1,mi+1,hi,term(b1+AI[nod].b1,b2+AI[nod].b2,mi+2-lo),term(b1+AI[nod].b1,b2+AI[nod].b2,mi+3-lo));

    AI[nod].b1=AI[nod].b2=0;
    AI[nod].sum=(AI[2*nod].sum+AI[2*nod+1].sum)%MOD;
}

int query(int nod,int lo,int hi,int b1,int b2) {
    if(L<=lo && hi<=R) {
        AI[nod].b1=(AI[nod].b1+b1)%MOD;
        AI[nod].b2=(AI[nod].b2+b2)%MOD;
        int s=sum(b1,b2,1,hi-lo+1);
        AI[nod].sum=(AI[nod].sum+s)%MOD;
        return AI[nod].sum;
    }

    if(hi<L || R<lo) {
        AI[nod].b1=(AI[nod].b1+b1)%MOD;
        AI[nod].b2=(AI[nod].b2+b2)%MOD;
        int s=sum(b1,b2,1,hi-lo+1);
        AI[nod].sum=(AI[nod].sum+s)%MOD;
        return 0;
    }

    int mi=(lo+hi)/2,q1,q2;

    q1=query(2*nod,lo,mi,b1+AI[nod].b1,b2+AI[nod].b2);
    q2=query(2*nod+1,mi+1,hi,term(b1+AI[nod].b1,b2+AI[nod].b2,mi+2-lo),term(b1+AI[nod].b1,b2+AI[nod].b2,mi+3-lo));

    AI[nod].b1=AI[nod].b2=0;
    AI[nod].sum=(AI[2*nod].sum+AI[2*nod+1].sum)%MOD;

    return (q1+q2)%MOD;
}

int main() {
    int i,x,op;

#ifndef ONLINE_JUDGE
    freopen(inputFile,"r",stdin);
    freopen(outputFile,"w",stdout);
#endif

    scanf("%d%d",&N,&M);

    for(i=1; i<=N; i++) {
        scanf("%d",&x);
        V[i]=(V[i-1]+x)%MOD;
    }

    precomputeFibonacci();

    while(M--) {
        scanf("%d%d%d",&op,&L,&R);

        if(op==1)
            update(1,1,N,0,0);

        if(op==2) {
            x=(query(1,1,N,0,0)+1LL*V[R]-1LL*V[L-1]+MOD)%MOD;
            printf("%d\n",x);
        }
    }

    return 0;
}


#include<algorithm>
#include<bitset>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<deque>
#include<fstream>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<utility>
#include<vector>

using namespace std;

#define dbg(x) (cout<<#x<<" = "<<(x)<<'\n')
#define inputFile "input.txt"
#define outputFile "output.txt"

typedef long long int lld;
typedef pair<int,int> PII;

const int INF = (1<<31)-1;
const lld LINF = (1LL<<63)-1;

const int NMAX = 300000+5;
const int MMAX = 100000+5;
const int KMAX = 100000+5;
const int PMAX = 100000+5;
const int LMAX = 100000+5;
const int VMAX = 100000+5;
const int MOD = 1e9+9;

struct node {
    int sum,b1,b2;
    node() {
        sum=b1=b2=0;
    }
};

int N,M,L,R;
node AI[4*NMAX];
int V[NMAX];
int F[NMAX];
int S[NMAX];

void precomputeFibonacci() {
    int i;
    F[1]=1;
    F[2]=1;
    for(i=3; i<=N+2; i++)
        F[i]=(F[i-2]+F[i-1])%MOD;
}

int term(int a1,int a2,int n) {
    if(n==0)
        return 0;
    if(n==1)
        return a1;
    if(n==2)
        return a2;

    if(a1<=a2)
        return (1LL*a1*F[n] + 1LL*F[n-1]*(a2-a1))%MOD;
    else
        return (1LL*a2*F[n] + 1LL*F[n-2]*(a1-a2))%MOD;
}

int sum(int a1,int a2,int i,int j) {
    return (term(a1,a2,j+2)-term(a1,a2,i+1)+MOD)%MOD;
}

void update(int nod,int lo,int hi,int b1,int b2) {
    if(L<=lo && hi<=R) {
        b1=(b1+F[lo-L+1])%MOD;
        b2=(b2+F[lo-L+2])%MOD;
        AI[nod].b1=(AI[nod].b1+b1)%MOD;
        AI[nod].b2=(AI[nod].b2+b2)%MOD;
        int s=sum(b1,b2,1,hi-lo+1);
        AI[nod].sum=(AI[nod].sum+s)%MOD;
        return;
    }

    if(hi<L || R<lo) {
        AI[nod].b1=(AI[nod].b1+b1)%MOD;
        AI[nod].b2=(AI[nod].b2+b2)%MOD;
        int s=sum(b1,b2,1,hi-lo+1);
        AI[nod].sum=(AI[nod].sum+s)%MOD;
        return;
    }

    int mi=(lo+hi)/2;

    update(2*nod,lo,mi,b1+AI[nod].b1,b2+AI[nod].b2);
    update(2*nod+1,mi+1,hi,term(b1+AI[nod].b1,b2+AI[nod].b2,mi+2-lo),term(b1+AI[nod].b1,b2+AI[nod].b2,mi+3-lo));

    AI[nod].b1=AI[nod].b2=0;
    AI[nod].sum=AI[2*nod].sum+AI[2*nod+1].sum;
}

int query(int nod,int lo,int hi,int b1,int b2) {
    if(L<=lo && hi<=R) {
        AI[nod].b1=(AI[nod].b1+b1)%MOD;
        AI[nod].b2=(AI[nod].b2+b2)%MOD;
        int s=sum(b1,b2,1,hi-lo+1);
        AI[nod].sum=(AI[nod].sum+s)%MOD;
        return AI[nod].sum;
    }

    if(hi<L || R<lo) {
        AI[nod].b1=(AI[nod].b1+b1)%MOD;
        AI[nod].b2=(AI[nod].b2+b2)%MOD;
        int s=sum(b1,b2,1,hi-lo+1);
        AI[nod].sum=(AI[nod].sum+s)%MOD;
        return 0;
    }

    int mi=(lo+hi)/2,q1,q2;

    q1=query(2*nod,lo,mi,b1+AI[nod].b1,b2+AI[nod].b2);
    q2=query(2*nod+1,mi+1,hi,term(b1+AI[nod].b1,b2+AI[nod].b2,mi+2-lo),term(b1+AI[nod].b1,b2+AI[nod].b2,mi+3-lo));

    AI[nod].b1=AI[nod].b2=0;
    AI[nod].sum=AI[2*nod].sum+AI[2*nod+1].sum;

    return (q1+q2)%MOD;
}

int main() {
    int i,x,op;

#ifndef ONLINE_JUDGE
    freopen(inputFile,"r",stdin);
    freopen(outputFile,"w",stdout);
#endif

    scanf("%d%d",&N,&M);

    for(i=1; i<=N; i++) {
        scanf("%d",&x);
        V[i]=(V[i-1]+x)%MOD;
    }

    precomputeFibonacci();

    while(M--) {
        scanf("%d%d%d",&op,&L,&R);

        if(op==1)
            update(1,1,N,0,0);

        if(op==2) {
            x=(query(1,1,N,0,0)+V[R]-V[L-1])%MOD;
            if(x<0) x+=MOD;
            printf("%d\n",x);
        }
    }

    return 0;
}


#include<algorithm>
#include<bitset>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<deque>
#include<fstream>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<utility>
#include<vector>

using namespace std;

#define dbg(x) (cout<<#x<<" = "<<(x)<<'\n')
#define inputFile "input.txt"
#define outputFile "output.txt"

typedef long long int lld;
typedef pair<int,int> PII;

const int INF = (1<<31)-1;
const lld LINF = (1LL<<63)-1;

const int NMAX = 300000+5;
const int MMAX = 100000+5;
const int KMAX = 100000+5;
const int PMAX = 100000+5;
const int LMAX = 100000+5;
const int VMAX = 100000+5;
const int MOD = 1e9+9;

struct node {
    int sum,b1,b2;
    node() {
        sum=b1=b2=0;
    }
};

int N,M,L,R;
node AI[4*NMAX];
int V[NMAX];
int F[NMAX];
int S[NMAX];

void precomputeFibonacci() {
    int i;
    F[1]=1;
    F[2]=1;
    for(i=3; i<=N+2; i++)
        F[i]=(F[i-2]+F[i-1])%MOD;
}

int term(int a1,int a2,int n) {
    if(n==0)
        return 0;
    if(n==1)
        return a1;
    if(n==2)
        return a2;

    if(a1<=a2)
        return (1LL*a1*F[n] + 1LL*F[n-1]*(a2-a1))%MOD;
    else
        return (1LL*a2*F[n] + 1LL*F[n-2]*(a1-a2))%MOD;
}

int sum(int a1,int a2,int i,int j) {
    return (term(a1,a2,j+2)-term(a1,a2,i+1)+MOD)%MOD;
}

void update(int nod,int lo,int hi,int b1,int b2) {
    if(L<=lo && hi<=R) {
        b1=(b1+F[lo-L+1])%MOD;
        b2=(b2+F[lo-L+2])%MOD;
        AI[nod].b1=(AI[nod].b1+b1)%MOD;
        AI[nod].b2=(AI[nod].b2+b2)%MOD;
        int s=sum(b1,b2,1,hi-lo+1);
        AI[nod].sum=(AI[nod].sum+s)%MOD;
        return;
    }

    if(hi<L || R<lo) {
        AI[nod].b1=(AI[nod].b1+b1)%MOD;
        AI[nod].b2=(AI[nod].b2+b2)%MOD;
        int s=sum(b1,b2,1,hi-lo+1);
        AI[nod].sum=(AI[nod].sum+s)%MOD;
        return;
    }

    int mi=(lo+hi)/2;

    update(2*nod,lo,mi,b1+AI[nod].b1,b2+AI[nod].b2);
    update(2*nod+1,mi+1,hi,term(b1+AI[nod].b1,b2+AI[nod].b2,mi+2-lo),term(b1+AI[nod].b1,b2+AI[nod].b2,mi+3-lo));

    AI[nod].b1=AI[nod].b2=0;
    AI[nod].sum=(AI[2*nod].sum+AI[2*nod+1].sum)%MOD;
}

int query(int nod,int lo,int hi,int b1,int b2) {
    if(L<=lo && hi<=R) {
        AI[nod].b1=(AI[nod].b1+b1)%MOD;
        AI[nod].b2=(AI[nod].b2+b2)%MOD;
        int s=sum(b1,b2,1,hi-lo+1);
        AI[nod].sum=(AI[nod].sum+s)%MOD;
        return AI[nod].sum;
    }

    if(hi<L || R<lo) {
        AI[nod].b1=(AI[nod].b1+b1)%MOD;
        AI[nod].b2=(AI[nod].b2+b2)%MOD;
        int s=sum(b1,b2,1,hi-lo+1);
        AI[nod].sum=(AI[nod].sum+s)%MOD;
        return 0;
    }

    int mi=(lo+hi)/2,q1,q2;

    q1=query(2*nod,lo,mi,b1+AI[nod].b1,b2+AI[nod].b2);
    q2=query(2*nod+1,mi+1,hi,term(b1+AI[nod].b1,b2+AI[nod].b2,mi+2-lo),term(b1+AI[nod].b1,b2+AI[nod].b2,mi+3-lo));

    AI[nod].b1=AI[nod].b2=0;
    AI[nod].sum=(AI[2*nod].sum+AI[2*nod+1].sum)%MOD;

    return (q1+q2)%MOD;
}

int main() {
    int i,x,op;

#ifndef ONLINE_JUDGE
    freopen(inputFile,"r",stdin);
    freopen(outputFile,"w",stdout);
#endif

    scanf("%d%d",&N,&M);

    for(i=1; i<=N; i++) {
        scanf("%d",&x);
        V[i]=(V[i-1]+x)%MOD;
    }

    precomputeFibonacci();

    while(M--) {
        scanf("%d%d%d",&op,&L,&R);

        if(op==1)
            update(1,1,N,0,0);

        if(op==2) {
            x=(query(1,1,N,0,0)+1LL*V[R]-1LL*V[L-1]+MOD)%MOD;
            printf("%d\n",x);
        }
    }

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define For(i,a,n) for(int i=a;i<n;i++)
#define Fore(i,a,n) for(int i=a;i<=n;i++)
typedef long long ll;
ll M=1000000009;
int f[300010];
int a[300010];
int getN(int x,int y,int n)
   {
   return (ll(x)*(f[n])%M+ll(y)*(f[n+1])%M)%M;
   }

void ver();
struct Nodo
   {
   int x,y,s,cant,inicio;
   bool lazy;
   Nodo(int xx,int yy,int ss):x(xx),y(yy),s(ss) {}
   Nodo() {}

   void init_hoja(int v,int p)
      {
      s=v;
      cant=1;
      x=0;
      y=0;
      inicio=p;
      lazy=0;
      }
   void update(int X,int Y)
      {
      lazy=1;
      //cout<<x<<" "<<y<<" _ "<<s<<" . "<<cant<<endl;
      x=(x+X)%M;
      y=(y+Y)%M;

      s=(s+(ll(X)*(getN(1,0,cant+2)-1+M)%M+ll(Y)*(getN(1,0,cant+3)-2+M)%M)%M)%M;
      //cout<<x<<" "<<y<<" _ "<<s<<" . "<<cant<<endl;
      }
   void merge(const Nodo&a,const Nodo &b)
      {
      s=(a.s+b.s)%M;
      x=0;
      y=0;
      inicio=a.inicio;
      cant=a.cant+b.cant;
      lazy=0;
      }
   void split(Nodo&a,Nodo &b)
      {
      a.update(x,y);
      int pos=(cant+1)/2;
      //cout<<getN(x,y,pos-2)<<","<<getN(x,y,pos-1)<<endl;
      b.update(getN(x,y,pos-1),getN(x,y,pos));
      a.lazy=1;
      b.lazy=1;
      lazy=0;
      x=0;
      y=0;
      //cout<<"splitando"<<endl;
      //ver();
      }
   void Ver()
      {
      cout<<x<<" "<<y<<" "<<s<<endl;
      }
   };
Nodo T[1050000];
void ver()
   {
   int n=26;
   For(i,1,n) cout<<setw(4)<<i;cout<<endl;
   For(i,1,n) cout<<setw(4)<<T[i].x;cout<<endl;
   For(i,1,n) cout<<setw(4)<<T[i].y; cout<<endl;
   For(i,1,n) cout<<setw(4)<<T[i].s; cout<<endl;
   For(i,1,n) cout<<setw(4)<<T[i].lazy; cout<<endl;
   cout<<endl;
   }

void init(int N,int L,int R)
   {
   if(L==R)
      T[N].init_hoja(a[L],L+1);
   else
      {
      int M=(L+R)>>1;
      int a=N<<1;
      init(a,L,M);
      init(a|1,M+1,R);
      T[N].merge(T[a],T[a|1]);
      }
   }
int I,J;
Nodo query(int N,int L,int R)
   {
   //cout<<"query "<<L<<" "<<R<<"  buscando "<<I<<" "<<J<<endl;;

   if(I<=L&& R<=J)
      {
      //cout<<"rett"<<endl;
      //cout<<L<<" "<<R<<" ";
      //T[N].Ver();
      //cout<<endl;
      return T[N];
      }
   int M=(L+R)/2;
   int a=N<<1;
   if(T[N].lazy)
      {
      //cout<<"splitando"<<endl;
      T[N].split(T[a],T[a|1]);
      //ver();
      }
   if(I>M) return query(a|1,M+1,R);
   if(J<=M) return  query(a,L,M);
   Nodo ans;
   ans.merge(query(a|1,M+1,R),query(a,L,M));
   /*
   cout<<"merging"<<endl;
   cout<<"r  "<<endl;
   cout<<L<<" "<<R<<" ";
   ans.Ver();
   cout<<endl;
   */

   return ans;
   }

void update_range(int N,int L,int R,int X,int Y,string e="")
   {
   //cout<<e<<"updating "<<L<<" "<<R<<" with "<<X<<" "<<Y<<endl;;
   if(I<=L&& R<=J)
      {
      //cout<<e<<"rango"<<L<<" "<<R<<endl ;
      T[N].update(X,Y);
      //ver();
      }
   else
      {
      //cout<<e<<" no rango"<<endl;
      int M=(L+R)/2;
      int a=N<<1;
      if(T[N].lazy)
         T[N].split(T[a],T[a|1]);
      //cout<<M<<"   "<<a<<" "<<a+1<<endl;
      if(I>M) //cout<<e<<"right"<<endl,
         update_range(a|1,M+1,R,X,Y,e+"   ");
      else if(J<=M) //cout<<e<<"left"<<endl,
      update_range(a,L,M,X,Y,e+"   ");
      else
         {
         //cout<<e<<" left?right "<<endl;
         //cout<<e<<M<<"-"<<I<<":"<<getN(X,Y,M-I)<<","<<getN(X,Y,M-I+1)<<endl;
         update_range(a|1,M+1,R,getN(X,Y,M-I),getN(X,Y,M-I+1),e+"   ");
         update_range(a,L,M,X,Y,e+"   ");
         }
      //cout<<e<<"Joining para "<<N<<endl;
      T[N].merge(T[a],T[a|1]);
      //ver();
      }
   }
int calc2(int n)
   {
   n--;
   int b=0;
   while(n>0)
      b++,n>>=1;
   return 1<<(b+1);
   }

int main()
   {

   int n,m,A,B,op;
   scanf("%d %d",&n,&m);
   f[0]=0;
   f[1]=1;
   A=n+4;
   Fore(i,2,A)
   f[i]=(f[i-1]+f[i-2])%M;
   For(i,0,n)
   //cout<<i<<":"<<getN(1,0,i)<<endl,
   scanf("%d",&a[i]);

   //Fore(i,0,A)
   //  cout<<i<<"="<<f[i]<<endl;;
   init(1,0,n-1);
   //ver();
   For(i,2,n)
      {
      I=i-2,J=i;
      //cout<<query(1,0,n-1).s<<endl;
      }
   I=0;
   J=n-1;
   //update_range(1,0,n-1,1,0);
   //ver();
   //cout<<endl;
   For(i,2,n)
      {
      I=i-2,J=i;
      //cout<<"__"<<query(1,0,n-1).s<<endl;
      }
   while(m--)
      {

      scanf("%d",&op);
      scanf("%d %d",&A,&B);

      if(op&1)
         {
         I=A-1;
         J=B-1;
         //cout<<I<<" "<<J<<endl;
         update_range(1,0,n-1,1,0);
         //   ver();
         //puts("________________");

         //add
         }
      else
         {
         // query
         I=A-1;
         J=B-1;
         //cout<<I<<" "<<J<<endl;
         cout<<query(1,0,n-1).s<<endl;
         }
      }
   return 0;
   }


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll M=100000009;
#define deb(a) cout<<#a<<"="<<a<<endl
int v[300010];
int f[300010];
int getN(int x,int y,int n)
   {
   return (ll(x)*ll(f[n])%M  +
          ll(y)*ll(f[n+1])%M)%M;
   }
struct nodo
   {
   int sum,x,y,num;
   bool lazy;
   void ver()
      {
      deb(x);
      deb(y);
      deb(num);
      deb(sum);
      deb(lazy);
      }
   void init_hoja(int i)
      {
      x=y=0;
      sum=v[i];
      num=1;
      }
   void merge(nodo a,nodo b)
      {
      sum=(a.sum+b.sum)%M;
      num=a.num+b.num;
      x=y=0;
      }
   void update(int xx,int yy)
      {
      x=(x+xx)%M;
      y=(y+yy)%M;
      sum=(ll(sum)+
           ll(xx)*ll((f[num+2]-1+M)%M)%M  +
           ll(yy)*ll((f[num+3]-2+M)%M)%M
           )%M;
      lazy=1;
      }
   void split(nodo &a,nodo &b,int pos)
      {
      a.update(x,y);
      b.update(getN(x,y,pos-1),getN(x,y,pos));
      x=y=0;
      lazy=0;
      }
   };

nodo T[1050000];
int I,J;
void init(int N,int L,int R)
   {
   if(L==R)
      T[N].init_hoja(L);
   else
      {
      int M=(L+R)>>1;
      int a=N<<1;
      init(a,L,M);
      init(a|1,M+1,R);
      T[N].merge(T[a],T[a|1]);
      }
   }
void ver()
   {
   for(int i=1; i<=7; i++) cout<<setw(3)<<i;
   cout<<endl;
   for(int i=1; i<=7; i++) cout<<setw(3)<<T[i].x;
   cout<<endl;
   for(int i=1; i<=7; i++) cout<<setw(3)<<T[i].y;
   cout<<endl;
   for(int i=1; i<=7; i++) cout<<setw(3)<<T[i].sum;
   cout<<endl;
   for(int i=1; i<=7; i++) cout<<setw(3)<<T[i].lazy;
   cout<<endl;
   cout<<endl;
   }
void update(int N,int L,int R,int x,int y)
   {
   if(I<=L&&R<=J)
      T[N].update(x,y);
   else
      {
      int M=(L+R)>>1;
      int a=N<<1;
      if(T[N].lazy)
         T[N].split(T[a],T[a|1],M-L+1);
      if(J<=M)
         update(a,L,M,x,y);
      else if(I>M)
         update(a|1,M+1,R,x,y);
      else
         {
         update(a,L,M,x,y);
         int pos=M-max(I,L)+1;
         update(a|1,M+1,R,getN(x,y,pos-1),getN(x,y,pos));
         }
      T[N].merge(T[a],T[a|1]);
      }
   }
nodo query(int N,int L,int R)
   {
   if(I<=L&&R<=J)
      return T[N];
   int M=(L+R)>>1;
   int a=N<<1;
   if(T[N].lazy)
      T[N].split(T[a],T[a|1],M-L+1);
   if(J<=M)
      return query(a,L,M);
   if(I>M)
      return query(a|1,M+1,R);
   nodo ans;
   ans.merge(query(a,L,M),query(a|1,M+1,R));
   return ans;
   }

int main()
   {
   //freopen("in.txt","r",stdin);
   int n,m,a;
   scanf("%d %d",&n,&m);
   a=n+4;
   for(int i=1; i<=n; i++)
      scanf("%d",&v[i]);
   f[0]=0;
   f[1]=1;
   for(int i=2; i<=a; i++)
      f[i]=(f[i-1]+f[i-2])%M;
   init(1,1,n);

   while(m--)
      {
      scanf("%d",&a);
      scanf("%d %d",&I,&J);
      if(a==1)
         update(1,1,n,1,0);
      else printf("%d\n",query(1,1,n).sum);
      }
   return 0;
   }


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll M=1000000009;
#define deb(a) cout<<#a<<"="<<a<<endl
#define as(a,x,b) assert(a<=x && x<=b)
int v[300010];
int f[300010];
int getN(int x,int y,int n)
   {
   as(0,(ll(x)*ll(f[n])%M  + ll(y)*ll(f[n+1])%M)%M,1000000008);
   return (ll(x)*ll(f[n])%M  + ll(y)*ll(f[n+1])%M)%M;
   }
struct nodo
   {
   int sum,x,y,num;
   bool lazy;
   void ver()
      {
      deb(x);
      deb(y);
      deb(num);
      deb(sum);
      deb(lazy);
      }
   void init_hoja(int i)
      {
      x=y=0;
      sum=v[i];
      num=1;
      }
   void merge(nodo a,nodo b)
      {
      sum=(a.sum+b.sum)%M;
      as(0,sum,1000000008);
      num=a.num+b.num;
      as(0,num,300000);
      x=y=0;
      }
   void update(int xx,int yy)
      {
      x=(x+xx)%M;
      as(0,x,1000000008);
      y=(y+yy)%M;
      as(0,y,1000000008);
      sum=(ll(sum)+
           ll(xx)*ll((f[num+2]-1+M)%M)%M  +
           ll(yy)*ll((f[num+3]-2+M)%M)%M
           )%M;
      as(0,sum,1000000008);
      lazy=1;
      }
   void split(nodo &a,nodo &b,int pos)
      {
      a.update(x,y);
      b.update(getN(x,y,pos-1),getN(x,y,pos));
      x=y=0;
      lazy=0;
      }
   };

nodo T[1050000];
int I,J;
void init(int N,int L,int R)
   {
   if(L==R)
      T[N].init_hoja(L);
   else
      {
      int M=(L+R)>>1;
      int a=N<<1;
      init(a,L,M);
      init(a|1,M+1,R);
      T[N].merge(T[a],T[a|1]);
      }
   }
void ver()
   {
   for(int i=1; i<=7; i++) cout<<setw(3)<<i;cout<<endl;
   for(int i=1; i<=7; i++) cout<<setw(3)<<T[i].x;cout<<endl;
   for(int i=1; i<=7; i++) cout<<setw(3)<<T[i].y;cout<<endl;
   for(int i=1; i<=7; i++) cout<<setw(3)<<T[i].sum;cout<<endl;
   for(int i=1; i<=7; i++) cout<<setw(3)<<T[i].lazy;cout<<endl;
   cout<<endl;
   }
void update(int N,int L,int R,int x,int y)
   {
   if(I<=L&&R<=J)
      T[N].update(x,y);
   else
      {
      int M=(L+R)>>1;
      int a=N<<1;
      if(T[N].lazy)
         T[N].split(T[a],T[a|1],M-L+1);
      if(J<=M)
         update(a,L,M,x,y);
      else if(I>M)
         update(a|1,M+1,R,x,y);
      else
         {
         update(a,L,M,x,y);
         int pos=M-max(I,L)+1;
         update(a|1,M+1,R,getN(x,y,pos-1),getN(x,y,pos));
         }
      T[N].merge(T[a],T[a|1]);
      }
   }
nodo query(int N,int L,int R)
   {
   if(I<=L&&R<=J)
      return T[N];
   int M=(L+R)>>1;
   int a=N<<1;
   if(T[N].lazy)
      T[N].split(T[a],T[a|1],M-L+1);
   if(J<=M)
      return query(a,L,M);
   if(I>M)
      return query(a|1,M+1,R);
   nodo ans;
   ans.merge(query(a,L,M),query(a|1,M+1,R));
   return ans;
   }

int main()
   {

   int n,m,a;
   scanf("%d %d",&n,&m);
   a=n+4;
   for(int i=1; i<=n; i++)
      scanf("%d",&v[i]);
   f[0]=0;
   f[1]=1;
   for(int i=2; i<=a; i++)
      {
      f[i]=(f[i-1]+f[i-2])%M;
      as(0,f[i],1000000008);
      }
   init(1,1,n);

   while(m--)
      {
      scanf("%d",&a);
      scanf("%d %d",&I,&J);
      if(a==1)
         update(1,1,n,1,0);
      else printf("%d\n",query(1,1,n).sum);
      }
   return 0;
   }


#include<bits/stdc++.h>
using namespace std;
#define For(i,a,n) for(int i=a;i<n;i++)
#define Fore(i,a,n) for(int i=a;i<=n;i++)
typedef long long ll;
ll M=1000000009;
int f[300010];
int a[300010];
int getF(int i)
   {
   if(i==-1) return 1;
   return f[i];
   }
void ver();
struct Nodo
   {
   int x,y,s,cant,inicio;
   bool lazy;
   Nodo(int xx,int yy,int ss):x(xx),y(yy),s(ss) {}
   Nodo() {}

   void init_hoja(int v,int p)
      {
      s=v;
      cant=1;
      x=0;
      y=0;
      inicio=p;
      lazy=0;
      }
   void update(int X,int Y)
      {
      lazy=1;
      //cout<<x<<" "<<y<<" _ "<<s<<" . "<<cant<<endl;
      x=(x+X)%M;
      y=(y+Y)%M;

      s=(s+(ll(X)*(getF(cant+2)-1+M)%M+ll(Y)*(getF(cant+3)-2+M)%M)%M)%M;
      //cout<<x<<" "<<y<<" _ "<<s<<" . "<<cant<<endl;
      }
   void merge(const Nodo&a,const Nodo &b)
      {
      s=(a.s+b.s)%M;
      x=(a.x+b.x)%M;
      y=(a.y+b.y)%M;
      inicio=a.inicio;
      cant=a.cant+b.cant;
      lazy=0;
      }
   void split(Nodo&a,Nodo &b)
      {
      a.update(x,y);
      int pos=inicio+(cant+1)/2;
      b.update(getF(pos-2),getF(pos-1));
      a.lazy=1;
      b.lazy=1;
      lazy=0;
      x=0;
      y=0;
      //ver();
      }
   void Ver()
      {
      cout<<x<<" "<<y<<" "<<s<<endl;
      }
   };
Nodo T[1050000];
void ver()
   {
   int n=8;
   For(i,1,n) cout<<setw(3)<<i;
   cout<<endl;
   For(i,1,n) cout<<setw(3)<<T[i].x;
   cout<<endl;
   For(i,1,n) cout<<setw(3)<<T[i].y;
   cout<<endl;
   For(i,1,n) cout<<setw(3)<<T[i].s;
   cout<<endl;
   For(i,1,n) cout<<setw(3)<<T[i].lazy;
   cout<<endl;
   cout<<endl;
   }

void init(int N,int L,int R)
   {
   if(L==R)
      T[N].init_hoja(a[L],L+1);
   else
      {
      int M=(L+R)>>1;
      int a=N<<1;
      init(a,L,M);
      init(a|1,M+1,R);
      T[N].merge(T[a],T[a|1]);
      }
   }
int I,J;
Nodo query(int N,int L,int R)
   {
   //cout<<"query "<<L<<" "<<R<<"  buscando "<<I<<" "<<J<<endl;;

   if(I<=L&& R<=J)
      {
      //cout<<"rett"<<endl;
      //cout<<L<<" "<<R<<" ";
      //T[N].Ver();
      //cout<<endl;
      return T[N];
      }
   int M=(L+R)/2;
   int a=N<<1;
   if(T[N].lazy)
      {
      //cout<<"splitando"<<endl;
      T[N].split(T[a],T[a|1]);
      //ver();
      }
   if(I>M) return query(a|1,M+1,R);
   if(J<=M) return  query(a,L,M);
   Nodo ans;
   ans.merge(query(a|1,M+1,R),query(a,L,M));
   /*
   cout<<"merging"<<endl;
   cout<<"r  "<<endl;
   cout<<L<<" "<<R<<" ";
   ans.Ver();
   cout<<endl;
   */

   return ans;
   }
void update_range(int N,int L,int R,int X,int Y)
   {
   //cout<<"updating "<<L<<" "<<R<<" with "<<X<<" "<<Y<<endl;;
   if(I<=L&& R<=J)
      {
      //cout<<e<<"rango"<<L<<" "<<R<<endl ;
      T[N].update(X,Y);
      //ver();
      }
   else
      {
      //cout<<e<<" no rango"<<endl;
      int M=(L+R)/2;
      int a=N<<1;
      if(T[N].lazy)
         T[N].split(T[a],T[a|1]);
      int pos=L+(T[N].cant+1)/2;
      if(I>M) //cout<<e<<"right"<<endl,
         update_range(a|1,M+1,R,getF(pos-2),getF(pos-1));
      else if(J<=M) //cout<<e<<"left"<<endl,
      update_range(a,L,M,X,Y);
      else
         {
         //cout<<e<<"left?right"<<pos<<endl;
         update_range(a|1,M+1,R,getF(pos-2),getF(pos-1));
         update_range(a,L,M,X,Y);
         }
      T[N].merge(T[a],T[a|1]);

      }
   }
int calc2(int n)
   {
   n--;
   int b=0;
   while(n>0)
      b++,n>>=1;
   return 1<<(b+1);
   }

int main()
   {

   int n,m,A,B,op;
   scanf("%d %d",&n,&m);
   For(i,0,n)
   scanf("%d",&a[i]);
   f[0]=0;
   f[1]=1;
   A=n+4;
   Fore(i,2,A)
   f[i]=(f[i-1]+f[i-2])%M;
   //Fore(i,0,A)
   //  cout<<i<<"="<<f[i]<<endl;;
   init(1,0,n-1);
   //ver();
   For(i,2,n)
      {
      I=i-2,J=i;
      //cout<<query(1,0,n-1).s<<endl;
      }
   I=0;
   J=n-1;
   //update_range(1,0,n-1,1,0);
   //ver();
   //cout<<endl;
   For(i,2,n)
      {
      I=i-2,J=i;
      //cout<<"__"<<query(1,0,n-1).s<<endl;
      }
   while(m--)
      {

      scanf("%d",&op);
      scanf("%d %d",&A,&B);

      if(op&1)
         {
         I=A-1;
         J=B-1;
         update_range(1,0,n-1,1,0);

         //add
         }
      else
         {
         // query
         I=A-1;
         J=B-1;
         cout<<query(1,0,n-1).s<<endl;
         }
      //ver();
      //puts("________________");
      }
   return 0;
   }


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll M=1000000009;
#define deb(a) cout<<#a<<"="<<a<<endl
int v[300010];
int f[300010];
int getN(int x,int y,int n)
   {
   return (ll(x)*ll(f[n])%M  + ll(y)*ll(f[n+1])%M)%M;
   }
struct nodo
   {
   int sum,x,y,num;
   bool lazy;
   void ver()
      {
      deb(x);
      deb(y);
      deb(num);
      deb(sum);
      deb(lazy);
      }
   void init_hoja(int i)
      {
      x=y=0;
      sum=v[i];
      num=1;
      }
   void merge(nodo a,nodo b)
      {
      sum=(a.sum+b.sum)%M;
      num=a.num+b.num;
      x=y=0;
      }
   void update(int xx,int yy)
      {
      x=(x+xx)%M;
      y=(y+yy)%M;
      sum=(ll(sum)+
           ll(xx)*ll((f[num+2]-1+M)%M)%M  +
           ll(yy)*ll((f[num+3]-2+M)%M)%M
           )%M;
      lazy=1;
      }
   void split(nodo &a,nodo &b,int pos)
      {
      a.update(x,y);
      b.update(getN(x,y,pos-1),getN(x,y,pos));
      x=y=0;
      lazy=0;
      }
   };

nodo T[1050000];
int I,J;
void init(int N,int L,int R)
   {
   if(L==R)
      T[N].init_hoja(L);
   else
      {
      int M=(L+R)>>1;
      int a=N<<1;
      init(a,L,M);
      init(a|1,M+1,R);
      T[N].merge(T[a],T[a|1]);
      }
   }
void update(int N,int L,int R,int x,int y)
   {
   if(I<=L&&R<=J)
      T[N].update(x,y);
   else
      {
      int M=(L+R)>>1;
      int a=N<<1;
      if(T[N].lazy)
         T[N].split(T[a],T[a|1],M-L+1);
      if(J<=M)
         update(a,L,M,x,y);
      else if(I>M)
         update(a|1,M+1,R,x,y);
      else
         {
         update(a,L,M,x,y);
         int pos=M-max(I,L)+1;
         update(a|1,M+1,R,getN(x,y,pos-1),getN(x,y,pos));
         }
      T[N].merge(T[a],T[a|1]);
      }
   }
nodo query(int N,int L,int R)
   {
   if(I<=L&&R<=J)
      return T[N];
   int M=(L+R)>>1;
   int a=N<<1;
   if(T[N].lazy)
      T[N].split(T[a],T[a|1],M-L+1);
   if(J<=M)
      return query(a,L,M);
   if(I>M)
      return query(a|1,M+1,R);
   nodo ans;
   ans.merge(query(a,L,M),query(a|1,M+1,R));
   return ans;
   }
typedef unsigned int uint;
template<class T>
T in()
   {
   T n=0;
   char p;
   for(; (uint)((p=getchar())-'0')>9;)
      {
      if(p=='-') return -in<T>();
      //if (!~c) throw ~0;
      }
   for(n=p-'0'; (uint)((p=getchar())-'0')<10; n=n*10+p-'0');
   return n;
   }
#define get() in<int>()
int main()
   {

   int n,m,a;
   //scanf("%d %d",&n,&m);
   n=get();
   m=get();
   a=n+4;
   for(int i=1; i<=n; i++)
      //scanf("%d",&v[i]);
      v[i]=get();
   f[0]=0;
   f[1]=1;
   for(int i=2; i<=a; i++)
      f[i]=(f[i-1]+f[i-2])%M;
   init(1,1,n);
   while(m--)
      {
      //scanf("%d",&a);
      a=get();
      //scanf("%d %d",&I,&J);
      I=get();
      J=get();
      if(a==1)
         update(1,1,n,1,0);
      else printf("%d\n",query(1,1,n).sum);
      }
   return 0;
   }


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 500;
int n, m;

class SegTree{
	typedef ll SegT;
	private:
		vector<SegT> val;
		int n;

	public:
		SegTree(const vector<SegT> &in){
			n=1;
			while(n<in.size())n<<=1;
			val=vector<SegT>(2*n, 0ll);
			for(int i=n-1 + in.size()-1;i>=0;i--){
				if(n-1 <= i) val[i] = in[i - (n-1)];
				else val[i] = val[i*2+1] + val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		void update(int i,SegT a){
			i+=n-1;
			val[i]+=a;
			if(val[i] >= MOD) val[i] -= MOD;
			while(i>0){
				i=(i-1)/2;
				val[i]=val[i*2+1]+val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		SegT query(int a,int b,int k=0,int l=0,int r=-1){
			if(r==-1)r=n;
			if(r<=a||b<=l) return 0ll;
			if(a<=l&&r<=b){
				return val[k];
			}else{
				SegT ret = query(a,b,k*2+1,l,(l+r)/2)+query(a,b,k*2+2,(l+r)/2,r);

				return ret>=MOD ? ret-MOD : ret;
			}
		}
};

ll F[300005];
ll sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002){
		sumFib[i+1] = sumFib[i] + F[i];
		if(sumFib[i+1] >= MOD) sumFib[i+1] -= MOD;
	}
	scanf("%d%d", &n, &m);
	vector<ll> init(n+1);
	REP(i, n) scanf("%I64d", &init[i+1]);
	SegTree seg(init);

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<ll> fib(n+3);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = seg.query(l, r);
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - (r-l-1 >= 0 ? F[r-l-1] : 1);
//				printf("fib[%d] += MOD - %d\n", r, F[r-l]);
				if(fib[l] >= MOD) fib[l] -= MOD;
				if(fib[r] >= MOD) fib[r] -= MOD;
				if(fib[r+1] >= MOD) fib[r+1] -= MOD;
			}
		}
		p += BLOCK;
//		cout << fib << endl;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+1){
			if(i+2 < n+3){
				fib[i+2] += fib[i+1] + fib[i];
				while(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			seg.update(i, fib[i]);
		}
//		cout << fib << endl;
//		REP(i, n+1) printf("%d ", seg.query(i+1, i+2));
//		puts("");
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 400;
int n, m;

int F[300005];
int sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002) sumFib[i+1] = (sumFib[i] + F[i]) % MOD;

	scanf("%d%d", &n, &m);
	vector<int> init(n+1), sum(n+2);
	REP(i, n) scanf("%I64d", &init[i+1]);
	REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<int> fib(n+3);
		vi upd;
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = sum[r] - sum[l];
				REP(j, upd.size()){
					if(Q[p+upd[j]].S == 1){
						int ll = max(l, Q[p+upd[j]].F.F);
						int rr = min(r, Q[p+upd[j]].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+upd[j]].F.F] - sumFib[ll - Q[p+upd[j]].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - (r-l-1 >= 0 ? F[r-l-1] : 1);
//				printf("fib[%d] += MOD - %d\n", r, F[r-l]);
				if(fib[l] >= MOD) fib[l] -= MOD;
				if(fib[r] >= MOD) fib[r] -= MOD;
				if(fib[r+1] >= MOD) fib[r+1] -= MOD;
				upd.push_back(i);
			}
		}
		p += BLOCK;
//		cout << fib << endl;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+1){
			if(i+2 < n+3){
				fib[i+2] += fib[i+1];
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
				fib[i+2] += fib[i];
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			(init[i] += fib[i]) %= MOD;
		}
		REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;
//		cout << fib << endl;
//		REP(i, n+1) printf("%d ", seg.query(i+1, i+2));
//		puts("");
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 500;
int n, m;

int F[300005];
int sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002) sumFib[i+1] = (sumFib[i] + F[i]) % MOD;

	scanf("%d%d", &n, &m);
	vector<int> init(n+1), sum(n+2);
	REP(i, n) scanf("%I64d", &init[i+1]);
	REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<int> fib(n+3);
		vi upd;
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = sum[r] - sum[l];
				REP(j, upd.size()){
					if(Q[p+upd[j]].S == 1){
						int ll = max(l, Q[p+upd[j]].F.F);
						int rr = min(r, Q[p+upd[j]].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+upd[j]].F.F] - sumFib[ll - Q[p+upd[j]].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - (r-l-1 >= 0 ? F[r-l-1] : 1);
//				printf("fib[%d] += MOD - %d\n", r, F[r-l]);
				if(fib[l] >= MOD) fib[l] -= MOD;
				if(fib[r] >= MOD) fib[r] -= MOD;
				if(fib[r+1] >= MOD) fib[r+1] -= MOD;
				upd.push_back(i);
			}
		}
		p += BLOCK;
//		cout << fib << endl;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+1){
			if(i+2 < n+3){
				fib[i+2] += fib[i+1] + fib[i];
				while(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			(init[i] += fib[i]) %= MOD;
		}
		REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;
//		cout << fib << endl;
//		REP(i, n+1) printf("%d ", seg.query(i+1, i+2));
//		puts("");
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 700;
int n, m;

class SegTree{
	typedef int SegT;
	private:
		vector<SegT> val;
		int n;

	public:
		SegTree(const vector<SegT> &in){
			n=1;
			while(n<in.size())n<<=1;
			val=vector<SegT>(2*n, 0ll);
			for(int i=n-1 + in.size()-1;i>=0;i--){
				if(n-1 <= i) val[i] = in[i - (n-1)];
				else val[i] = val[i*2+1] + val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		//i �Ԗڂ̗v�f�� a �ɍX�V����
		void update(int i,SegT a){
			i+=n-1;
			val[i]+=a;
			if(val[i] >= MOD) val[i] -= MOD;
			while(i>0){
				i=(i-1)/2;
				val[i]=val[i*2+1]+val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		//[a, b) �̒l������Ă���
		SegT query(int a,int b,int k=0,int l=0,int r=-1){
			if(r==-1)r=n;
			if(r<=a||b<=l) return 0ll;
			if(a<=l&&r<=b){
				return val[k];
			}else{
				SegT ret = query(a,b,k*2+1,l,(l+r)/2)+query(a,b,k*2+2,(l+r)/2,r);

				return ret>=MOD ? ret-MOD : ret;
			}
		}
};

int F[300005];
int sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300000){
		sumFib[i+1] = sumFib[i] + F[i];
		if(sumFib[i+1] >= MOD) sumFib[i+1] -= MOD;
	}
	scanf("%d%d", &n, &m);
	vi init(n+1);
	REP(i, n) scanf("%d", &init[i+1]);
	SegTree seg(init);

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vi fib(n+2);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = seg.query(l, r);
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", res % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
//				printf("fib[%d] += MOD - %d\n", r, F[r-l]);
				if(fib[l] >= MOD) fib[l] -= MOD;
				if(fib[r] >= MOD) fib[r] -= MOD;
			}
		}
		p += BLOCK;
//		cout << fib << endl;
		REP(i, n+1){
			if(i+2 < n+2){
				fib[i+2] += fib[i+1] + fib[i];
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			seg.update(i, fib[i]);
		}
//		cout << fib << endl;
//		REP(i, n+1) printf("%d ", seg.query(i+1, i+2));
//		puts("");
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 500;
int n, m;

int F[300005];
int sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002) sumFib[i+1] = (sumFib[i] + F[i]) % MOD;

	scanf("%d%d", &n, &m);
	vector<int> init(n+1), sum(n+2);
	REP(i, n) scanf("%I64d", &init[i+1]);
	REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<int> fib(n+3);
		vi upd;
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = sum[r] - sum[l];
				REP(j, upd.size()){
					if(Q[p+upd[j]].S == 1){
						int ll = max(l, Q[p+upd[j]].F.F);
						int rr = min(r, Q[p+upd[j]].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+upd[j]].F.F] - sumFib[ll - Q[p+upd[j]].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - (r-l-1 >= 0 ? F[r-l-1] : 1);
//				printf("fib[%d] += MOD - %d\n", r, F[r-l]);
				if(fib[l] >= MOD) fib[l] -= MOD;
				if(fib[r] >= MOD) fib[r] -= MOD;
				if(fib[r+1] >= MOD) fib[r+1] -= MOD;
				upd.push_back(i);
			}
		}
		p += BLOCK;
//		cout << fib << endl;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+1){
			if(i+2 < n+3){
				fib[i+2] += fib[i+1];
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
				fib[i+2] += fib[i];
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			(init[i] += fib[i]) %= MOD;
		}
		REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;
//		cout << fib << endl;
//		REP(i, n+1) printf("%d ", seg.query(i+1, i+2));
//		puts("");
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 700;
int n, m;

class SegTree{
	typedef ll SegT;
	private:
		vector<SegT> val;
		int n;

	public:
		SegTree(const vector<SegT> &in){
			n=1;
			while(n<in.size())n<<=1;
			val=vector<SegT>(2*n, 0ll);
			for(int i=n-1 + in.size()-1;i>=0;i--){
				if(n-1 <= i) val[i] = in[i - (n-1)];
				else val[i] = val[i*2+1] + val[i*2+2];
				val[i] %= MOD;
			}
		}
		//i �Ԗڂ̗v�f�� a �ɍX�V����
		void update(int i,SegT a){
			i+=n-1;
			(val[i]+=a)%=MOD;
			while(i>0){
				i=(i-1)/2;
				val[i]=(val[i*2+1]+val[i*2+2])%MOD;
			}
		}
		//[a, b) �̒l������Ă���
		SegT query(int a,int b,int k=0,int l=0,int r=-1){
			if(r==-1)r=n;
			if(r<=a||b<=l) return 0ll;
			if(a<=l&&r<=b){
				return val[k];
			}else{
				SegT ret = query(a,b,k*2+1,l,(l+r)/2)+query(a,b,k*2+2,(l+r)/2,r);

				return ret%MOD;
			}
		}
};

ll F[300005];
ll sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	sumFib[0] = 0;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002){
		sumFib[i+1] = (sumFib[i] + F[i]) % MOD;
	}
	scanf("%d%d", &n, &m);
	vector<ll> init(n+1);
	REP(i, n) scanf("%I64d", &init[i+1]);
	SegTree seg(init);

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<ll> fib(n+3);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = seg.query(l, r);
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				if(r-l-1 >= 0) fib[r+1] += MOD - F[r-l-1];
//				printf("fib[%d] += MOD - %d\n", r, F[r-l]);
				if(fib[l] >= MOD) fib[l] -= MOD;
				if(fib[r] >= MOD) fib[r] -= MOD;
				if(fib[r+1] >= MOD) fib[r+1] -= MOD;
			}
		}
		p += BLOCK;
//		cout << fib << endl;
		REP(i, n+1){
			if(i+2 < n+3){
				fib[i+2] += fib[i+1] + fib[i];
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			seg.update(i, fib[i]);
		}
//		cout << fib << endl;
//		REP(i, n+1) printf("%d ", seg.query(i+1, i+2));
//		puts("");
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 700;
int n, m;

int F[300005];
int sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002) sumFib[i+1] = (sumFib[i] + F[i]) % MOD;

	scanf("%d%d", &n, &m);
	vector<int> init(n+1), sum(n+2);
	REP(i, n) scanf("%I64d", &init[i+1]);
	REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<int> fib(n+3);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = sum[r] - sum[l];
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - (r-l-1 >= 0 ? F[r-l-1] : 1);
				if(fib[l] >= MOD) fib[l] %= MOD;
				if(fib[r] >= MOD) fib[r] %= MOD;
				if(fib[r+1] >= MOD) fib[r+1] %= MOD;
			}
		}
		p += BLOCK;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+1){
			if(i+2 < n+3){
				fib[i+2] += (fib[i+1] + fib[i])%MOD;
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			(init[i] += fib[i]) %= MOD;
			sum[i+1] = (sum[i] + init[i]) % MOD;
		}
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 700;
int n, m;

class SegTree{
	typedef ll SegT;
	private:
		vector<SegT> val;
		int n;

	public:
		SegTree(const vector<SegT> &in){
			n=1;
			while(n<in.size())n<<=1;
			val=vector<SegT>(2*n, 0ll);
			for(int i=n-1 + in.size()-1;i>=0;i--){
				if(n-1 <= i) val[i] = in[i - (n-1)];
				else val[i] = val[i*2+1] + val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		//i �Ԗڂ̗v�f�� a �ɍX�V����
		void update(int i,SegT a){
			i+=n-1;
			val[i]+=a;
			if(val[i] >= MOD) val[i] -= MOD;
			while(i>0){
				i=(i-1)/2;
				val[i]=val[i*2+1]+val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		//[a, b) �̒l������Ă���
		SegT query(int a,int b,int k=0,int l=0,int r=-1){
			if(r==-1)r=n;
			if(r<=a||b<=l) return 0ll;
			if(a<=l&&r<=b){
				return val[k];
			}else{
				SegT ret = query(a,b,k*2+1,l,(l+r)/2)+query(a,b,k*2+2,(l+r)/2,r);

				return ret>=MOD ? ret-MOD : ret;
			}
		}
};

ll F[300005];
ll sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002){
		sumFib[i+1] = sumFib[i] + F[i];
		if(sumFib[i+1] >= MOD) sumFib[i+1] -= MOD;
	}
	scanf("%d%d", &n, &m);
	vector<ll> init(n+1);
	REP(i, n) scanf("%I64d", &init[i+1]);
	SegTree seg(init);

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<ll> fib(n+3);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = seg.query(l, r);
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - F[r-l-1];
//				printf("fib[%d] += MOD - %d\n", r, F[r-l]);
				if(fib[l] >= MOD) fib[l] -= MOD;
				if(fib[r] >= MOD) fib[r] -= MOD;
				if(fib[r+1] >= MOD) fib[r+1] -= MOD;
			}
		}
		p += BLOCK;
//		cout << fib << endl;
		REP(i, n+1){
			if(i+2 < n+2){
				fib[i+2] += fib[i+1] + fib[i];
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			seg.update(i, fib[i]);
		}
//		cout << fib << endl;
//		REP(i, n+1) printf("%d ", seg.query(i+1, i+2));
//		puts("");
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 400;
int n, m;

int F[300005];
int sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002) sumFib[i+1] = (sumFib[i] + F[i]) % MOD;

	scanf("%d%d", &n, &m);
	vector<int> init(n+1), sum(n+2);
	REP(i, n) scanf("%I64d", &init[i+1]);
	REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<int> fib(n+3);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = sum[r] - sum[l];
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - (r-l-1 >= 0 ? F[r-l-1] : 1);
				if(fib[l] >= MOD) fib[l] %= MOD;
				if(fib[r] >= MOD) fib[r] %= MOD;
				if(fib[r+1] >= MOD) fib[r+1] %= MOD;
			}
		}
		p += BLOCK;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+1){
			if(i+2 < n+3){
				fib[i+2] += (fib[i+1] + fib[i])%MOD;
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			(init[i] += fib[i]) %= MOD;
			sum[i+1] = (sum[i] + init[i]) % MOD;
		}
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 1000;
int n, m;

int F[300005];
int sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002) sumFib[i+1] = (sumFib[i] + F[i]) % MOD;

	scanf("%d%d", &n, &m);
	vector<int> init(n+1), sum(n+2);
	REP(i, n) scanf("%I64d", &init[i+1]);
	REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<int> fib(n+3);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = sum[r] - sum[l];
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - (r-l-1 >= 0 ? F[r-l-1] : 1);
				if(fib[l] >= MOD) fib[l] %= MOD;
				if(fib[r] >= MOD) fib[r] %= MOD;
				if(fib[r+1] >= MOD) fib[r+1] %= MOD;
			}
		}
		p += BLOCK;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+1){
			if(i+2 < n+3){
				fib[i+2] += (fib[i+1] + fib[i])%MOD;
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			(init[i] += fib[i]) %= MOD;
			sum[i+1] = (sum[i] + init[i]) % MOD;
		}
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );

template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000007;

// ��ԉ��Z ��ԍ��v

class RARS{
	typedef ll SegT;
	class SegTree{
		private:
			vector<SegT> val;
			int n;

			SegT combine(SegT a, SegT b){
				return a + b;
			}

		public:
			SegTree(int size){
				n=1;
				while(n<size)n<<=1;
				val=vector<SegT>(2*n, 0);
			}
			SegTree(const vector<SegT> &in){
				n=1;
				while(n<in.size())n<<=1;
				val=vector<SegT>(2*n, 0);
				for(int i=n-1 + in.size()-1;i>=0;i--){
					if(n-1 <= i) val[i] = in[i - (n-1)];
					else val[i] = combine(val[i*2+1],val[i*2+2]);
				}
			}
			//i �Ԗڂ̗v�f�� a �ɍX�V����
			void update(int i,SegT a){
				i+=n-1;
				val[i]+=a;
				while(i>0){
					i=(i-1)/2;
					val[i]=combine(val[i*2+1],val[i*2+2]);
				}
			}
			//[a, b) �̒l������Ă���
			SegT query(int a,int b,int k=0,int l=0,int r=-1){
				if(r==-1)r=n;
				if(r<=a||b<=l) return 0;
				if(a<=l&&r<=b){
					return val[k];
				}else{
					return combine(query(a,b,k*2+1,l,(l+r)/2),query(a,b,k*2+2,(l+r)/2,r));
				}
			}
	};
    SegTree dif, pre;
public:
    RARS(int n):dif(n),pre(n){}
    void add(int s, int t, ll v){
        dif.update(s, v);
        dif.update(t, -v);
        pre.update(s, v * s);
        pre.update(t, -v * t);
    }
    ll sum(int s, int t){
        if (s > 0) return sum(0, t) - sum(0, s);
        return dif.query(0, t) * t - pre.query(0, t);
    }
};

int n, m;
main(){
	scanf("%d%d", &n, &m);
	RARS seg(n);
	set<pii> range;
	REP(i, n+1) range.insert(pii(i, i));
	REP(i, m){
		int type, l, r, x;
		scanf("%d%d%d", &type, &l, &r);
		if(type == 1){
			scanf("%d", &x);
			l --;
			auto it = range.lower_bound(pii(l+1, 0));
			int w = it->second;
			--it;
			if(it->first < l) range.insert(pii(l, w));
			it = range.lower_bound(pii(l+1, 0));
			while(it!=range.end() && it->first <= r){
				seg.add(l, it->first, abs(x - it->second));
				l = it->first;
				it = range.erase(it);
			}
			seg.add(l, r, abs(x - it->second));
			range.insert(pii(r, x));
		}else{
			printf("%I64d\n", seg.sum(l-1, r));
		}
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 600;
int n, m;

int F[300005];
int sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002) sumFib[i+1] = (sumFib[i] + F[i]) % MOD;

	scanf("%d%d", &n, &m);
	vector<int> init(n+1), sum(n+2);
	REP(i, n) scanf("%I64d", &init[i+1]);
	REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<int> fib(n+3);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = sum[r] - sum[l];
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - (r-l-1 >= 0 ? F[r-l-1] : 1);
				if(fib[l] >= MOD) fib[l] %= MOD;
				if(fib[r] >= MOD) fib[r] %= MOD;
				if(fib[r+1] >= MOD) fib[r+1] %= MOD;
			}
		}
		p += BLOCK;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+1){
			if(i+2 < n+3){
				fib[i+2] += (fib[i+1] + fib[i])%MOD;
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			(init[i] += fib[i]) %= MOD;
			sum[i+1] = (sum[i] + init[i]) % MOD;
		}
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 1000;
int n, m;

class SegTree{
	typedef ll SegT;
	private:
		vector<SegT> val;
		int n;

	public:
		SegTree(const vector<SegT> &in){
			n=1;
			while(n<in.size())n<<=1;
			val=vector<SegT>(2*n, 0ll);
			for(int i=n-1 + in.size()-1;i>=0;i--){
				if(n-1 <= i) val[i] = in[i - (n-1)];
				else val[i] = val[i*2+1] + val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		void update(int i,SegT a){
			i+=n-1;
			val[i]+=a;
			if(val[i] >= MOD) val[i] -= MOD;
			while(i>0){
				i=(i-1)/2;
				val[i]=val[i*2+1]+val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		SegT query(int a,int b,int k=0,int l=0,int r=-1){
			if(r==-1)r=n;
			if(r<=a||b<=l) return 0ll;
			if(a<=l&&r<=b){
				return val[k];
			}else{
				SegT ret = query(a,b,k*2+1,l,(l+r)/2)+query(a,b,k*2+2,(l+r)/2,r);

				return ret>=MOD ? ret-MOD : ret;
			}
		}
};

ll F[300005];
ll sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002){
		sumFib[i+1] = sumFib[i] + F[i];
		if(sumFib[i+1] >= MOD) sumFib[i+1] -= MOD;
	}
	scanf("%d%d", &n, &m);
	vector<ll> init(n+1);
	REP(i, n) scanf("%I64d", &init[i+1]);
	SegTree seg(init);

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<ll> fib(n+3);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = seg.query(l, r);
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - (r-l-1 >= 0 ? F[r-l-1] : 1);
//				printf("fib[%d] += MOD - %d\n", r, F[r-l]);
				if(fib[l] >= MOD) fib[l] -= MOD;
				if(fib[r] >= MOD) fib[r] -= MOD;
				if(fib[r+1] >= MOD) fib[r+1] -= MOD;
			}
		}
		p += BLOCK;
//		cout << fib << endl;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+1){
			if(i+2 < n+2){
				fib[i+2] += fib[i+1] + fib[i];
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			seg.update(i, fib[i]);
		}
		if(n == 1865)cout << "BEND" << endl;
//		cout << fib << endl;
//		REP(i, n+1) printf("%d ", seg.query(i+1, i+2));
//		puts("");
	}
	return 0;
}