#include <iostream>
using namespace std;
struct mat {
    int a, b, c;
    mat () {}
    mat ( int a_, int b_, int c_ ) { a = a_; b = b_; c = c_; }
};
struct v {
    int val;
    int a, b;
    v () { a = 0, b = 0, val = 0; }
}it[10000042];
long long   mod = 1000000009;

void modd ( long long &a ) {
    if ( a < 0 ) { a += mod; }
    if ( a >= mod ) { a -= mod; }
    if ( a >= mod ) { a %= mod; }
}
void modd ( int &a ) {
    if ( a < 0 ) { a += mod; }
    if ( a >= mod ) { a -= mod; }
    if ( a >= mod ) { a %= mod; }
}
mat mult ( mat a, mat b ) {
    mat ans;
    ans.a = (1LL*a.a*b.a + 1LL*a.b*b.b)%mod;
    ans.b =  (1LL*a.a*b.b + 1LL*a.b*b.c)%mod;
    ans.c = (1LL*a.b*b.b + 1LL*a.c*b.c)%mod;
    return ans;
}
mat pows[32];
int getFib( int a, int b, int n ) {
    if ( n == -1 ) { return 0; }
    mat crr ( a, b, a+b );
    for ( int i = 0 ; i < 32 ; i ++ ) {
        if ( n&(1<<i) ) {
            crr = mult( crr, pows[i] );
        }
    }
    return crr.a%mod;
}
void prePows ( ) {
    pows[0] = mat ( 0, 1, 1 );
    for ( int i = 1 ; i < 32 ; i ++ ) {
        pows[i] = mult( pows[i-1], pows[i-1] );
    }
}
int n, m, k = 18;
void handle (int ind, int s ) {
    if ( it[ind].a == 0 && it[ind].b == 0 ) { return; }
    if ( ind >= (1<<k) ) {
        it[ind].val += it[ind].a;
        modd( it[ind].val );
        it[ind].a = 0; it[ind].b = 0;
    }

    it[ind].val += (1LL*getFib( it[ind].a, it[ind].b, s+1 ) - 1LL*getFib( it[ind].a, it[ind].b, 1 )+mod)%mod;
    modd( it[ind].val );

    it [ind*2].a += getFib( it[ind].a, it[ind].b, 0 );
    modd ( it[ind*2].a );
    it [ind*2].b += getFib( it[ind].a, it[ind].b, 1 );
    modd ( it[ind*2].b );

    it[ind*2+1].a += getFib( it[ind].a, it[ind].b, s/2 );
    modd ( it[ind*2+1].a );
    it[ind*2+1].b += getFib( it[ind].a, it[ind].b, s/2+1 );
    modd ( it[ind*2+1].b );

    it[ind].a = 0;
    it[ind].b = 0;
}
int stL;
void add ( int s, int f, int ss, int ff, int ind ) {
    handle( ind, f-s );
    if ( f <= ss || ff <= s ) { return ; }
    if ( ss <= s && f <= ff ) {
        it[ind].a += getFib( 1, 1, s-stL );
        modd ( it[ind].a );
        it[ind].b += getFib( 1, 1, s-stL+1 );
        modd ( it[ind].b );
        handle( ind, f-s );
        return;
    }
    add( s, (s+f)/2, ss, ff, ind*2 );
    add( (s+f)/2, f, ss, ff, ind*2+1 );
    it[ind].val = (it[ind*2].val + it[ind*2+1].val)%mod;
    modd ( it[ind].val );
    return ;
}

long long sum ( int s, int f, int ss, int  ff, int ind ) {
    handle( ind, f-s );
    if ( f <= ss || ff <= s ) { return 0; }
    if ( ss <= s && f <= ff ) { return it[ind].val; }
    return ( sum ( s, (s+f)/2, ss, ff, ind*2 )+sum( (s+f)/2, f, ss, ff, ind*2+1 ) )%mod;
}

int main () {
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    prePows () ;

    cin >> n >> m;
    for ( int  i = 0 ; i < n ; i ++ ) {
        cin >> it[i+(1<<k)].val;
    }
    for ( int  i = (1<<k)-1 ; i ; i-- ) {
        it[i].val = it[i*2].val + it[i*2+1].val;
        it[i].val %= mod;
    }
    for ( int i = 0 ; i < m ; i ++ ) {
        int t, l ,r;
        cin >> t >> l >> r;
        l --;
        if ( t == 1 ) {
            stL = l;
            add ( 0, (1<<k), l, r, 1 );
        }else {
            cout << sum ( 0, (1<<k), l, r, 1 ) << "\n";
        }
    }
    return 0;
}
/*

a b     a+b   a+2b     2a+3b  3a+5b   5a+8b
a a+b  2a+b   3a+3b    5a+6b  8a+11b 13a+19b

0 1   1     2    3      5     8     13     21     55
0 1   2     4    7     12    20     33     54

3    4     7    11    18     29
3    7     14   25

*/


#include <iostream>
using namespace std;
struct mat {
    int a, b, c;
    mat () {}
    mat ( int a_, int b_, int c_ ) { a = a_; b = b_; c = c_; }
};
struct v {
    int val;
    int a, b;
    v () { a = 0, b = 0, val = 0; }
}it[10000042];
long long   mod = 1000000009;

void modd ( long long &a ) {
    if ( a < 0 ) { a += mod; }
    if ( a >= mod ) { a -= mod; }
    if ( a >= mod ) { a %= mod; }
}
void modd ( int &a ) {
    if ( a < 0 ) { a += mod; }
    if ( a >= mod ) { a -= mod; }
    if ( a >= mod ) { a %= mod; }
}
mat mult ( mat a, mat b ) {
    mat ans;
    ans.a = (1LL*a.a*b.a + 1LL*a.b*b.b)%mod;
    ans.b =  (1LL*a.a*b.b + 1LL*a.b*b.c)%mod;
    ans.c = (1LL*a.b*b.b + 1LL*a.c*b.c)%mod;
    return ans;
}
mat pows[32];
int getFib( int a, int b, int n ) {
    if ( n == -1 ) { return 0; }
    mat crr ( a, b, a+b );
    for ( int i = 0 ; i < 32 ; i ++ ) {
        if ( n&(1<<i) ) {
            crr = mult( crr, pows[i] );
        }
        if ( (1<<i) >= n ) { return crr.a; }
    }
    return crr.a;
}
void prePows ( ) {
    pows[0] = mat ( 0, 1, 1 );
    for ( int i = 1 ; i < 32 ; i ++ ) {
        pows[i] = mult( pows[i-1], pows[i-1] );
    }
}
int n, m, k = 19;
void handle (int ind, int s ) {
    if ( it[ind].a == 0 && it[ind].b == 0 ) { return; }
    if ( ind >= (1<<k) ) {
        it[ind].val += it[ind].a;
        modd( it[ind].val );
        it[ind].a = 0; it[ind].b = 0;
    }

    it[ind].val += (1LL*getFib( it[ind].a, it[ind].b, s+1 ) - 1LL*it[ind].b );
    modd( it[ind].val );

    it [ind*2].a += it[ind].a;
    modd ( it[ind*2].a );
    it [ind*2].b += it[ind].b;
    modd ( it[ind*2].b );

    it[ind*2+1].a += getFib( it[ind].a, it[ind].b, s/2 );
    modd ( it[ind*2+1].a );
    it[ind*2+1].b += getFib( it[ind].a, it[ind].b, s/2+1 );
    modd ( it[ind*2+1].b );

    it[ind].a = 0;
    it[ind].b = 0;
}
int stL;
void add ( int s, int f, int ss, int ff, int ind ) {
    handle( ind, f-s );
    if ( f <= ss || ff <= s ) { return ; }
    if ( ss <= s && f <= ff ) {
        it[ind].a += getFib( 1, 1, s-stL );
        it[ind].b += getFib( 1, 1, s-stL+1 );
        handle( ind, f-s );
        return;
    }
    add( s, (s+f)/2, ss, ff, ind*2 );
    add( (s+f)/2, f, ss, ff, ind*2+1 );
    it[ind].val = (it[ind*2].val + it[ind*2+1].val);
    modd ( it[ind].val );
    return ;
}

int sum ( int s, int f, int ss, int  ff, int ind ) {
    handle( ind, f-s );
    if ( f <= ss || ff <= s ) { return 0; }
    if ( ss <= s && f <= ff ) { return it[ind].val; }
    return ( sum ( s, (s+f)/2, ss, ff, ind*2 )+sum( (s+f)/2, f, ss, ff, ind*2+1 ) )%mod;
}

int main () {
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    prePows () ;

    cin >> n >> m;
    for ( int  i = 0 ; i < n ; i ++ ) {
        cin >> it[i+(1<<k)].val;
    }
    for ( int  i = (1<<k)-1 ; i ; i-- ) {
        it[i].val = it[i*2].val + it[i*2+1].val;
        modd( it[i].val );
    }
    for ( int i = 0 ; i < m ; i ++ ) {
        int t, l ,r;
        cin >> t >> l >> r;
        l --;
        if ( t == 1 ) {
            stL = l;
            add ( 0, (1<<k), l, r, 1 );
        }else {
            cout << sum ( 0, (1<<k), l, r, 1 ) << "\n";
        }
    }
    return 0;
}
/*

a b     a+b   a+2b     2a+3b  3a+5b   5a+8b
a a+b  2a+b   3a+3b    5a+6b  8a+11b 13a+19b

0 1   1     2    3      5     8     13     21     55
0 1   2     4    7     12    20     33     54

3    4     7    11    18     29
3    7     14   25

*/


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
template<typename T>void read(T &x){
	x=0;int f(1);char c(getchar());
	for(;!isdigit(c);c=getchar())if(c=='-')f=-f;
	for(; isdigit(c);c=getchar())x=(x<<3)+(x<<1)+(c-'0');
	x*=f;
}
template<typename T>void write(T x){
	if(x<0)putchar('-'),x=-x;
	if(x/10)write(x/10),x%=10;
	putchar(x+'0');
}
const int maxn=300005,saxn=3000005,mod=1000000009;
int map[maxn][3][3];
int mo(int x){
	return x>=mod?x-mod:x;
}
int la1[saxn],la2[saxn],tr[saxn],len[saxn];
void push(int x,int _1,int _2){
	if(len[x]==1)tr[x]=mo(tr[x]+_1);
	else{
		int pos=len[x]-2;
		tr[x]=mo(tr[x]+1ll*_1*mo(map[pos][0][2]+map[pos][2][2])%mod);
		tr[x]=mo(tr[x]+1ll*_2*mo(map[pos][1][2]+map[pos][2][2])%mod);
	}
	la1[x]=mo(la1[x]+_1);
	la2[x]=mo(la2[x]+_2);
}
void pushup(int x){
	tr[x]=mo(tr[x<<1]+tr[x<<1|1]);
}
int t1,t2;
void getr(int _1,int _2,int pos){
	t1=mo(1ll*_1*map[pos][0][0]%mod+1ll*_2*map[pos][1][0]%mod),
	t2=mo(1ll*_1*map[pos][0][1]%mod+1ll*_2*map[pos][1][1]%mod);
}
void pushdown(int x){
	if(!la1[x]&&!la2[x])return;
	push(x<<1,la1[x],la2[x]);
	getr(la1[x],la2[x],len[x<<1]);
	push(x<<1|1,t1,t2);
	la1[x]=la2[x]=0;
}
void build(int x,int l,int r){
	len[x]=r-l+1;
	if(l==r){
		read(tr[x]);
		return;
	}
	int mid=(l+r)>>1;
	build(x<<1,l,mid);
	build(x<<1|1,mid+1,r);
	pushup(x);
}
void change(int x,int l,int r,int L,int R,int _1,int _2){
	if(L<=l&&r<=R)return push(x,_1,_2);
	int mid=(l+r)>>1;pushdown(x);
	if(L<=mid)change(x<<1,l,mid,L,R,_1,_2);
	if(R>mid)getr(_1,_2,max(0,mid+1-L)),change(x<<1|1,mid+1,r,max(L,mid+1),R,t1,t2);
	return pushup(x);
}
int query(int x,int l,int r,int L,int R){
	if(L<=l&&r<=R)return tr[x];
	int mid=(l+r)>>1,re=0;pushdown(x);
	if(L<=mid)re=mo(re+query(x<<1,l,mid,L,R));
	if(R>mid)re=mo(re+query(x<<1|1,mid+1,r,L,R));
	return re;
}
int main(){
	int n,m;
	read(n),read(m);
	for(int i=0;i<3;++i)
		map[0][i][i]=map[1][i][i]=1;
	map[1][0][0]=0;
	map[1][0][1]=map[1][0][2]=1;
	map[1][1][0]=map[1][1][2]=1;
	for(int i=2;i<=n;++i)
		for(int j=0;j<3;++j)
			for(int k=0;k<3;++k)
				for(int l=0;l<3;++l)
					map[i][j][k]=mo(map[i][j][k]+map[i-1][j][l]*map[1][l][k]);
	build(1,1,n);
	while(m--){
		int op,l,r;
		read(op),read(l),read(r);
		if(op==1)
			change(1,1,n,l,r,1,1);
		if(op==2)
			write(query(1,1,n,l,r)),putchar('\n');
	}
	return 0;
}


#include<cstdio>
using namespace std;
const int maxn=500050,mod=1e9+9;
#define ls(x) x<<1
#define rs(x) x<<1|1
int n,m,a[maxn],fib[maxn],rfib[maxn],pre[maxn],sum[maxn<<2],add1[maxn<<2],add2[maxn<<2];
void pushup(int x){sum[x]=(sum[ls(x)]+sum[rs(x)])%mod;}
void build(int x,int l,int r)
{
    if(l==r)
    {
        sum[x]=a[l]%mod;
        return;
    }
    int mid=l+r>>1;
    build(ls(x),l,mid);
    build(rs(x),mid+1,r);
    pushup(x);
}
void modify(int x,int ad1,int ad2,int l,int r)
{
	add1[x]=(add1[x]+ad1)%mod;
    add2[x]=(add2[x]+ad2)%mod;
    sum[x]=(sum[x]+1ll*(pre[r+1]-pre[l]+mod)%mod*ad1%mod)%mod;
    sum[x]=(sum[x]+1ll*(pre[r]-pre[l-1]+mod)%mod*ad2%mod)%mod;
}
void pushdown(int x,int l,int r)
{
    if(!add1[x]&&!add2[x]) return;
    int mid=l+r>>1;
    modify(ls(x),add1[x],add2[x],l,mid);
    modify(rs(x),add1[x],add2[x],mid+1,r);
    add1[x]=add2[x]=0;
}
void update(int k,int l,int r,int x,int y,int ad1,int ad2)
{
    if(l>=x&&r<=y)
    {
    	modify(k,ad1,ad2,l,r);
    	return;
	}
    pushdown(k,l,r);
    int mid=l+r>>1;
    if(mid>=x)update(ls(k),l,mid,x,y,ad1,ad2);
    if(y>mid)update(rs(k),mid+1,r,x,y,ad1,ad2);
    pushup(k);
}
int query(int k,int l,int r,int x,int y)
{
    if(l>=x&&r<=y)return sum[k];
    pushdown(k,l,r);
    int mid=l+r>>1,ans=0;
    if(mid>=x)ans=(ans+query(ls(k),l,mid,x,y))%mod;
    if(y>mid)ans=(ans+query(rs(k),mid+1,r,x,y))%mod;
    return ans;
}
int main()
{
    int op,l,r,i;
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;++i)scanf("%d",&a[i]);
    fib[1]=fib[2]=1;
    pre[1]=1;pre[2]=2;
    rfib[0]=0;rfib[1]=1;rfib[2]=mod-1;
    for(i=3;i<=n+1;++i)
    {
        fib[i]=(fib[i-1]+fib[i-2])%mod;
        pre[i]=(pre[i-1]+fib[i])%mod;
        if(i&1)rfib[i]=fib[i];
        else rfib[i]=mod-fib[i];
        rfib[i]=(i&1)?fib[i]:mod-fib[i];
    }
    build(1,1,n);
    for(i=1;i<=m;++i)
    {
        scanf("%d%d%d",&op,&l,&r);
        if(op==1)update(1,1,n,l,r,rfib[l-1],rfib[l]);
        else printf("%d\n",query(1,1,n,l,r));
    }
    return 0;
}


/*
--------------------------
给区间加上斐波那契数列.
性质1. ∑fib(i)=fib(n+2)-fib(2)
       即对于S(i)=S(i-2)+S(i-1),∑S(i)=S(n+2)-S(2).
	   (∑范围是[1,n])
性质2. 若S(i)=S(i-2)+S(i-1),有S(i)=S(1)*fib(i-2)+S(2)*fib(i-1).
可以利用性质,已知S1,S2,len,求出这一段的总和.
用线段树维护,pushdown的时候注意分类讨论,给左边右边加上相应的权值.
--------------------------
调试技巧:
1.如果参考标程可以把相应的变量输出.
2.#define int long long.
3.检查数组越界.
--------------------------2019.1.24
*/
#include<bits/stdc++.h>
#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)<(y)?(x):(y))
#define int long long
using namespace std;
typedef long long LL;
const int INF=1e9+7;
inline LL read(){
	register LL x=0,f=1;register char c=getchar();
	while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
	while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
	return f*x;
}

const int MAXN=3e5+5;
const int mod=1e9+9;

int fib[MAXN];
int n,m;

namespace SGT{
	int sum[MAXN<<2],num[MAXN<<2][2];
	bool tag[MAXN<<2];
#define ls (rt<<1)
#define rs (rt<<1|1)
	inline int delta(int a,int b,int len){
		LL res=0;
		if(len>=1) res+=a;
		if(len>=2) res+=b;
		if(len>=3) res+=(LL)a*(fib[len]-1)+b*(fib[len+1]-2);
		return res%mod;
	}
	inline void pushup(int rt){
		sum[rt]=(sum[ls]+sum[rs])%mod;
	}
	inline void pushdown(int rt,int l,int r,int mid){
		if(tag[rt]){
			//num[ls][0]=num[rt][0],num[ls][1]=num[rt][1];
			int a=num[rt][0],b=num[rt][1];
			printf("%d %d\n",num[rt][0],num[rt][1]);
			(num[ls][0]+=a)%=mod;
			(num[ls][1]+=b)%=mod;
			(sum[ls]+=delta(a,b,mid-l+1))%=mod;
			tag[ls]=1;
			int len=mid-l;
			int c=(a*fib[len]%mod+b*fib[len+1]%mod)%mod,d=(a*fib[len+1]%mod+b*fib[len+2]%mod)%mod;//
			(num[rs][0]+=c)%=mod;
			(num[rs][1]+=d)%=mod;
			//num[2][0]-=dd256;
			(sum[rs]+=delta(c,d,r-mid))%=mod;
			tag[rs]=1;
			num[rt][0]=num[rt][1]=0;//
			tag[rt]=0;
//			printf("%d %d %d %d %d %d %d \n",num[rt][0],num[rt][1],sum[rt],num[ls][0],num[ls][1],num[rs][0],num[rs][1]);
//			printf("%d %d %d %d\n",a,b,c,d);
		}
	}
	inline void build(int rt,int l,int r){
		if(l==r){
			sum[rt]=read()%mod;
			return;
		}
		int mid=(l+r)>>1;
		build(ls,l,mid);
		build(rs,mid+1,r);
		pushup(rt);
	}
	inline void modify(int rt,int l,int r,int x,int y,int s1,int s2){
//		printf("%d %d %d %d %d %d %d\n",rt,l,r,x,y,s1,s2);
		if(l>=x&&r<=y){
			(num[rt][0]+=s1)%=mod,(num[rt][1]=+s2)%=mod;
			(sum[rt]+=delta(s1,s2,r-l+1))%=mod;
			tag[rt]=1;
			return;
		}
		int mid=(l+r)>>1;
		pushdown(rt,l,r,mid);
		if(y<=mid) modify(ls,l,mid,x,y,s1,s2);
		else if(x>=mid+1) modify(rs,mid+1,r,x,y,s1,s2);
		else{
			modify(ls,l,mid,x,mid,s1,s2);//
			int len=mid-x;//
			int c=(s1*fib[len]+s2*fib[len+1])%mod,d=(s1*fib[len+1]+s2*fib[len+2])%mod;
			modify(rs,mid+1,r,mid+1,y,c,d);
		}
		pushup(rt);
	}
	inline int query(int rt,int l,int r,int x,int y){
//		printf("%d %d %d %d %d %d\n",rt,l,r,x,y,sum[rt]);
		if(l>=x&&r<=y) return sum[rt];
		int mid=(l+r)>>1;
		pushdown(rt,l,r,mid);
		int res=0;
		if(x<=mid) res+=query(ls,l,mid,x,y);
		if(mid<y) res+=query(rs,mid+1,r,x,y);
		return res%mod;
	}
#undef ls
#undef rs
}

signed main(){
#ifdef flie
	freopen("you.in","r",stdin);
	freopen("you.out","w",stdout);
#endif
	n=read(),m=read();
	SGT::build(1,1,n);
	fib[1]=fib[2]=1;
	for(int i=3;i<MAXN;i++)
		fib[i]=(fib[i-1]+fib[i-2])%mod;
	for(int i=1;i<=m;i++){
		int op=read(),x=read(),y=read();
		if(op==1) SGT::modify(1,1,n,x,y,1,1);
		if(op==2) printf("%d\n",SGT::query(1,1,n,x,y));
	}
}


#include<iostream>
#include<cstring>
#include<cstdio>
#define int long long
using namespace std;
const int mod=1e9+9;
const int N=300005;
inline int read()
{
    register int x=0,y=1;register char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')y=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return x*y;
}
struct node
{
	int f1;
	int f2;
	int sum;
}tr[N<<2];
int a[N],sum[N];
int f[N<<1];
int n,m;
void init()
{
	f[1]=1;f[2]=1;
	for(int i=3;i<=(N<<1)-1;i++) f[i]=(f[i-1]+f[i-2])%mod;
}
void up(int k,int len)
{tr[k].f1%=mod,tr[k].f2%=mod,tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum+(tr[k].f1*f[len]%mod+tr[k].f2*f[len+1]%mod-tr[k].f2)%mod;}
void down(int k,int l,int r)
{
	if(tr[k].f1==0&&tr[k].f2==0) return;
	int mid=(l+r)>>1;
	tr[k<<1].f1+=tr[k].f1;
	tr[k<<1].f1%=mod;
	tr[k<<1].f2+=tr[k].f2;
	tr[k<<1].f2%=mod;
	tr[k<<1|1].f1+=tr[k].f1*f[mid-l]%mod+tr[k].f2*f[mid-l+1]%mod;
	tr[k<<1|1].f1%=mod;
	tr[k<<1|1].f2+=tr[k].f1*f[mid-l+1]%mod+tr[k].f2*f[mid-l+2]%mod;
	tr[k<<1|1].f2%=mod;
	tr[k].f1=0;tr[k].f2=0;
	up(k<<1,mid-l+1);up(k<<1|1,r-mid);
}
void change(int k,int l,int r,int ql,int qr)
{
	if(ql<=l&&r<=qr)
	{
		tr[k].f1+=f[l-ql+1];
		tr[k].f2+=f[l-ql+2];
		tr[k].f1%=mod;
		tr[k].f2%=mod;
		up(k,r-l+1);
		return;
	}
	down(k,l,r);
	int mid=(l+r)>>1;
	if(ql<=mid) change(k<<1,l,mid,ql,qr);
	if(mid<qr) change(k<<1|1,mid+1,r,ql,qr);
	up(k,r-l+1);
}
int query(int k,int l,int r,int ql,int qr)
{
	if(l>=ql&&r<=qr) return tr[k].sum;
	down(k,l,r);
	int mid=(l+r)>>1;
	int res=0;
	if(ql<=mid) res+=query(k<<1,l,mid,ql,qr);
	if(mid<qr) res+=query(k<<1|1,mid+1,r,ql,qr);
	return res;
}
signed main()
{
	n=read();m=read();
	init();
	for(int i=1;i<=n;i++) a[i]=read();
	for(int i=1;i<=n;i++) sum[i]=(sum[i-1]+a[i])%mod;
	for(int i=1;i<=m;i++)
    {
        int opt,l,r;
       opt=read();l=read();r=read();
        if(opt==1)change(1,1,n,l,r);
        else printf("%lld\n",(query(1,1,n,l,r)+sum[r]-sum[l-1]+mod)%mod);
    }
}


#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define ls p<<1
#define rs p<<1|1
using namespace std;
typedef long long ll;
const ll mxn=1e6+5,mod=1e9+9;
ll n,m,cnt,a[mxn],hd[mxn];
ll f[mxn],tr[mxn<<2],vis[mxn<<2],tag[mxn<<2][2];

inline ll read() {
	char c=getchar(); ll x=0,f=1;
	while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
	while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();}
	return x*f;
}
inline void chkmax(ll &x,ll y) {if(x<y) x=y;}
inline void chkmin(ll &x,ll y) {if(x>y) x=y;}

struct ed {
	ll to,nxt;
}t[mxn<<1];

inline void add(ll u,ll v) {
	t[++cnt]=(ed) {v,hd[u]}; hd[u]=cnt;
}

void push_up(ll p) {
	tr[p]=(tr[ls]+tr[rs])%mod;
}

struct ST {
	ll x,y;
};

ST fibget(ST tp,ll len) {
	ll c=tp.x*f[len]%mod+tp.y*f[len+1]%mod,d=tp.x*f[len+1]%mod+tp.y*f[len+2]%mod;
	return (ST) {c%mod,d%mod};
}

ll fibcal(ll f1,ll f2,ll len) {
	ll res=0;
	if(len>=1) res=f1;
	if(len>=2) res=(res+f2)%mod;
	if(len>=3) res=(res+f2*(f[len+1]-2)%mod+f1*(f[len]-1)%mod+mod)%mod;
	//前两项的系数的值,直接乘以当前f[i+1],f[i],计算出f[i+2]
	return res;
}

void push_down(ll p,ll l,ll r) {
	ll mid=(l+r)>>1;
	if(vis[p]) {
		ll &a=tag[p][0],&b=tag[p][1];
		tag[ls][0]=(tag[ls][0]+a)%mod;
		tag[ls][1]=(tag[ls][1]+b)%mod;
		tr[ls]=(tr[ls]+fibcal(a,b,mid-l+1))%mod;
		vis[ls]=1;

		ll c=a*f[mid-l]+b*f[mid-l+1],d=a*f[mid-l+1]+b*f[mid-l+2];
		c%=mod; d%=mod;
		tag[rs][0]=(tag[rs][0]+c)%mod;
		tag[rs][1]=(tag[rs][1]+d)%mod;
		tr[rs]=(tr[rs]+fibcal(c,d,r-mid))%mod;
		vis[rs]=1;

		vis[p]=tag[p][0]=tag[p][1]=0;
	}
}

void build(ll l,ll r,ll p) {
	if(l==r) {tr[p]=a[l]; return ;}
	ll mid=(l+r)>>1;
	build(l,mid,ls); build(mid+1,r,rs); push_up(p);
}

void modify(ll l,ll r,ll ql,ll qr,ll val1,ll val2,ll p) {
	if(ql<=l&&r<=qr) {
		tag[p][0]=(tag[p][0]+val1)%mod;
		tag[p][1]=(tag[p][1]+val2)%mod;
		tr[p]=(tr[p]+fibcal(val1,val2,r-l+1))%mod;
		vis[p]=1; return ;
	}
	ll mid=(l+r)>>1; push_down(p,l,r);
	if(qr<=mid) modify(l,mid,ql,qr,val1,val2,ls);
	else if(ql>mid) modify(mid+1,r,ql,qr,val1,val2,rs);
	else {
		modify(l,mid,ql,qr,val1,val2,ls);
		ST z=fibget((ST){val1,val2},mid-ql);
		modify(mid+1,r,mid+1,qr,z.x,z.y,rs); //算出区间前两个fib,貌似也可以用前缀和
	}
	push_up(p);
}

ll query(ll l,ll r,ll ql,ll qr,ll p) {
	if(ql<=l&&r<=qr) return tr[p];
	ll mid=(l+r)>>1; push_down(p,l,r); ll res=0;
	if(ql<=mid) res=(res+query(l,mid,ql,qr,ls))%mod;
	if(qr>mid) res=(res+query(mid+1,r,ql,qr,rs))%mod;
	return res;
}

void init() {
	n=read(); m=read(); ll x,y,opt; f[1]=f[2]=1;
	for(ll i=3;i<=n+4;++i) f[i]=(f[i-1]+f[i-2])%mod;
	for(ll i=1;i<=n;++i) a[i]=read()%mod; build(1,n,1);
	for(ll i=1;i<=m;++i) {
		opt=read(); x=read(); y=read();
		if(opt==1) modify(1,n,x,y,1,1,1);
		else printf("%lld\n",(query(1,n,x,y,1)+mod)%mod);
	}
}

int main()
{
	init();
    return 0;
}


#include<bits/stdc++.h>
#define REP(i,first,last) for(int i=first;i<=last;++i)
#define DOW(i,first,last) for(int i=first;i>=last;--i)
using namespace std;
const int maxN=3e5+7;
const int mod=1e9+9;
int N,M;
int arr[maxN];
long long sum[maxN];
int Mod(long long a)
{
	a%=mod;
	a+=mod;
	a%=mod;
	return a;
}
int f[maxN];
int CalcNext(int fir,int sec,int len)
{
	if(len==1)
	{
		return fir;
	}
	if(len==2)
	{
		return sec;
	}
	return Mod(1ll*fir*f[len-2]+1ll*sec*f[len-1]);
}
int CalcSum(int fir,int sec,int len)
{
	if(len==1)
	{
		return fir;
	}
	if(len==2)
	{
		return Mod(fir+sec);
	}
	return Mod(CalcNext(fir,sec,len+2)-sec);
}
struct Tree
{
	int sum;
	int first,second;
}tree[maxN*4];
#define LSON (now<<1)
#define RSON (now<<1|1)
#define MIDDLE ((left+right)>>1)
#define LEFT LSON,left,MIDDLE
#define RIGHT RSON,MIDDLE+1,right
#define NOW now_left,now_right
void PushUp(int now)
{
	tree[now].sum=Mod(tree[LSON].sum+tree[RSON].sum);
}
void Build(int now=1,int left=1,int right=N)
{
	if(left==right)
	{
		tree[now].sum=arr[left];
		return;
	}
	Build(LEFT);
	Build(RIGHT);
	PushUp(now);
}
#define LEN (right-left+1)
void Down(int now,int left,int right,int add_first,int add_second)
{
	tree[now].first=Mod(tree[now].first+add_first);
	tree[now].second=Mod(tree[now].second+add_second);
	tree[now].sum=Mod(tree[now].sum+CalcSum(add_first,add_second,LEN));
}
#undef LEN
#define TWO tree[now].first,tree[now].second
#define LEN (MIDDLE-left+1)
void PushDown(int now,int left,int right)
{
	Down(LEFT,TWO);
	Down(RIGHT,CalcNext(TWO,LEN+1),CalcNext(TWO,LEN+2));
	tree[now].first=tree[now].second=0;
}
#undef TWO
#undef LEN
#define LEN (left-now_left+1)
void Updata(int now_left,int now_right,int now=1,int left=1,int right=N)
{
	if(right<now_left||now_right<left)
	{
		return;
	}
	if(now_left<=left&&right<=now_right)
	{
		Down(now,left,right,f[LEN],f[LEN+1]);
		return;
	}
	PushDown(now,left,right);
	Updata(NOW,LEFT);
	Updata(NOW,RIGHT);
	PushUp(now);
}
int Query(int now_left,int now_right,int now=1,int left=1,int right=N)
{
	if(right<now_left||now_right<left)
	{
		return 0;
	}
	if(now_left<=left&&right<=now_right)
	{
		return tree[now].sum;
	}
	PushDown(now,left,right);
	int result=Mod(Query(NOW,LEFT)+Query(NOW,RIGHT));
	PushUp(now);
	return result;
}
int main()
{
	freopen("data.in","r",stdin);
	freopen("data.out","w",stdout);
	scanf("%d%d",&N,&M);
	REP(i,1,N)
	{
		scanf("%d",&arr[i]);
	}
	Build();
	f[1]=f[2]=1;
	REP(i,3,N+2)
	{
		f[i]=Mod(f[i-1]+f[i-2]);
	}
	int op,left,right;
	REP(i,1,M)
	{
		scanf("%d%d%d",&op,&left,&right);
		if(op==1)
		{
			Updata(left,right);
		}
		if(op==2)
		{
			printf("%d\n",Query(left,right));
		}
	}
	return 0;
}


#include<bits/stdc++.h>
#define int long long
using namespace std;
int read(){
	int c=0,nx,sign=1;
	do{
		nx=getchar()-'0';
		if(nx=='-'-'0')
			sign=-1;
	}while(nx<0 or nx>9);
	while(nx>=0 and nx<=9){
		c=c*10+nx;
		nx=getchar()-'0';
	}
	return sign*c;
}
const int N=5e5+10,mod=1e9+9;
int fib[2*N],a[N];
struct stree{
	int tot,a,b;
	stree *ls,*rs;
}c[4*N];
stree* New(){
	static int now=0;
	stree &s=c[++now];
	s.tot=s.a=s.b=0;
	s.ls=s.rs=c;
	return c+now;
}
inline int h(int a,int b,int x){
	if(x>=2)
		return (a*fib[x-2] + b*fib[x-1]) % mod;
	else
		return a;
}
inline void pd(stree &s,int a,int b,int l,int r){
	s.a = (s.a + a) % mod;
	s.b = (s.b + b) % mod;
	s.tot = (s.tot + h(a,b,r-l+3) - b + mod) % mod;
}
void pushdown(stree &s,int l,int r){
	if(!s.a and !s.b or l==r)
		return ;
	int mid=(l+r)>>1;
	int &a=s.a,&b=s.b;
	pd(*s.ls,a,b,l,mid);
	pd(*s.rs,h(a,b,mid+2-l),h(a,b,mid+3-l),mid+1,r);
	a=b=0;
}
inline void pushup(stree &s){
	s.tot = (s.ls->tot + s.rs->tot) % mod;
}
void add(int ql,int qr,stree &s,int l,int r){
	if(ql<=l and r<=qr){
		pd(s,fib[l-ql+1],fib[l-ql+2],l,r);
		return ;
	}
	pushdown(s,l,r);
	int mid=(l+r)>>1;
	if(ql<=mid)
		add(ql,qr,*s.ls,l,mid);
	if(qr>mid)
		add(ql,qr,*s.rs,mid+1,r);
	pushup(s);
}
int query(int ql,int qr,stree &s,int l,int r){
	if(ql<=l and r<=qr){
		return s.tot;
	}
	pushdown(s,l,r);
	int mid=(l+r)>>1,ans=0;
	if(ql<=mid)
		ans+=query(ql,qr,*s.ls,l,mid);
	if(qr>mid)
		ans+=query(ql,qr,*s.rs,mid+1,r);
	return ans % mod;
}
void build(stree &s,int l,int r){
	if(l==r){
		s.tot=a[l];
		return ;
	}
	s.ls = New();
	s.rs = New();
	int mid = (l + r) >> 1;
	build(*s.ls,l,mid);
	build(*s.rs,mid+1,r);
	pushup(s);
}

signed main(){
	fib[1]=1;
	for(int i=2;i<=1e6;i++)
		fib[i]=(fib[i-1] + fib[i-2]) % mod;

	int n=read(),t=read();
	for(int i=1;i<=n;i++)
		a[i]=read();

	stree &root=*New();
	build(root,1,n);

	while(t--){
		int ord=read(),l=read(),r=read();
		switch(ord){
			case 1:
				add(l,r,root,1,n);
				break;
			case 2:
				printf("%lld\n",query(l,r,root,1,n));
				break;
		}
	}
}


#define<bits/stdc++.h>
#define int long long
#pragma GCC optimize(3)
using namespace std;
const int mod=1e9+9;
int n,m,fib[300010]={0,1},fibs[300010]={0,1},a[300010],sum[2400010],add[2400010][2];
int cal(int l,int r){
    return (fibs[r]-fibs[l-1]+mod)%mod;
}
void build(int k,int l,int r){
    if(l==r){
        sum[k]=a[l];
        return;
    }
    int mid=(l+r)/2;
    build(2*k,l,mid);
    build(2*k+1,mid+1,r);
    sum[k]=(sum[2*k]+sum[2*k+1])%mod;
}
void push_down(int k,int l,int r){
    if(!add[k][0]||l==r) return;
    int mid=(l+r)/2;
//  printf("%lld %lld %lld\n",k,add[k][0],add[k][1]);
    sum[2*k]=(sum[2*k]+cal(add[k][0],add[k][0]+mid-l))%mod;
    add[2*k][0]=add[k][0];
    add[2*k][1]=add[k][0]+mid-l;
//  printf("%lld %lld %lld\n",2*k,add[2*k][0],add[2*k][1]);
    sum[2*k+1]=(sum[2*k+1]+cal(add[k][0]+mid-l+1,add[k][1]))%mod;
    add[2*k+1][0]=add[k][0]+mid-l+1;
    add[2*k+1][1]=add[k][1];
    add[k][0]=add[k][1]=0;
}
int query(int k,int l,int r,int x,int y){
    push_down(k,l,r);
    if(x<=l&&r<=y) return sum[k];
    int mid=(l+r)/2,res=0;
    if(x<=mid) res=(res+query(k*2,l,mid,x,y))%mod;
    if(mid<y) res=(res+query(k*2+1,mid+1,r,x,y))%mod;
    return res;
}
void modify(int k,int l,int r,int x,int y){
    push_down(k,l,r);
    if(x<=l&&r<=y){
        add[k][0]=l-x+1;
        add[k][1]=r-x+1;
        sum[k]=(sum[k]+cal(add[k][0],add[k][1]));
//      printf("%lld\n",k);
        return;
    }
    int mid=(l+r)/2;
    if(x<=mid) modify(2*k,l,mid,x,y);
    if(mid<y) modify(2*k+1,mid+1,r,x,y);
    sum[k]=(sum[2*k]+sum[2*k+1])%mod;
}
signed main(){
    scanf("%lld %lld",&n,&m);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    for(int i=2;i<=300000;i++) fib[i]=(fib[i-1]+fib[i-2])%mod,fibs[i]=(fibs[i-1]+fib[i])%mod;
    build(1,1,n);
    int x,y,z;
    for(int i=1;i<=m;i++){
        scanf("%lld %lld %lld",&x,&y,&z);
        if(x==1){
            modify(1,1,n,y,z);
//            int k;
//            srand(rand());
//            for(int j=1;j<=100;j++) k=rand()%n+1,query(1,1,n,k,k);
        }
        else printf("%lld\n",query(1,1,n,y,z));
    }
    return 0;
}


#include<cstdio>
#include<iostream>
#define int long long
using namespace std;
const int mod = 1e9 + 7;
const int N = 300005;
int n,m;
long long f[N << 1],a[N],sum[N];
struct node{
	long long f1,f2,v;
	node(long long f1 = 0,long long f2 = 0,long long v = 0):f1(f1),f2(f2),v(v){};
}tr[N << 4];
void init()
{
	f[0] = 0;f[1] = 1;
	for(int i = 2;i <= 200000;i ++)	f[i] = (f[i - 1] + f[i - 2]) % mod;
}
void update(int k,int len)
{
	tr[k].f1 %= mod;	tr[k].f2 %= mod;
	tr[k].v = (((tr[k << 1].v + tr[k << 1 | 1].v) % mod + tr[k].f1 * f[len] % mod + tr[k].f2 * f[len + 1] % mod - tr[k].f2) % mod + mod) % mod;
//	cout << tr[k << 1].v << " " << tr[k << 1 | 1].v << endl;
}/*
void down(int k,int l,int r)
{
	cout << k << endl;
	if(tr[k].f1 == 0 && tr[k].f2 == 0)	return;
	int mid = (l + r) >> 1;
	tr[k << 1].f1 += tr[k].f1;	tr[k << 1].f2 += tr[k].f2;
	tr[k << 1 | 1].f1 += (tr[k].f1 * f[mid - l] % mod + tr[k].f2 * f[mid - l + 1] % mod) % mod;
	tr[k << 1 | 1].f2 += (tr[k].f1 * f[mid - l + 1] % mod + tr[k].f2 * f[mid - l + 2] % mod) % mod;
	tr[k].f1 = tr[k].f2 = 0;
//	cout << tr[k].f2 << " " << tr[k << 1 | 1].f2 << endl;
	update(k << 1,mid - l + 1);	update(k << 1 | 1,r - mid);
}*/
void down(int rt,int l,int r)
{
    if(tr[rt].f1==0&&tr[rt].f2==0)return ;
    int mid=(l+r)>>1;	int ls = (rt << 1),rs = (rt << 1 | 1);
    tr[ls].f1+=tr[rt].f1,tr[rs].f1+=tr[rt].f1*f[mid-l]+tr[rt].f2*f[mid-l+1];
    tr[ls].f2+=tr[rt].f2,tr[rs].f2+=tr[rt].f1*f[mid-l+1]+tr[rt].f2*f[mid-l+2];
    tr[rt].f1=tr[rt].f2=0;
//    cout << t[ls].f2 << " " << t[rs].f2 << endl;
    update(ls,mid-l+1),update(rs,r-mid);
}
long long ask(int k,int l,int r,int x,int y)
{
	if(x <= l && r <= y)	return tr[k].v %= mod;
	down(k,l,r);
	int mid = (l + r) >> 1;
	long long ans = 0;
	if(x <= mid)	ans = (ans + ask(k << 1,l,mid,x,y)) % mod;
	if(y > mid)		ans = (ans + ask(k << 1 | 1,mid + 1,r,x,y)) % mod;
	return ans;
}
void change(int k,int l,int r,int x,int y,int em)
{
	if(x <= l && r <= y)
	{
		tr[k].f1 = (tr[k].f1 + f[em + l - x + 1]) % mod;
		tr[k].f2 = (tr[k].f2 + f[em + l - x + 2]) % mod;
		update(k,r - l + 1);
		return;
	}
	down(k,l,r);
	int mid = (l + r) >> 1;
	if(x <= mid)	change(k << 1,l,mid,x,y,em);
	if(y > mid)		change(k << 1 | 1,mid + 1,r,x,y,em);
	update(k,r - l + 1);
}
signed main()
{
//	freopen("d.in","r",stdin);
//	freopen("d.out","w",stdout);
	init();
	scanf("%lld%lld",&n,&m);
	for(int i = 1;i <= n;i ++)
	{
		scanf("%lld",&a[i]);
		a[i] %= mod;
	}
	for(int i = 1;i <= n;i ++)	sum[i] = ((sum[i - 1] + a[i]) % mod + mod) % mod;

	for(int i = 1,opt,l,r,x;i <= m;i ++)
	{
		scanf("%lld%lld%lld",&opt,&l,&r);
		if(opt == 2)	printf("%lld\n",((ask(1,1,n,l,r) + sum[r] - sum[l - 1]) % mod + mod) % mod);
		else
		{
//			scanf("%d",&x);
			change(1,1,n,l,r,0);
		}
//		for(int i = 1;i <= n * 4;i ++)	cout << tr[i].f1 << " " << tr[i].f2 << " " << tr[i].v << endl;
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}
/*
5 3
1 2 3 4 5
1 1 5
2 1 5 2
1 1 5
*/
/*
5 3
1 2 3 4 5
1 1 5
2 1 1 2
1 1 5
*/


#include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")

#define pp pos[x+j-1]
using namespace std;
typedef long long ll;
const int N=300005;
const ll mod=1000000009;
template<typename T>inline void read(T &x) {
    int f=1;x=0;char c=getchar();
    while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    x*=f;return;
}
template<typename T,typename...Args>
    inline void read(T &x,Args &...args){
    read(x);read(args...);
}
int n,m;
ll fib[N];
int lft[N],rgt[N],pos[N];
ll a[N];
ll num[N];
int base;
void pre(){
    base=sqrt(n);
    if(base*base<n) base++;
    int i,j;
    i=1;j=1;
    while(j<=n){
        lft[i]=j;rgt[i]=j+base-1;
        for(int k=j;k<j+base;k++) pos[k]=i;
        j+=base;i++;
    }
	for(i=1;i<=n;i++){
		num[pos[i]]+=a[i];
	}
    return;
}
int op,x,y;
int main()
{
	int i,j;
	read(n,m);
	for(i=1;i<=n;i++) read(a[i]);
	pre();
	fib[1]=1;fib[2]=1;
	for(i=3;i<=n;i++) fib[i]=(fib[i-1]+fib[i-2])%mod;
	for(i=1;i<=n;i++){
		fib[i]+=fib[i-1];
		fib[i]%=mod;
	}
	ll ans;
	while(m--){
		read(op,x,y);
		if(op&1){
			j=1;
			if(pos[x]==pos[y]){
				while(x+j-1<=y){
					a[x+j-1]+=fib[j]-fib[j-1];
					num[pp]+=fib[j]-fib[j-1];
					j++;
				}
			}
			else{
				while(x+j-1<=rgt[pos[x]]){
					a[x+j-1]+=fib[j]-fib[j-1];
					num[pp]+=fib[j]-fib[j-1];
					j++;
				}
				while(x+j-1<lft[pos[y]]){
					num[pp]+=fib[j+base]-fib[j-1];
					j+=base;
				}
				while(x+j-1<=y){
					a[x+j-1]+=fib[j]-fib[j-1];
					num[pp]+=fib[j]-fib[j-1];
					j++;
				}
			}
		}
		else{
			j=1;ans=0;
			if(pos[x]==pos[y]){
				while(x+j-1<=y){
					ans+=a[x+j-1];
					ans%=mod;
					j++;
				}
			}
			else{
				while(x+j-1<=rgt[pos[x]]){
					ans+=a[x+j-1];
					ans%=mod;
					j++;
				}
				while(x+j-1<lft[pos[y]]){
					ans+=num[pp];
					j+=base;
					ans%=mod;
				}
				while(x+j-1<=y){
					ans+=a[x+j-1];
					ans%=mod;
					j++;
				}
			}
			cout<<(ans%mod+mod)%mod<<endl;
		}
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
typedef long long LL;
#define int long long
const int mod = 1e9+9;
const int maxn = 1e5;
const int N = 1e5+100;
inline int read()
{
	int x = 0 , f = 1; char c = getchar();
	while(c < '0' || c > '9') { f = c == '-' ? -f : f; c = getchar(); }
	while(c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0' , c = getchar();
	return x * f;
}
int n , m;
int a[N];
LL f[N<<1] , sum[N<<1];

void f_Ask(int l , int r)
{
	LL ans = 0LL;
	for(int i = l ; i <= r ; ++i) ans = ( ans + a[i] ) % mod;
	printf("%lld\n",ans);
	return ;
}

void f_Change(int l , int r , int x)
{
	for(int i = l ; i <= r ; ++i)
		a[i] = ( a[i] + f[i-l+x] ) % mod;
}

void force()
{
	f[1] = 1;
	for(int i = 2 ; i <= n+maxn ; ++i) f[i] = (f[i-1] + f[i-2]) % mod;
	int opt , l , r;
	for(int i = 1 ; i <= m ; ++i)
	{
		opt = read(); l = read(); r = read();
		if(opt == 1) f_Ask(l , r);
		if(opt == 2) f_Change(l , r , read());
	}
	return ;
}

void Init()
{
	f[1] = 1; sum[1] = 1;
	for(int i = 2 ; i <= n + maxn ; ++i) f[i] = ( f[i-1] + f[i-2] ) % mod , sum[i] = ( sum[i-1] + f[i] ) % mod;
}

LL tr[N<<2];
LL tag[N<<2][2];
void build(int k , int l , int r)
{
	if(l == r) { tr[k] = a[l] ; return ; }
	int mid = (l + r) >> 1;
	build(k << 1 , l , mid);
	build(k << 1 | 1 , mid + 1 , r);
	tr[k] = (tr[k<<1] + tr[k<<1|1]) % mod;

}

void add(int k , int a , int b , int len)
{
	tag[k][0] = (tag[k][0] + a) % mod;
	tag[k][1] = (tag[k][1] + b) % mod;
	tr[k] = (tr[k] + f[len] * a % mod + f[len + 1] * b % mod - b) % mod;
}

void down(int k , int l , int r)
{
	if(tag[k][0] == 0 && tag[k][1] == 0) return;
	int mid = (l + r) >> 1;
	add(k << 1 , tag[k][0] , tag[k][1] , mid - l + 1);
	int tempa = ( f[mid - l] * tag[k][0] % mod + f[mid - l + 1] * tag[k][1] % mod ) % mod;
	int tempb = ( f[mid - l + 1] * tag[k][0] % mod + f[mid - l + 2] * tag[k][1] % mod ) % mod ;
	add(k << 1 | 1 , tempa , tempb , r - mid);
	tag[k][0] = tag[k][1] = 0;
}

LL ask(int k , int l , int r , int x , int y)
{
	if(x <= l && r <= y) return tr[k];
	down(k , l , r);
	int mid = (l + r) >> 1;
	LL ans = 0LL;
	if(x <= mid) ans = ( ans + ask(k << 1 , l , mid , x , y) ) % mod;
	if(y  > mid) ans = ( ans + ask(k << 1 | 1 , mid + 1 , r , x , y) ) % mod;
	return ( ans % mod + mod ) % mod;
}

void Ask(int x , int y)
{
	printf("%lld\n",ask(1 , 1 , n , x , y) % mod);
}

void change(int k , int l , int r , int x , int y , int a)
{
	if(x <= l && r <= y)
	{
		add(k , f[l - x + a] , f[l - x + a + 1] , r - l + 1);
		return ;
	}
	down(k , l , r);
	int mid = (l + r) >> 1;
	if(x <= mid) change( k << 1 , l , mid , x , y , a);
	if(y  > mid) change( k << 1 | 1 , mid + 1 , r , x , y , a);
	tr[k] = ( tr[k<<1] + tr[k<<1|1] ) % mod;
}

void Change(int l , int r , int x)
{
	change(1 , 1 , n , l , r , x);
}

signed main()
{
//	freopen("d.in","r",stdin);
//	freopen("d.out","w",stdout);
	n = read(); m = read();
	for(int i = 1 ; i <= n ; ++i) a[i] = read();
	Init();
	build(1 , 1 , n);
	int opt , l , r;
	for(int i = 1 ; i <= m ; ++i)
	{
		opt = read(); l = read(); r = read();
		if(opt == 2) Ask(l , r);
		if(opt == 1) Change(l , r , 1);
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}
/*
5 3
1 2 3 4 5
1 1 5
2 1 5 2
1 1 5
*/


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ls (k << 1)
#define rs (k << 1 | 1)
#define L (T[k].l)
#define R (T[k].r)
#define Len (T[k].len)

using namespace std;
typedef long long LL;
const int p = 1e9+9;
const int N = 3e5+5;
int n, m;
struct Tree {
	LL sum, lay, tag;
	int l, r, len;
}T[N<<2];
LL f[N], a[N];

inline void update(int k) {	T[k].sum = (T[ls].sum + T[rs].sum) % p; }

inline void add(int k, LL a, LL b) {
	T[k].tag = (T[k].tag + a) % p;
	T[k].lay = (T[k].lay + b) % p;
	T[k].sum = (T[k].sum + a * f[Len] % p + b * f[Len + 1] % p - b) % p;
}

inline void pushdown(int k) {
	LL a = (T[k].tag * f[T[ls].len - 1] % p + T[k].lay * f[T[ls].len] % p) % p;
	LL b = (T[k].tag * f[T[ls].len] % p + T[k].lay * f[T[ls].len + 1] % p) % p;
	add(ls, T[k].tag, T[k].lay);
	add(rs, a, b);
	T[k].tag = T[k].lay = 0;
}

void build(int k, int l, int r) {
	T[k].l = l, T[k].r = r, T[k].len = r - l + 1;
	if(l == r) { T[k].sum = a[l] % p; return; }
	int mid = (l + r) >> 1;
	build(ls, l, mid), build(rs, mid + 1, r);
	update(k);
}

void Change(int k, int l, int r) {
	if(L >= l && R <= r) {
		add(k, f[L - l + 1], f[L - l + 2]);
		return;
	}
	if(T[k].tag) pushdown(k);
	int mid = (L + R) >> 1;
	if(l <= mid) Change(ls, l, r);
	if(r > mid) Change(rs, l, r);
	update(k);
}

LL query(int k ,int l, int r) {
	if(L >= l && R <= r) return T[k].sum;
	if(T[k].tag) pushdown(k);
	int mid = (L + R) >> 1;
	LL res = 0;
	if(l <= mid) res = (res + query(ls, l, r) % p) % p;
	if(r > mid) res = (res + query(rs, l, r) % p) % p;
	return res;
}

inline void init() {
	f[1] = f[2] = 1;
	for(int i = 3;i < N;++ i)
		f[i] = (f[i - 1] + f[i - 2]) % p;
}

int main() {
	// freopen("d.in", "r", stdin);
	// freopen("d.out", "w", stdout);
	init();
	scanf("%d%d", &n, &m);
	for(int i = 1;i <= n;++ i) scanf("%lld", &a[i]);
	build(1, 1, n);
	for(int i = 1, op, l, r, x;i <= m;++ i) {
		scanf("%d%d%d", &op, &l, &r);
		if(op == 2) printf("%lld\n", (query(1, l, r) + p) % p);
		if(op == 1) Change(1, l, r);
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}


#include<bits/stdc++.h>
#define mod 1000000009
#define five 383008016
#define five1 691504013
#define five2 308495997
using namespace std;
int n,m;
long long a[300005];
int op,L,R;

int sqrtn;
int bl[300005];//block
int l[1005],r[1005],tt;
int siz[1005];//size
long long lazy1[1005],lazy2[1005];
long long sum[1005];

long long f[300005];
long long fs[300005];
inline void init()
{
	f[1]=f[2]=1;
	for(int i=3;i<=300000;i++) f[i]=(f[i-1]+f[i-2])%mod;
	for(int i=1;i<=300000;i++) fs[i]=(fs[i-1]+f[i])%mod;
}

inline void inblock()
{
	for(int i=1;i<=n/sqrtn;i++)
	{
		tt++;
		l[tt]=r[tt-1]+1;
		r[tt]=r[tt-1]+sqrtn;
		siz[tt]=r[tt]-l[tt]+1;
		for(int j=l[tt];j<=r[tt];j++) bl[j]=tt;
	}
	if(sqrtn*sqrtn!=n)
	{
		tt++;l[tt]=r[tt-1]+1;r[tt]=n;siz[tt]=r[tt]-l[tt]+1;
		for(int j=l[tt];j<=r[tt];j++) bl[j]=tt;
	}
}

long long mi(long long n,long long p)
{
	if(n==0) return 0;
    if(p==0) return 1;
	long long yuan=1,mul=n;
	while(p)
    {
        if(p&1) yuan*=mul;
        yuan%=mod;
        mul*=mul;
        mul%=mod;
        p>>=1;
    }
    return yuan%mod;
}

inline void insert()
{
	if(bl[L]==bl[R])
	{
		int tot=1;
		for(int i=L;i<=R;i++)
		{
			a[i]+=f[tot]%mod; a[i]%=mod;
			tot++;
		}
		sum[bl[L]]+=fs[tot-1]%mod; sum[bl[L]]%=mod;
		return ;
	}

	int tot=1;
	for(int i=L;i<=r[bl[L]];i++)
	{
		a[i]+=f[tot]%mod; a[i]%=mod;
		sum[bl[L]]+=f[tot]%mod; sum[bl[L]]%=mod;
		tot++;
	}
	for(int i=bl[L]+1;i<bl[R];i++)
	{
		lazy1[i]+=mi(five1,tot)%mod;
		lazy2[i]+=mi(five2,tot)%mod;
		sum[i]+=fs[tot+siz[i]-1]-fs[tot-1]; sum[i]%=mod;
		tot+=siz[i];
	}
	for(int i=l[bl[R]];i<=R;i++)
	{
		a[i]+=f[tot]%mod; a[i]%=mod;
		sum[bl[R]]+=f[tot]%mod; sum[bl[R]]%=mod;
		tot++;
	}
}

inline void push_down()
{
	if(lazy1[bl[L]]!=0 || lazy2[bl[L]]!=0)
	{
		int tot=0;
		for(int i=l[bl[L]];i<=r[bl[L]];i++)
		{
			a[i]+=lazy1[bl[L]]*mi(five1,tot)%mod*mi(five,mod-2)%mod;
			a[i]-=lazy2[bl[L]]*mi(five2,tot)%mod*mi(five,mod-2)%mod;
			tot++;
		}
		lazy1[bl[L]]=lazy2[bl[L]]=0;
	}
	if(lazy1[bl[R]]!=0 || lazy2[bl[R]]!=0)
	{
		int tot=0;
		for(int i=l[bl[R]];i<=r[bl[R]];i++)
		{
			a[i]+=lazy1[bl[R]]*mi(five1,tot)%mod*mi(five,mod-2)%mod;
			a[i]-=lazy2[bl[R]]*mi(five2,tot)%mod*mi(five,mod-2)%mod;
			tot++;
		}
		lazy1[bl[R]]=lazy2[bl[R]]=0;
	}
//	cout<<"pushed:"<<endl;
//	for(int i=1;i<=n;i++) cout<<a[i]<<" "; cout<<endl;
}

inline void ask()
{
	long long anss=0;
	push_down();

	if(bl[L]==bl[R])
	{
		for(int i=L;i<=R;i++)
		{
			anss+=a[i]%mod;
			anss%=mod;
		}
		cout<<anss<<endl;
		return ;
	}

	for(int i=L;i<=r[bl[L]];i++)
	{
		anss+=a[i]%mod;
		anss%=mod;
	}
	for(int i=l[bl[R]];i<=R;i++)
	{
		anss+=a[i]%mod;
		anss%=mod;
	}
	for(int i=bl[L]+1;i<bl[R];i++)
	{
		anss+=sum[i]%mod;
		anss%=mod;
	}
	cout<<(anss%mod+mod)%mod<<endl;
	return ;
}

int main()
{
//	freopen("rd.in","r",stdin);
//	freopen("my.out","w",stdout);
	ios::sync_with_stdio(0);
	cin>>n>>m;
	sqrtn=pow(n,0.55);
	inblock();
	init();
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		sum[bl[i]]+=a[i];
		sum[bl[i]]%=mod;
	}

//	for(int i=1;i<=n;i++) cout<<bl[i]<<" "; cout<<endl;
//	for(int i=1;i<=tt;i++) cout<<sum[i]<<" "; cout<<endl;
//	cout<<endl;
	while(m--)
	{
		cin>>op>>L>>R;
		if(op==1)
		{
			insert();
//			cout<<endl;
//			for(int i=1;i<=n;i++) cout<<a[i]<<" "; cout<<endl;
//			for(int i=1;i<=tt;i++) cout<<sum[i]<<" "; cout<<endl;
//			cout<<endl;
		}
		else
		{
			ask();
		}
	}
}


/*
--------------------------
给区间加上斐波那契数列.
性质1. ∑fib(i)=fib(n+2)-fib(2)
       即对于S(i)=S(i-2)+S(i-1),∑S(i)=S(n+2)-S(2).
       (∑范围是[1,n])
性质2. 若S(i)=S(i-2)+S(i-1),有S(i)=S(1)*fib(i-2)+S(2)*fib(i-1).
可以利用性质,已知S1,S2,len,求出这一段的总和.
用线段树维护,pushdown的时候注意分类讨论,给左边右边加上相应的权值.
--------------------------
调试技巧:
1.如果参考标程可以把相应的变量输出.
2.#define int long long.
3.检查数组越界.
--------------------------2019.1.24
*/
#include<bits/stdc++.h>
#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)<(y)?(x):(y))
#define int long long
using namespace std;
typedef long long LL;
const int INF=1e9+7;
inline LL read(){
    register LL x=0,f=1;register char c=getchar();
    while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
    while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
    return f*x;
}

const int MAXN=3e5+5;
const int mod=1e9+9;

int fib[MAXN];
int n,m;

namespace SGT{
    int sum[MAXN<<2],num[MAXN<<2][2];
    bool tag[MAXN<<2];
#define ls (rt<<1)
#define rs (rt<<1|1)
    inline int delta(int a,int b,int len){
        LL res=0;
        if(len>=1) res+=a;
        if(len>=2) res+=b;
        if(len>=3) res+=(LL)a*(fib[len]-1)+b*(fib[len+1]-2);
        return res%mod;
    }
    inline void pushup(int rt){
        sum[rt]=(sum[ls]+sum[rs])%mod;
    }
    inline void pushdown(int rt,int l,int r,int mid){
        if(tag[rt]){
            //num[ls][0]=num[rt][0],num[ls][1]=num[rt][1];
            int a=num[rt][0],b=num[rt][1];
//            printf("%d %d\n",num[rt][0],num[rt][1]);
            (num[ls][0]+=a)%=mod;
            (num[ls][1]+=b)%=mod;
            (sum[ls]+=delta(a,b,mid-l+1))%=mod;
            tag[ls]=1;
            int len=mid-l;
            int c=(a*fib[len]%mod+b*fib[len+1]%mod)%mod,d=(a*fib[len+1]%mod+b*fib[len+2]%mod)%mod;//
            (num[rs][0]+=c)%=mod;
            (num[rs][1]+=d)%=mod;
            //num[2][0]-=dd256;
            (sum[rs]+=delta(c,d,r-mid))%=mod;
            tag[rs]=1;
            num[rt][0]=num[rt][1]=0;//
            tag[rt]=0;
//			printf("%d %d %d %d %d %d %d \n",num[rt][0],num[rt][1],sum[rt],num[ls][0],num[ls][1],num[rs][0],num[rs][1]);
//			printf("%d %d %d %d\n",a,b,c,d);
        }
    }
    inline void build(int rt,int l,int r){
        if(l==r){
            sum[rt]=read()%mod;
            return;
        }
        int mid=(l+r)>>1;
        build(ls,l,mid);
        build(rs,mid+1,r);
        pushup(rt);
    }
    inline void modify(int rt,int l,int r,int x,int y,int s1,int s2){
//		printf("%d %d %d %d %d %d %d\n",rt,l,r,x,y,s1,s2);
        if(l>=x&&r<=y){
            (num[rt][0]+=s1)%=mod,(num[rt][1]=+s2)%=mod;
            (sum[rt]+=delta(s1,s2,r-l+1))%=mod;
            tag[rt]=1;
            return;
        }
        int mid=(l+r)>>1;
        pushdown(rt,l,r,mid);
        if(y<=mid) modify(ls,l,mid,x,y,s1,s2);
        else if(x>=mid+1) modify(rs,mid+1,r,x,y,s1,s2);
        else{
            modify(ls,l,mid,x,mid,s1,s2);//
            int len=mid-x;//
            int c=(s1*fib[len]+s2*fib[len+1])%mod,d=(s1*fib[len+1]+s2*fib[len+2])%mod;
            modify(rs,mid+1,r,mid+1,y,c,d);
        }
        pushup(rt);
    }
    inline int query(int rt,int l,int r,int x,int y){
//		printf("%d %d %d %d %d %d\n",rt,l,r,x,y,sum[rt]);
        if(l>=x&&r<=y) return sum[rt];
        int mid=(l+r)>>1;
        pushdown(rt,l,r,mid);
        int res=0;
        if(x<=mid) res+=query(ls,l,mid,x,y);
        if(mid<y) res+=query(rs,mid+1,r,x,y);
        return res%mod;
    }
#undef ls
#undef rs
}

signed main(){
#ifdef flie
    freopen("you.in","r",stdin);
    freopen("you.out","w",stdout);
#endif
    n=read(),m=read();
    SGT::build(1,1,n);
    fib[1]=fib[2]=1;
    for(int i=3;i<MAXN;i++)
        fib[i]=(fib[i-1]+fib[i-2])%mod;
    for(int i=1;i<=m;i++){
        int op=read(),x=read(),y=read();
        if(op==1) SGT::modify(1,1,n,x,y,1,1);
        if(op==2) printf("%d\n",SGT::query(1,1,n,x,y));
    }
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
#define drep(i, a, b) for(int i = (a), i##_end_ = (b); i >= i##_end_; --i)
#define clar(a, b) memset((a), (b), sizeof(a))
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define Debug(s) debug("The massage in line %d, Function %s: %s\n", __LINE__, __FUNCTION__, s)
typedef long long LL;
typedef long double LD;
int read() {
    char ch = getchar();
    int x = 0, flag = 1;
    for(;!isdigit(ch); ch = getchar()) if(ch == '-') flag *= -1;
    for(;isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
    return x * flag;
}
void write(int x) {
    if(x < 0) putchar('-'), x = -x;
    if(x >= 10) write(x / 10);
    putchar(x % 10 + 48);
}

#define Maxn 300009
const LL Mod = (LL)(1e9 + 7);
int n, a[Maxn], m; LL f[Maxn];
struct node { LL x, y; };
LL FibDelta(LL F1, LL F2, LL len) {
    LL res = 0;
    if(len >= 1) (res += F1) %= Mod;
    if(len >= 2) (res += F2) %= Mod;
    if(len >= 3) (res += (F2 * (f[len + 1] - f[3]) % Mod + F1 * (f[len] - f[2]) % Mod) % Mod) %= Mod;
    return res;
}// needs to be analyzed in different conditions
node FibForward(node s, int len) {
    LL c = s.x * f[len] % Mod + s.y * f[len + 1] % Mod, d = s.x * f[len + 1] % Mod + s.y * f[len + 2] % Mod;
    return (node){c % Mod, d % Mod};
}
namespace SGMT_tree {
    LL tree[Maxn << 2], beg[Maxn << 2][2], val[Maxn << 2];
#define lc(x) (x) << 1
#define rc(x) (x) << 1 | 1
#define ls rt << 1, l, mid
#define rs rt << 1 | 1, mid + 1, r
    void pushup(int rt) { tree[rt] = (1ll * tree[lc(rt)] + 1ll * tree[rc(rt)]) % Mod; }
    void pushdown(int rt, int l, int r) {
        int mid = (l + r) >> 1;
        if(val[rt]) {
            LL &a = beg[rt][0], &b = beg[rt][1];
            (beg[lc(rt)][0] += a) %= Mod, (beg[lc(rt)][1] += b) %= Mod;
            (tree[lc(rt)] += FibDelta(a, b, mid - l + 1)) %= Mod;
            val[lc(rt)] = 1;

            LL c = a * f[mid - l] + b * f[mid - l + 1], d = a * f[mid - l + 1] + b * f[mid - l + 2];
            c %= Mod, d %= Mod;
            (beg[rc(rt)][0] += c) %= Mod, (beg[rc(rt)][1] += d) %= Mod;
            (tree[rc(rt)] += FibDelta(c, d, r - mid)) %= Mod;
            val[rc(rt)] = 1;
            beg[rt][0] = beg[rt][1] = 0;
            val[rt] = 0;
        }
    }
    void build(int rt, int l, int r) {
        if(l == r) {
            tree[rt] = a[l];
            return ;
        }
        int mid = (l + r) >> 1;
        build(ls), build(rs);
        pushup(rt);
    }
    void modify(int rt, int l, int r, int x, int y, int p1, int p2) {
        if(x <= l && r <= y) {
            (beg[rt][0] += p1) %= Mod, (beg[rt][1] += p2) %= Mod;
            (tree[rt] += FibDelta(p1, p2, r - l + 1)) %= Mod;
            val[rt] = 1;
            return ;
        }

        int mid = (l + r) >> 1;
        pushdown(rt, l, r);

        if(y <= mid)  modify(ls, x, y, p1, p2);
        else if(mid + 1 <= x)  modify(rs, x, y, p1, p2);
        else {
            modify(ls, x, mid, p1, p2); /**/
            node z = FibForward((node){p1, p2}, mid - x);/**/
            //F[i] -> F[i + mid - x]: p1 -> z.x, p2 -> z.y
            modify(rs, mid + 1, y, z.x, z.y);/*The InterVal's Range needs to be moved*/
        }
        pushup(rt);
    }
    int query(int rt, int l, int r, int x, int y) {
        if(x <= l && r <= y) return tree[rt];

        int mid = (l + r) >> 1; pushdown(rt, l, r);

        if(y <= mid) return query(ls, x, y);
        else if(mid + 1 <= x) return query(rs, x, y);
        else return (1ll * query(ls, x, y) + 1ll * query(rs, x, y)) % Mod;
    }
#undef lc
#undef rc
#undef ls
#undef rs
}
namespace INIT {
    void Main() {
        n = read(), m = read();

        f[1] = 1; f[2] = 1;
        rep(i, 3, n + 4) f[i] = (f[i - 1] * 1ll + f[i - 2]) % Mod;

        rep(i, 1, n) a[i] = read() % Mod;

        SGMT_tree :: build(1, 1, n);
    }
}
namespace SOLVE {
    void Main() {
        rep(i, 1, m) {
            int opt = read();

            if(opt == 1) {
                int x = read(), y = read();
                SGMT_tree :: modify(1, 1, n, x, y, 1, 1);
            }
            if(opt == 2) {
                int x = read(), y = read();
                write(SGMT_tree :: query(1, 1, n, x, y) % Mod), putchar('\n');
            }
        }
    }
}
int main() {
//	freopen("you.in", "r", stdin);
//	freopen("you.out", "w", stdout);

    INIT :: Main();
    SOLVE :: Main();
#ifdef Qrsikno
    debug("\nRunning time: %.3lf(s)\n", clock() * 1.0 / CLOCKS_PER_SEC);
#endif
    return 0;
}


#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
#define g getchar()
#define lc (x<<1)
#define rc (x<<1|1)
using namespace std;
typedef long long ll;
const int N=3e5+10,p=1e9+9;

template<class o> void qr(o&x) {
	char c=g;x=0;int f=1;
	while(!isdigit(c)){if(c=='-')f=-1; c=g;}
	while(isdigit(c)) x=x*10+c-'0',c=g;
	x*=f;
}
void write(int x) {
	if(x/10)write(x/10);
	putchar(x%10+'0');
}

//两条重要的性质：
//1.g[i]=f[i-2]*a+f[i-1]*b (f为斐波那契数列,a、b为广义斐波那契数列的前两项)
//2.s[n]=g[n+2]-g[2] (s为广义斐波那契数列的前缀和)
//这个可以用数学归纳法证明:
//首先对于n=1,显然成立.
//s[n+1]=s[n]+g[n+1]=g[n+2]+g[n+1]+g[2]=g[n+3]+g[2]
struct node {
	ll a,b,s;
}tr[N<<2];
int n,m,f[N];ll s[N];

inline void upd(int x,int l,int r) {
	tr[x].s=(tr[lc].s+tr[rc].s+tr[x].a*f[r-l+1]+tr[x].b*f[r-l+2]-tr[x].b)%p;
}

int lazy(int x,int l,int r) {
	int mid=(l+r)>>1;
	if(tr[x].a||tr[x].b) {
		tr[lc].a=(tr[lc].a+tr[x].a)%p;
		tr[lc].b=(tr[lc].b+tr[x].b)%p;
		upd(lc,l,mid);
		tr[rc].a=(tr[rc].a+tr[x].a*f[mid-l]+tr[x].b*f[mid-l+1])%p;
		tr[rc].b=(tr[rc].b+tr[x].a*f[mid-l+1]+tr[x].b*f[mid-l+2])%p;
		upd(rc,mid+1,r);
		tr[x].a=tr[x].b=0;
	}
	return mid;
}

void add(int x,int l,int r,const int &L,const int &R) {
	if(L<=l&&r<=R) {
		tr[x].a=(tr[x].a+f[l-L+1])%p;
		tr[x].b=(tr[x].b+f[l-L+2])%p;
		upd(x,l,r);
		return ;
	}
	int mid=lazy(x,l,r);
	if(L<=mid) add(lc,l,mid,L,R);
	if(mid< R) add(rc,mid+1,r,L,R);
	upd(x,l,r);
}

ll ans;
void find(int x,int l,int r,const int &L,const int &R) {
	if(L<=l&&r<=R) { ans=(ans+tr[x].s)%p; return; }
	int mid=lazy(x,l,r);
	if(L<=mid) find(lc,l,mid,L,R);
	if(mid< R) find(rc,mid+1,r,L,R);
}

int main() {
	qr(n);qr(m); f[1]=f[2]=1;
	for(register int i=3;i<=n+1;i++)f[i]=(f[i-2]+f[i-1])%p;
	for(register int i=1;i<=n;i++)qr(s[i]),s[i]+=s[i-1];//前缀和
	while(m--) {
		int op,l,r;qr(op);qr(l);qr(r);
		switch(op) {
			case 1:add(1,1,n,l,r);break;
			case 2:
				ans=(s[r]-s[l-1])%p;
				find(1,1,n,l,r);write((int)ans);
				puts("");break;
		}
	}
	return 0;
}


#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<cstring>
#define int long long
using namespace std;
inline int read()
{
	int GYH,LZY;
	GYH=0,LZY=1;
	char aqx;
	aqx=getchar();
	while(aqx<'0'||aqx>'9')
	{
		if(aqx=='-')LZY=-1;
		aqx=getchar();
	}
	while(aqx>='0'&&aqx<='9')
	{
		GYH=(GYH<<1)+(GYH<<3)+aqx-'0';
		aqx=getchar();
	}
	return GYH*LZY;
}
const int maxn=3e5+5;
const int maxm=maxn<<3;
const int lzy=1e9+9;
int n,gvh;
int shu[maxn];
int num[maxm],_num[maxm];
int sum[maxm];
int tree[maxm];
int luzy1[maxm],luzy2[maxm];
inline int ls(int x){return x<<1;}
inline int rs(int x){return x<<1|1;}
void build(int l,int r,int x)
{
	if(l>r)return;
	if(l==r)
	{
		tree[x]=shu[l];
		return;
	}
	int mid=(l+r)>>1;
	build(l,mid,ls(x)),build(mid+1,r,rs(x));
	tree[x]=tree[ls(x)]+tree[rs(x)],tree[x]%=lzy;
	return;
}
inline void push(int l,int r,int x)
{
	int mid=(l+r)>>1;
	luzy1[ls(x)]+=luzy1[x],luzy1[rs(x)]+=luzy1[x];
	luzy1[ls(x)]%=lzy,luzy1[rs(x)]%=lzy;

	luzy2[ls(x)]+=luzy2[x],luzy2[rs(x)]+=luzy2[x];
	luzy2[ls(x)]%=lzy,luzy2[rs(x)]%=lzy;

	tree[ls(x)]+=((sum[mid+1]-sum[l]+lzy)%lzy)*luzy1[x];
	tree[rs(x)]+=((sum[r+1]-sum[mid+1]+lzy)%lzy)*luzy1[x];
	tree[ls(x)]%=lzy,tree[rs(x)]%=lzy;

	tree[ls(x)]+=((sum[mid]-sum[l-1]+lzy)%lzy)*luzy2[x];
	tree[rs(x)]+=((sum[r]-sum[mid]+lzy)%lzy)*luzy2[x];
	tree[ls(x)]%=lzy,tree[rs(x)]%=lzy;

	luzy1[x]=luzy2[x]=0;
	return;
}
void add(int zl,int zr,int l,int r,int x,int jia1,int jia2)
{
	if(l>zr||r<zl)return;
	push(l,r,x);
	int mid=(l+r)>>1;
	if(zl<=l&&r<=zr)
	{
		luzy1[x]+=jia1,luzy2[x]+=jia2;
		luzy1[x]%=lzy,luzy2[x]%=lzy;
		tree[x]+=((sum[r+1]-sum[l]+lzy)%lzy)*luzy1[x];
		tree[x]%=lzy;
		tree[x]+=((sum[r]-sum[l-1]+lzy)%lzy)*luzy2[x];
		tree[x]%=lzy;
		return;
	}
	add(zl,zr,l,mid,ls(x),jia1,jia2);
	add(zl,zr,mid+1,r,rs(x),jia1,jia2);
	tree[x]=tree[ls(x)]+tree[rs(x)],tree[x]%=lzy;
	return;
}
int get(int zl,int zr,int l,int r,int x)
{
	if(l>zr||r<zl)return 0;
	push(l,r,x);
	if(zl<=l&&r<=zr)
	return tree[x];
	int mid=(l+r)>>1;
	int jie=0;
	jie+=get(zl,zr,l,mid,ls(x));
	jie+=get(zl,zr,mid+1,r,rs(x));
	return jie%lzy;
}
signed main()
{
	n=read(),gvh=read();
	for(int i=1;i<=n;i++)
	{
		shu[i]=read();
		shu[i]%=lzy;
	}
	num[1]=num[2]=1;
    sum[1]=1,sum[2]=2;
    _num[0]=0,_num[1]=1,_num[2]=lzy-1;
    for(int i=3;i<maxm;i++)
	{
        num[i]=(num[i-1]+num[i-2])%lzy;
        sum[i]=(sum[i-1]+num[i])%lzy;
        _num[i]=(i&1)?num[i]:lzy-num[i];
    }
	build(1,n,1);
	int opt,l,r;
	while(gvh--)
	{
		opt=read(),l=read(),r=read();
//		for(int i=1;i<=n*5;i++)
//        cout<<tree[i]<<" "<<luzy1[i]<<" "<<luzy2[i]<<" "<<i<<"tree\n";
		if(opt==1)
		add(l,r,1,n,1,_num[l-1],_num[l]);
		else
		cout<<get(l,r,1,n,1)<<"\n";
	}
}


#include<bits/stdc++.h>
namespace my_std{
	using namespace std;
	#define pii pair<int,int>
	#define fir first
	#define sec second
	#define MP make_pair
	#define rep(i,x,y) for (int i=(x);i<=(y);i++)
	#define drep(i,x,y) for (int i=(x);i>=(y);i--)
	#define go(x) for (int i=head[x];i;i=edge[i].nxt)
	#define sz 303030
	typedef long long ll;
	const ll mod=1e9+9;
	template<typename T>
	inline void read(T& t)
	{
		t=0;char f=0,ch=getchar();
		double d=0.1;
		while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
		while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
		if(ch=='.')
		{
			ch=getchar();
			while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();
		}
		t=(f?-t:t);
	}
	template<typename T,typename... Args>
	inline void read(T& t,Args&... args){read(t); read(args...);}
	void file()
	{
		#ifndef ONLINE_JUDGE
		freopen("a.txt","r",stdin);
		#endif
	}
//	inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std;

int n,m;
int a[sz];

ll f[sz],ff[sz],F[sz];
void init()
{
	F[1]=f[1]=1;
	rep(i,2,sz-1) F[i]=(F[i-1]+(f[i]=(f[i-1]+f[i-2])%mod))%mod;
	rep(i,1,sz-1) ff[i]=(i&1)?f[i]:mod-f[i];
}

ll tg1[sz<<2],tg2[sz<<2],sum[sz<<2];
#define ls k<<1
#define rs k<<1|1
#define lson k<<1,l,mid
#define rson k<<1|1,mid+1,r
#define S int k,int l,int r
#define I inline
I void Add1(S,ll s){(tg1[k]+=s)%=mod;(sum[k]+=s*(F[r]-F[l-1]+mod)%mod)%=mod;}
I void Add2(S,ll s){(tg2[k]+=s)%=mod;(sum[k]+=s*(F[r+1]-F[l]+mod)%mod)%=mod;}
I void pushdown(S)
{
	if (!tg1[k]&&!tg2[k]) return;
	int mid=(l+r)>>1;
	ll &t1=tg1[k],&t2=tg2[k];
	Add1(lson,t1);Add1(rson,t1);
	Add2(lson,t2);Add2(rson,t2);
	t1=t2=0;
}
void pushup(int k){sum[k]=(sum[ls]+sum[rs])%mod;}
void add(S,int x,int y,ll s1,ll s2)
{
	if (x<=l&&r<=y) return Add1(k,l,r,s1),Add2(k,l,r,s2);
	pushdown(k,l,r);
	int mid=(l+r)>>1;
	if (x<=mid) add(lson,x,y,s1,s2);
	if (y>mid) add(rson,x,y,s1,s2);
	pushup(k);
}
ll query(S,int x,int y)
{
	if (x<=l&&r<=y) return sum[k];
	pushdown(k,l,r);
	int mid=(l+r)>>1;
	ll ret=0;
	if (x<=mid) ret+=query(lson,x,y);
	if (y>mid) ret+=query(rson,x,y);
	return ret%mod;
}
void build(S)
{
	if (l==r) return (void)(sum[k]=a[l]%mod);
	int mid=(l+r)>>1;
	build(lson);build(rson);
	pushup(k);
}

int main()
{
	file();
	int x,y,z;
	read(n,m);
	rep(i,1,n) read(a[i]);
	init();
	build(1,1,n);
	while (m--)
	{
		read(z,x,y);
		if (z==1) add(1,1,n,x,y,ff[x],ff[x-1]);
		else printf("%lld\n",query(1,1,n,x,y));
	}
	return 0;
}


#include<cstdio>
#include<iostream>
#define int long long
using namespace std;
const int N = 300005;
int n,m;
struct T{
    int f1,f2,v;
}tr[N*20];
int a[N],f[N],sum[N];
const int mod=1e9+9;
void init()
{
    f[1]=1,f[2]=1;
    for(int i=3;i<=n+1;i++)f[i]=(f[i-2]+f[i-1])%mod;
}/*
void update(int k,int len)
{
	tr[k].f1 %= mod;	tr[k].f2 %= mod;
	tr[k].v = (((tr[k << 1].v + tr[k << 1 | 1].v) % mod + tr[k].f1 * f[len] % mod + tr[k].f2 * f[len + 1] % mod - tr[k].f2) % mod + mod) % mod;
}*/
void update(int rt,int pos)
{
	int ls = (rt << 1),rs = (rt << 1 | 1);
    tr[rt].f1%=mod,tr[rt].f2%=mod;
    tr[rt].v=tr[ls].v+tr[rs].v+(tr[rt].f1*f[pos]+tr[rt].f2*f[pos+1]-tr[rt].f2),tr[rt].v%=mod;
//    cout <<t[ls].v << " " << t[rs].v << endl;
}/*
void down(int k,int l,int r)
{
	if(tr[k].f1 == 0 && tr[k].f2 == 0)	return;
	int mid = (l + r) >> 1;
	tr[k << 1].f1 += tr[k].f1;
	tr[k << 1 | 1].f1 += (tr[k].f1 * f[mid - l] % mod + tr[k].f2 * f[mid - l + 1] % mod) % mod;
	tr[k << 1].f2 += tr[k].f2;
	tr[k << 1 | 1].f2 += (tr[k].f1 * f[mid - l + 1] % mod + tr[k].f2 * f[mid - l + 2] % mod) % mod;
	tr[k].f1 = tr[k].f2 = 0;
	update(k << 1,mid - l + 1);	update(k << 1 | 1,r - mid);
}*/
void down(int rt,int l,int r)
{
    if(tr[rt].f1==0&&tr[rt].f2==0)return ;
    int mid=(l+r)>>1,ls = (rt << 1),rs = (rt << 1 | 1);
    tr[ls].f1+=tr[rt].f1,tr[rs].f1+=tr[rt].f1*f[mid-l]+tr[rt].f2*f[mid-l+1];
    tr[ls].f2+=tr[rt].f2,tr[rs].f2+=tr[rt].f1*f[mid-l+1]+tr[rt].f2*f[mid-l+2];
    tr[rt].f1=tr[rt].f2=0;
    update(ls,mid-l+1),update(rs,r-mid);
}/*
long long ask(int k,int l,int r,int x,int y)
{
	if(x <= l && r <= y)	return tr[k].v %= mod;
	down(k,l,r);
	int mid = (l + r) >> 1;
	long long ans = 0;
	if(x <= mid)	ans = (ans + ask(k << 1,l,mid,x,y)) % mod;
	if(y > mid)		ans = (ans + ask(k << 1 | 1,mid + 1,r,x,y)) % mod;
	return ans;
}*//*
void change(int k,int l,int r,int x,int y,int em)
{
	if(x <= l && r <= y)
	{
		tr[k].f1 = (tr[k].f1 + f[em + l - x + 1]) % mod;
		tr[k].f2 = (tr[k].f2 + f[em + l - x + 2]) % mod;
		update(k,r - l + 1);
		return;
	}
	down(k,l,r);
	int mid = (l + r) >> 1;
	if(x <= mid)	change(k << 1,l,mid,x,y,em);
	if(y > mid)		change(k << 1 | 1,mid + 1,r,x,y,em);
	update(k,r - l + 1);
}*/
int ask(int rt,int l,int r,int L,int R)
{
    if(L<=l&&r<=R)return tr[rt].v;
    down(rt,l,r);
    int res=0;
    int mid=(l+r)>>1,ls = (rt << 1),rs = (rt << 1 | 1);
    if(L<=mid)res+=ask(ls,l,mid,L,R);
    if(mid<R)res+=ask(rs,mid+1,r,L,R);
    return res%mod;
}
void change(int rt,int l,int r,int L,int R)
{
    if(L<=l&&r<=R)//边界条件
    {
        tr[rt].f1+=f[l-L+1];
        tr[rt].f2+=f[l-L+2];
        tr[rt].f1%=mod,tr[rt].f2%=mod;
        update(rt,r-l+1);
        return ;
    }
    down(rt,l,r);
    int mid=(l+r)>>1,ls = (rt << 1),rs = (rt << 1 | 1);
    if(L<=mid)change(ls,l,mid,L,R);
    if(mid<R)change(rs,mid+1,r,L,R);
    update(rt,r-l+1);
}
/*
signed main()
{
//	freopen("d.in","r",stdin);
//	freopen("d.out","w",stdout);
	init();
	scanf("%lld%lld",&n,&m);
	for(int i = 1;i <= n;i ++)	scanf("%lld",&a[i]);
	for(int i = 1;i <= n;i ++)	sum[i] = sum[i - 1] + a[i];
	for(int i = 1,opt,l,r,x;i <= m;i ++)
	{
		scanf("%lld%lld%lld",&opt,&l,&r);
		if(opt == 2)	printf("%lld\n",((ask(1,1,n,l,r) + sum[r] - sum[l - 1]) % mod + mod) % mod);
		else
		{
//			scanf("%d",&x);
			change(1,1,n,l,r,0);
		}
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}*/
signed main()
{
    scanf("%lld%lld",&n,&m);
    init();
    for(int i=1;i<=n;i++)scanf("%lld",&a[i]),sum[i]=sum[i-1]+a[i];//预处理前缀和

    while(m--)
    {
        int opt,l,r;
        scanf("%lld%lld%lld",&opt,&l,&r);
        if(opt==1)change(1,1,n,l,r);
        else printf("%lld\n",(ask(1,1,n,l,r)+sum[r]-sum[l-1]+mod)%mod);
//        for(int i = 1;i <= n * 4;i ++)	cout << t[i].f1 << " " << t[i].f2 << " " << t[i].v << endl;
    }

    return 0;
}
/*
5 3
1 2 3 4 5
1 1 5
2 1 5 2
1 1 5
*/
/*
5 3
1 2 3 4 5
1 1 5
2 1 1 2
1 1 5
*/


#include<iostream>
#include<cstring>
#include<cstdio>
#define int long long
using namespace std;
const int mod=1e9+9;
const int N=300005;
inline int read()
{
    register int x=0,y=1;register char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')y=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return x*y;
}
struct node
{
	int f1;
	int f2;
	int sum;
}tr[N<<2];
int a[N],sum[N];
int f[N];
int n,m;
void init()
{
	f[1]=1;f[2]=1;
	for(int i=3;i<=N-1;i++) f[i]=(f[i-1]+f[i-2])%mod;
}
void up(int k,int len)
{tr[k].f1%=mod,tr[k].f2%=mod,tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum+(tr[k].f1*f[len]%mod+tr[k].f2*f[len+1]%mod-tr[k].f2)%mod;}
void down(int k,int l,int r)
{
	if(tr[k].f1==0&&tr[k].f2==0) return;
	int mid=(l+r)>>1;
	tr[k<<1].f1+=tr[k].f1;
	tr[k<<1].f2+=tr[k].f2;
	tr[k<<1|1].f1+=tr[k].f1*f[mid-l]+tr[k].f2*f[mid-l+1];
	tr[k<<1|1].f2+=tr[k].f1*f[mid-l+1]+tr[k].f2*f[mid-l+2];
	tr[k].f1=0;tr[k].f2=0;
	up(k<<1,mid-l+1);up(k<<1|1,r-mid);
}
void change(int k,int l,int r,int ql,int qr)
{
	if(ql<=l&&r<=qr)
	{
		tr[k].f1+=f[l-ql+1];
		tr[k].f2+=f[l-ql+2];
		tr[k].f1%=mod;
		tr[k].f2%=mod;
		up(k,r-l+1);
		return;
	}
	down(k,l,r);
	int mid=(l+r)>>1;
	if(ql<=mid) change(k<<1,l,mid,ql,qr);
	if(mid<qr) change(k<<1|1,mid+1,r,ql,qr);
	up(k,r-l+1);
}
int query(int k,int l,int r,int ql,int qr)
{
	if(l>=ql&&r<=qr) return tr[k].sum;
	down(k,l,r);
	int mid=(l+r)>>1;
	int res=0;
	if(ql<=mid) res+=query(k<<1,l,mid,ql,qr);
	if(mid<qr) res+=query(k<<1|1,mid+1,r,ql,qr);
	return res;
}
signed main()
{
	n=read();m=read();
	init();
	for(int i=1;i<=n;i++) a[i]=read();
	for(int i=1;i<=n;i++) sum[i]=(sum[i-1]+a[i])%mod;
	for(int i=1;i<=m;i++)
    {
        int opt,l,r;
       opt=read();l=read();r=read();
        if(opt==1)change(1,1,n,l,r);
        else printf("%lld\n",(query(1,1,n,l,r)+sum[r]-sum[l-1]+mod)%mod);
    }
}


// FUCK DS

#include <algorithm>
#include <cstdio>
#include <cstring>

#define L ch][0
#define R ch][1
#define mid (l + r) / 2
const int N = 2e6 + 62, P = 1e9 + 9, X = 691504013, Y = 308495997, Z = 276601605;
int sum(int x, int y) { return (x += y) >= P ? x - P : x; }
void add(int& x, int y) { (x += y) >= P && (x -= P); }
int pwX[N], pwY[N];
int ch[N][2], s[N], t1[N], t2[N], sz[N], nc;
void up(int x) { x[s] = sum(x[L][s], x[R][s]); }
void put(int x, int v1, int v2) {
	add(x[s], 1ll * v1 * (P + pwX[x[sz] + 1] - X) % P * X % P);
	add(x[s], 1ll * v2 * (P + pwY[x[sz] + 1] - Y) % P * Y % P);
	add(x[t1], v1), add(x[t2], v2);
}
void pd(int x) {
	put(x[L], x[t1], x[t2]);
	put(x[R], 1ll * pwX[x[L][sz]] * x[t1] % P, 1ll * pwY[x[L][sz]] * x[t2] % P);
	x[t1] = x[t2] = 0;
}
void build(int x, int l, int r) {
	x[sz] = r - l + 1;
	if (l < r) build(x[L] = ++nc, l, mid), build(x[R] = ++nc, mid + 1, r);
}
// 区间加 [v1*X + v2*Y, v1*X^2 + v2*Y^2, ..., v1*X^k + v2*Y^k]
void upd(int x, int l, int r, int ql, int qr, int v1, int v2) {
	if (ql <= l && r <= qr) {
		int gap = std::max(0, l - ql);
		return put(x, 1ll * pwX[gap] * v1 % P, 1ll * pwY[gap] * v2 % P);
	}
	pd(x);
	if (ql <= mid) upd(x[L], l, mid, ql, qr, v1, v2);
	if (mid < qr) upd(x[R], mid + 1, r, ql, qr, v1, v2);
	up(x);
}
int qry(int x, int l, int r, int ql, int qr) {
	if (ql <= l && r <= qr) return x[s];
	pd(x);
	if (qr <= mid) return qry(x[L], l, mid, ql, qr);
	if (mid < ql) return qry(x[R], mid + 1, r, ql, qr);
	return sum(qry(x[L], l, mid, ql, qr), qry(x[R], mid + 1, r, ql, qr));
}

int n, m, x, y, z, a[N];
int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++) scanf("%d", a + i), add(a[i], a[i - 1]);
	pwX[0] = pwY[0] = 1;
	for (int i = 1; i <= n + 1; i++) {
		pwX[i] = 1ll * pwX[i - 1] * X % P;
		pwY[i] = 1ll * pwY[i - 1] * Y % P;
	}
	build(nc = 1, 1, n);
	while (m--) {
		scanf("%d%d%d", &x, &y, &z);
		if (x == 2)
			printf("%lld\n", (1ll * P + a[z] - a[y - 1] + qry(1, 1, n, y, z)) % P);
		else
			upd(1, 1, n, y, z, Z, P - Z);
	}
}


#include<iostream>
#include<cstdio>
using namespace std;
#define mid ((l+r)>>1)
typedef long long ll;
const int maxn=6e5+10;
const int p=1e9+9;

ll fr[maxn],fib[maxn],sum[maxn];

struct ms {
	ll a,b;
	ms() {a=b=0;}
	ms(ll x,ll y):a(x),b(y) {}
	ms operator +(const ms &y) {
		return ms((a+y.a)%p,(b+y.b)%p);
	}
	ms operator +(const int &y) {
		return ms((fib[y-1]*a%p+fib[y]*b%p)%p,(fib[y]*a%p+fib[y+1]*b%p)%p);
	}
} tag[maxn];

int n,m,a[maxn],lson[maxn],rson[maxn],ttop=1;

ll getsum(ms ysj,int sjb) {
	if(sjb==1) return ysj.a;
	return ((fr[sjb-2]+1)*ysj.a%p+fr[sjb-1]*ysj.b%p)%p;
}

void pushdown(int t0,int l,int r) {
	if(!tag[t0].a&&!tag[t0].b) return ;
	tag[lson[t0]]=tag[lson[t0]]+tag[t0];
	tag[rson[t0]]=tag[rson[t0]]+(tag[t0]+(mid-l+1));
	sum[lson[t0]]=(sum[lson[t0]]+getsum(tag[t0],mid-l+1))%p;
 	sum[rson[t0]]=(sum[rson[t0]]+getsum(tag[t0]+(mid-l+1),r-mid))%p;
	tag[t0].a=tag[t0].b=0;
	return ;
}

void update(int t0,int l,int r,int l0,int r0) {
	if(l>=l0&&r<=r0) {
		tag[t0]=tag[t0]+ms(fib[l-l0+1],fib[l-l0+2]);
		sum[t0]=(sum[t0]+fr[r-l0+1]-fr[l-l0]+p)%p;
		return ;
	}
	pushdown(t0,l,r);
	if(l0<=mid) update(lson[t0],l,mid,l0,r0);
	if(r0>mid) update(rson[t0],mid+1,r,l0,r0);
	sum[t0]=(sum[lson[t0]]+sum[rson[t0]])%p;
	return ;
}

ll query(int t0,int l,int r,int l0,int r0) {
	if(l>=l0&&r<=r0) return sum[t0];
	pushdown(t0,l,r);
	ll res=0;
	if(l0<=mid) res=(res+query(lson[t0],l,mid,l0,r0))%p;
	if(r0>mid) res=(res+query(rson[t0],mid+1,r,l0,r0))%p;
	return res;
}

void build(int t0,int l,int r) {
	if(l==r) {sum[t0]=a[l];return ;}
	lson[t0]=++ttop;
	rson[t0]=++ttop;
	build(lson[t0],l,mid);
	build(rson[t0],mid+1,r);
	sum[t0]=(sum[lson[t0]]+sum[rson[t0]])%p;
	return ;
}

int main() {
	scanf("%d%d",&n,&m);
	fib[1]=fib[2]=1;
	for(int i=3;i<=n;i++) fib[i]=(fib[i-1]+fib[i-2])%p;
	for(int i=1;i<=n;i++) fr[i]=(fr[i-1]+fib[i])%p;
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	build(1,1,n);
	for(int i=0,op,l,r;i<m;i++) {
		scanf("%d%d%d",&op,&l,&r);if(l>r) swap(l,r);
		if(op==1) update(1,1,n,l,r);
		else printf("%I64d\n",query(1,1,n,l,r));
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#define int long long
using namespace std;
inline int read()
{
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	return x*f;
}
int n,m;
const int N = 310000;
const int mod = 1e9 + 9;
int tr[N << 2],tag[N << 2][2];
int sum[N],f[N << 1];

void update(int k){tr[k] = (tr[k << 1] + tr[k << 1 | 1]) % mod;}

void down(int k,int l,int r)
{
	int mid = (l + r) >> 1;

	int x = (tag[k][0] * f[mid - l] % mod + tag[k][1] * f[mid - l + 1] % mod) % mod;
	int y = (tag[k][0] * f[mid - l + 1] % mod + tag[k][1] * f[mid - l + 2] % mod) % mod;

	tag[k << 1][0] = (tag[k << 1][0] + tag[k][0]) % mod;
	tag[k << 1 | 1][0] = (tag[k << 1 | 1][0] + x) % mod;

	tag[k << 1][1] = (tag[k << 1][1] + tag[k][1]) % mod;
	tag[k << 1 | 1][1] = (tag[k << 1 | 1][1] + y) % mod;

	tr[k << 1] = ((tr[k << 1] + tag[k][0] * f[mid - l + 1] % mod + tag[k][1] * f[mid - l + 2] % mod) % mod - tag[k][1] + mod) % mod;
	tr[k << 1 | 1] = ((tr[k << 1 | 1] + x * f[r - mid] + y * f[r - mid + 1]) % mod - y + mod) % mod;
	tag[k][0] = tag[k][1] = 0;
}

void change(int k,int l,int r,int x,int y,int v)
{
	if(x <= l && y >= r)
	{
		int len = r - l + 1;
		tag[k][0] = (tag[k][0] + f[l - x + v]) % mod;
		tag[k][1] = (tag[k][1] + f[l - x + v + 1]) % mod;
		tr[k] = ((tr[k] + f[l - x + v] * f[len] % mod + f[l - x + v + 1] * f[len + 1] % mod - f[l - x + v + 1]) % mod + mod) % mod;
		return;
	}
	int mid = (l + r) >> 1;
	if(tag[k][0] || tag[k][1]) down(k,l,r);
	if(x <= mid)	change(k << 1,l,mid,x,y,v);
	if(y > mid) 	change(k << 1 | 1,mid + 1,r,x,y,v);
	update(k);
	return;
}

int ask(int k,int l,int r,int x,int y)
{
	if(x <= l && y >= r) return tr[k];
	int mid = (l + r) >> 1,ans = 0;
	if(tag[k][0] || tag[k][1]) down(k,l,r);
	if(x <= mid) ans = (ans + ask(k << 1,l,mid,x,y)) % mod;
	if(y > mid)	 ans = (ans + ask(k << 1 | 1,mid + 1,r,x,y)) % mod;
	return ans;
}

signed main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	n = read();m = read();
	f[1] = f[2] = 1;
	for(int i = 3;i <= (n << 1);i ++) f[i] = (f[i - 1] + f[i - 2]) % mod;
	for(int i = 1;i <= n;i ++) sum[i] = (sum[i - 1] + read())  % mod;
	int opt,l,r,x = 1;
	while(m --)
	{
		opt = read();l = read();r = read();
		if(opt == 1)
		{
//			x = read();
			change(1,1,n,l,r,x);
		}
		else
		{
			printf("%lld\n",(sum[r] - sum[l - 1] + ask(1,1,n,l,r)) % mod);
		}
	}
//	fclose(stdin);fclose(stdout);
	return 0;
}
/*
1049358504
1000000009
49358495
*/


#include<bits/stdc++.h>
#define ls p<<1
#define rs p<<1|1
using namespace std;
typedef long long ll;
const int mxn=3e5+5,mod=1e9+9;
struct T { ll x,y; };
int n,m;
int f[mxn],a[mxn],val[mxn<<2];
ll tag[mxn<<2][2],t[mxn<<2];

inline int read()
{
	char c=getchar(); int x=0,f=1;
	while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
	while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
	return x*f;
}

inline void push_up(int p)
{
	t[p]=(t[ls]+t[rs])%mod;
}

inline ll cal(ll x,ll y,int len)
{
	ll res=0;
	if(len>=1) res=(res+x)%mod;
	if(len>=2) res=(res+y)%mod;
	if(len>=3) res=(res+y*(f[len+1]-2)%mod+x*(f[len]-1)%mod)%mod;
	return res;
}
T fibcal(T tp,int len)
{
	ll c=tp.x*f[len]%mod+tp.y*f[len+1]%mod,
	   d=tp.x*f[len+1]%mod+tp.y*f[len+2]%mod;
	return (T){ c%mod,d%mod };
}

void build(int l,int r,int p)
{
	if(l==r) {
		t[p]=a[l];
		return ;
	}
	int mid=(l+r)>>1;
	build(l,mid,ls);
	build(mid+1,r,rs);
	push_up(p);
}

void push_down(int l,int r,int p)
{
	if(val[p]) {
		int mid=(l+r)>>1;

		ll x=tag[p][0],y=tag[p][1];
		tag[ls][0]=(tag[ls][0]+x)%mod;
		tag[ls][1]=(tag[ls][1]+y)%mod;
		t[ls]=(t[ls]+cal(x,y,mid-l+1))%mod;
		val[ls]=1;

		ll c=(x*f[mid-l]%mod+y*f[mid-l+1]%mod)%mod,
		   d=(x*f[mid-l+1]%mod+y*f[mid-l+2]%mod)%mod;
		tag[rs][0]=(tag[rs][0]+c)%mod;
		tag[rs][1]=(tag[rs][1]+d)%mod;
		t[rs]=(t[rs]+cal(c,d,r-mid))%mod;
		val[rs]=1;

		tag[p][0]=tag[p][1]=0; val[p]=0;
	}
}

void update(int l,int r,int ql,int qr,int x,int y,int p)
{
	if(ql<=l&&r<=qr) {
		tag[p][0]=(tag[p][0]+x)%mod;
		tag[p][1]=(tag[p][1]+y)%mod;
		t[p]=(t[p]+cal(x,y,r-l+1));
		val[p]=1; return ;
	}
	int mid=(l+r)>>1; push_down(l,r,p);
	if(qr<=mid) update(l,mid,ql,qr,x,y,ls);
	else if(mid+1<=ql) update(mid+1,r,ql,qr,x,y,rs);
	else {
		update(l,mid,ql,qr,x,y,ls);
		T tp=fibcal((T){x,y},mid-ql);
		update(mid+1,r,ql,qr,tp.x,tp.y,rs);
	}
	push_up(p);
}

int query(int l,int r,int ql,int qr,int p)
{
	if(ql<=l&&r<=qr) return t[p]; int ans=0;
	int mid=(l+r)>>1; push_down(l,r,p);
	if(ql<=mid) ans=(ans+query(l,mid,ql,qr,ls))%mod;
	if(qr>mid) ans=(ans+query(mid+1,r,ql,qr,rs))%mod;
	return ans;
}

int main()
{
	n=read(); m=read(); f[1]=f[2]=1;
	for(int i=3;i<mxn;++i) f[i]=(f[i-1]+f[i-2])%mod;
	for(int i=1;i<=n;++i) a[i]=read()%mod;
	build(1,n,1); int opt,l,r;
	for(int i=1;i<=m;++i) {
		opt=read(); l=read(); r=read();
		if(opt==1) update(1,n,l,r,1,1,1);
		else printf("%d\n",query(1,n,l,r,1));
	}
}


#include<bits/stdc++.h>
#define mod 1000000009
#define five 383008016
#define five1 691504013
#define five2 308495997
using namespace std;
int n,m;
long long a[300005];
int op,L,R;

int sqrtn;
int bl[300005];//block
int l[1005],r[1005],tt;
int siz[1005];//size
long long lazy1[1005],lazy2[1005];
long long sum[1005];

long long f[300005];
long long fs[300005];
inline void init()
{
	f[1]=f[2]=1;
	for(int i=3;i<=300000;i++) f[i]=(f[i-1]+f[i-2])%mod;
	for(int i=1;i<=300000;i++) fs[i]=(fs[i-1]+f[i])%mod;
}

inline void inblock()
{
	for(int i=1;i<=n/sqrtn;i++)
	{
		tt++;
		l[tt]=r[tt-1]+1;
		r[tt]=r[tt-1]+sqrtn;
		siz[tt]=r[tt]-l[tt]+1;
		for(int j=l[tt];j<=r[tt];j++) bl[j]=tt;
	}
	if(sqrtn*sqrtn!=n)
	{
		tt++;l[tt]=r[tt-1]+1;r[tt]=n;siz[tt]=r[tt]-l[tt]+1;
		for(int j=l[tt];j<=r[tt];j++) bl[j]=tt;
	}
}

long long mi(long long n,long long p)
{
	if(n==0) return 0;
    if(p==0) return 1;
	long long yuan=1,mul=n;
	while(p)
    {
        if(p&1) yuan*=mul;
        yuan%=mod;
        mul*=mul;
        mul%=mod;
        p>>=1;
    }
    return yuan%mod;
}

inline void insert()
{
	if(bl[L]==bl[R])
	{
		int tot=1;
		for(int i=L;i<=R;i++)
		{
			a[i]+=f[tot]%mod; a[i]%=mod;
			tot++;
		}
		sum[bl[L]]+=fs[tot]%mod; sum[bl[L]]%=mod;
		return ;
	}

	int tot=1;
	for(int i=L;i<=r[bl[L]];i++)
	{
		a[i]+=f[tot]%mod; a[i]%=mod;
		sum[bl[L]]+=f[tot]%mod; sum[bl[L]]%=mod;
		tot++;
	}
	for(int i=bl[L]+1;i<bl[R];i++)
	{
		lazy1[i]+=mi(five1,tot)%mod;
		lazy2[i]+=mi(five2,tot)%mod;
		sum[i]+=fs[tot+siz[i]-1]-fs[tot-1]; sum[i]%=mod;
		tot+=siz[i];
	}
	for(int i=l[bl[R]];i<=R;i++)
	{
		a[i]+=f[tot]%mod; a[i]%=mod;
		sum[bl[R]]+=f[tot]%mod; sum[bl[R]]%=mod;
		tot++;
	}
}

inline void push_down()
{
	if(lazy1[bl[L]]!=0 || lazy2[bl[L]]!=0)
	{
		int tot=0;
		for(int i=L;i<=r[bl[L]];i++)
		{
			a[i]+=lazy1[bl[L]]*mi(five1,tot)%mod*mi(five,mod-2)%mod;
			a[i]-=lazy2[bl[L]]*mi(five2,tot)%mod*mi(five,mod-2)%mod;
			tot++;
		}
		lazy1[bl[L]]=lazy2[bl[L]]=0;
	}
	if(lazy1[bl[R]]!=0 || lazy2[bl[R]]!=0)
	{
		int tot=1;
		for(int i=l[bl[R]];i<=R;i++)
		{
			a[i]+=lazy1[bl[R]]*mi(five1,tot)%mod*mi(five,mod-2)%mod;
			a[i]-=lazy2[bl[R]]*mi(five2,tot)%mod*mi(five,mod-2)%mod;
			tot++;
		}
		lazy1[bl[R]]=lazy2[bl[R]]=0;
	}
}

inline void ask()
{
	long long anss=0;
	push_down();

	if(bl[L]==bl[R])
	{
		for(int i=L;i<=R;i++)
		{
			anss+=a[i]%mod;
			anss%=mod;
		}
		cout<<anss<<endl;
		return ;
	}

	for(int i=L;i<=r[bl[L]];i++)
	{
		anss+=a[i]%mod;
		anss%=mod;
	}
	for(int i=l[bl[R]];i<=R;i++)
	{
		anss+=a[i]%mod;
		anss%=mod;
	}
	for(int i=bl[L]+1;i<bl[R];i++)
	{
		anss+=sum[i]%mod;
		anss%=mod;
	}
	cout<<anss<<endl;
	return ;
}

int main()
{
	ios::sync_with_stdio(0);
	cin>>n>>m;
	sqrtn=pow(n,0.55);
	inblock();
	init();
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		sum[bl[i]]+=a[i];
		sum[bl[i]]%=mod;
	}

	while(m--)
	{
		cin>>op>>L>>R;
		if(op==1)
		{
			insert();
		}
		else
		{
			ask();
		}
	}
}


#include<bits/stdc++.h>
#define mod 1000000009
#define five 383008016
#define inv5 276601605
#define five1 691504013
#define five2 308495997
using namespace std;
int n,m;
long long a[300005];
int op,L,R;

int sqrtn;
int bl[300005];//block
int l[10005],r[10005],tt;
int siz[10005];//size
long long lazy1[10005],lazy2[10005];
long long sum[10005];

long long mi(long long n,long long p)
{
    if(n==0) return 0;
    if(p==0) return 1;
    long long yuan=1,mul=n;
    while(p)
    {
        if(p&1) yuan*=mul;
        yuan%=mod;
        mul*=mul;
        mul%=mod;
        p>>=1;
    }
    return yuan%mod;
}

long long f[300005];
long long fs[300005];
long long m1[300005],m2[300005];
inline void init()
{
    f[1]=f[2]=1;
    for(int i=3;i<=300000;i++) f[i]=(f[i-1]+f[i-2])%mod;
    for(int i=1;i<=300000;i++) fs[i]=(fs[i-1]+f[i])%mod;
    m1[0]=m2[0]=1;
    for(int i=1;i<=n;i++)
    {
        m1[i]=m1[i-1]*(five+1)%mod*mi(2,mod-2)%mod;
        m2[i]=m2[i-1]*(1-five+mod)%mod*mi(2,mod-2)%mod;
    }
}

inline void inblock()
{
    for(int i=1;i<=n/sqrtn;i++)
    {
        tt++;
        l[tt]=r[tt-1]+1;
        r[tt]=r[tt-1]+sqrtn;
        siz[tt]=r[tt]-l[tt]+1;
        for(int j=l[tt];j<=r[tt];j++) bl[j]=tt;
    }
    if(sqrtn*sqrtn!=n)
    {
        tt++;l[tt]=r[tt-1]+1;r[tt]=n;siz[tt]=r[tt]-l[tt]+1;
        for(int j=l[tt];j<=r[tt];j++) bl[j]=tt;
    }
}

inline void push_down()
{
    if(lazy1[bl[L]]!=0 || lazy2[bl[L]]!=0)
    {
        int tot=0;
        for(int i=l[bl[L]];i<=r[bl[L]];i++)
        {
            a[i]+=lazy1[bl[L]]*m1[tot]%mod*inv5%mod;
            a[i]-=lazy2[bl[L]]*m2[tot]%mod*inv5%mod;
            a[i]%=mod;
            tot++;
        }
        lazy1[bl[L]]=lazy2[bl[L]]=0;
    }
    if(lazy1[bl[R]]!=0 || lazy2[bl[R]]!=0)
    {
        int tot=0;
        for(int i=l[bl[R]];i<=r[bl[R]];i++)
        {
            a[i]+=lazy1[bl[R]]*m1[tot]%mod*inv5%mod;
            a[i]-=lazy2[bl[R]]*m2[tot]%mod*inv5%mod;
            a[i]%=mod;
            tot++;
        }
        lazy1[bl[R]]=lazy2[bl[R]]=0;
    }
//  cout<<"pushed:"<<endl;
//  for(int i=1;i<=n;i++) cout<<a[i]<<" "; cout<<endl;
}

inline void insert()
{
    push_down();
    if(bl[L]==bl[R])
    {
        int tot=1;
        for(int i=L;i<=R;i++)
        {
            a[i]+=f[tot]%mod; a[i]%=mod;
            tot++;
        }
        sum[bl[L]]+=fs[tot-1]%mod; sum[bl[L]]%=mod;
        return ;
    }

    int tot=1;
    for(int i=L;i<=r[bl[L]];i++)
    {
        a[i]+=f[tot]%mod; a[i]%=mod;
        sum[bl[L]]+=f[tot]%mod; sum[bl[L]]%=mod;
        tot++;
    }
    for(int i=bl[L]+1;i<bl[R];i++)
    {
        lazy1[i]+=m1[tot]%mod; lazy1[i]%=mod;
        lazy2[i]+=m2[tot]%mod; lazy2[i]%=mod;
        sum[i]+=fs[tot+siz[i]-1]-fs[tot-1]; sum[i]%=mod;
        tot+=siz[i];
    }
    for(int i=l[bl[R]];i<=R;i++)
    {
        a[i]+=f[tot]%mod; a[i]%=mod;
        sum[bl[R]]+=f[tot]%mod; sum[bl[R]]%=mod;
        tot++;
    }
}

inline void ask()
{
    long long anss=0;
    push_down();

    if(bl[L]==bl[R])
    {
        for(int i=L;i<=R;i++)
        {
            anss+=a[i]%mod;
            anss%=mod;
        }
        cout<<(anss%mod+mod)%mod<<endl;
        return ;
    }

    for(int i=L;i<=r[bl[L]];i++)
    {
        anss+=a[i]%mod;
        anss%=mod;
    }
    for(int i=l[bl[R]];i<=R;i++)
    {
        anss+=a[i]%mod;
        anss%=mod;
    }
    for(int i=bl[L]+1;i<bl[R];i++)
    {
        anss+=sum[i]%mod;
        anss%=mod;
    }
    cout<<(anss%mod+mod)%mod<<endl;
    return ;
}

int main()
{
//  freopen("rd.in","r",stdin);
//  freopen("my.out","w",stdout);
    ios::sync_with_stdio(0);
    cin>>n>>m;
    sqrtn=pow(n,0.33);
    inblock();
    init();
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        sum[bl[i]]+=a[i];
        sum[bl[i]]%=mod;
    }

//  for(int i=1;i<=n;i++) cout<<bl[i]<<" "; cout<<endl;
//  for(int i=1;i<=tt;i++) cout<<sum[i]<<" "; cout<<endl;
//  cout<<endl;
    while(m--)
    {
        cin>>op>>L>>R;
        if(op==1)
        {
            insert();
//          cout<<endl;
//          for(int i=1;i<=n;i++) cout<<a[i]<<" "; cout<<endl;
//          for(int i=1;i<=tt;i++) cout<<sum[i]<<" "; cout<<endl;
//          cout<<endl;
        }
        else
        {
            ask();
        }
    }
}


#include<bits/stdc++.h>
using namespace std;
#define N 300000
const long long P=1000000009;

int Fibo[N+9];

void prework()
{
	Fibo[1]=1,Fibo[2]=1;
	for(int i=3;i<=N;i++) Fibo[i]=(Fibo[i-2]+Fibo[i-1])%P;
}

long long f(long long f1,long long f2,int x)
{
	return (f1*Fibo[x]+f2*(Fibo[x+1]-1))%P;
}

struct seg_tree{
	int l,r;
	long long f1,f2,sum;
} t[N*5];

int n,m;
long long x,a[N+9];

void build(int l,int r,int id)
{
	t[id].l=l,t[id].r=r,t[id].f1=0,t[id].f2=0,t[id].sum=0;
	int mid=(l+r)>>1;
	if(l!=r) build(l,mid,id<<1),build(mid+1,r,id<<1|1);
}

void pushdown(int id)
{
	int ll=id<<1,rr=id<<1|1;
	int lpos=t[id].l,midpos=(t[id].l+t[id].r)>>1l,rpos=t[id].r;
	t[ll].f1=(t[ll].f1+t[id].f1)%P,t[ll].f2=(t[ll].f2+t[id].f2)%P,
	t[ll].sum=(t[ll].sum+f(t[id].f1,t[id].f2,midpos-lpos+1))%P;
	long long tmp1=f(t[id].f1,t[id].f2,midpos-lpos+2)-f(t[id].f1,t[id].f2,midpos-lpos+1);
	long long tmp2=f(t[id].f1,t[id].f2,midpos-lpos+3)-f(t[id].f1,t[id].f2,midpos-lpos+2);
	t[rr].f1=(t[rr].f1+tmp1)%P,
	t[rr].f2=(t[rr].f2+tmp2)%P,
	t[rr].sum=(t[rr].sum+f(tmp1,tmp2,rpos-midpos+1));
	t[id].f1=0,t[id].f2=0;
}

void modify(int x,int l,int r,int id)
{
	if(l==t[id].l && r==t[id].r)
	{
		t[id].f1=(t[id].f1+x)%P,t[id].f2=(t[id].f2+x)%P;
		t[id].sum=(t[id].sum+f(Fibo[x],Fibo[x+1],r-l+1))%P;
		return ;
	}
	pushdown(id);
	if(r<=t[id<<1].r) modify(x,l,r,id<<1);
	else if(l>=t[id<<1|1].l) modify(x,l,r,id<<1|1);
	else
		modify(x,l,t[id<<1].r,id<<1),
		modify(x+t[id<<1|1].l-l,t[id<<1|1].l,r,id<<1|1);
}

long long query(int l,int r,int id)
{
	if(l==t[id].l && r==t[id].r) return t[id].sum;
	pushdown(id);
	if(r<=t[id<<1].r) return query(l,r,id<<1);
	if(l>=t[id<<1|1].l) return query(l,r,id<<1|1);
	return (query(l,t[id<<1].r,id<<1)+query(t[id<<1|1].l,r,id<<1|1))%P;
}

int main()
{
	prework();
	scanf("%d%d",&n,&m),a[0]=0;
	for(int i=1;i<=n;i++) scanf("%lld",&x),a[i]=(a[i-1]+x)%P;
	build(1,n,1);
	while(m--)
	{
		int opt,l,r;
		scanf("%d%d%d",&opt,&l,&r);
		if(opt==1) modify(1,l,r,1);
		else
		{
			long long res=query(l,r,1);
			printf("%lld\n",(a[r]-a[l-1]+res)%P);
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll rd(){
    ll x=0;char o,f=1;
    while(o=getchar(),o<48)if(o==45)f=-f;
    do x=(x<<3)+(x<<1)+(o^48);
    while(o=getchar(),o>47);
    return x*f;
}
const int maxn=3e5+5;
const ll mod=1e9+9;
ll n,m,op,l,r,a[maxn],val[maxn<<2];
ll lazy1[maxn<<2],lazy2[maxn<<2];
ll f[maxn],pre[maxn];
void presolve(){
    f[1]=f[2]=1;
    for (int i=3;i<=300002;i++)f[i]=(f[i-1]+f[i-2])%mod;
    for (int i=1;i<=300002;i++)pre[i]=(pre[i-1]+f[i])%mod;
}
void pushup(int p){
    val[p]=(val[p<<1]+val[p<<1|1])%mod;
}
void pushdown(int p,int l,int r){
    int mid=(l+r)>>1;
    ll a=lazy1[p],b=lazy2[p];
    lazy1[p<<1]=(lazy1[p<<1]+a)%mod;
    lazy2[p<<1]=(lazy2[p<<1]+b)%mod;
    val[p<<1]=(val[p<<1]+a*f[mid-l+1]+b*f[mid-l+2]-b+mod)%mod;
    val[p<<1|1]=(val[p<<1|1]+a*f[r-l+1]+b*f[r-l+2]-b-(a*f[mid-l+1]+b*f[mid-l+2]-b)%mod+mod*2)%mod;
    ll cnt1=(a*f[mid-l]+b*f[mid-l+1])%mod,cnt2=(a*f[mid-l+1]+b*f[mid-l+2])%mod;
    lazy1[p<<1|1]=(lazy1[p<<1|1]+cnt1)%mod;
    lazy2[p<<1|1]=(lazy2[p<<1|1]+cnt2)%mod;
    lazy1[p]=lazy2[p]=0;
}
void build(int l=1,int r=n,int p=1){
    if (l==r){
        val[p]=a[l];
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,p<<1);
    build(mid+1,r,p<<1|1);
    pushup(p);
}
void update(int a,int b,int l=1,int r=n,int p=1){
    if (a>r||b<l)return;
    if (a<=l&&b>=r){
        int s=l-a+1,e=r-a+1;
        val[p]=(val[p]+pre[e]-pre[s-1]+mod)%mod;
        lazy1[p]=(lazy1[p]+f[s])%mod;
        lazy2[p]=(lazy2[p]+f[s+1])%mod;
        return;
    }
    int mid=(l+r)>>1;
    pushdown(p,l,r);
    update(a,b,l,mid,p<<1);
    update(a,b,mid+1,r,p<<1|1);
    pushup(p);
}
ll query(int a,int b,int l=1,int r=n,int p=1){
    if (a>r||b<l)return 0;
    if (a<=l&&b>=r)return val[p];
    int mid=(l+r)>>1;
    pushdown(p,l,r);
    return (query(a,b,l,mid,p<<1)+query(a,b,mid+1,r,p<<1|1))%mod;
}
int main() {
    presolve();
    n=rd();m=rd();
    for (int i=1;i<=n;i++)a[i]=rd();
    build();
    while (m--){
        op=rd();l=rd();r=rd();
        if (op==1){
            update(l,r);
        }
        else{
            printf("%lld\n",query(l,r));
        }
    }
    return 0;
}


// luogu-judger-enable-o2
#include<bits/stdc++.h>
typedef __int128 LL;
const LL mod=1e9+9;
using namespace std;
inline int lowbit(int i)
{
    return i&-i;
}
template<typename T>inline void read(T&x)
{
    T ll=1;
    T res=0;
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch=='-')
        ll=-1;
        ch=getchar();
    }
    while(isdigit(ch))
    res=(res<<3)+(res<<1)+ch-'0',ch=getchar();
    x=res*ll;
}
template<typename T>void print(T x)
{
    if(x<0)putchar('-'),x=-x;
    if(x<10)
    putchar(x+'0');
    else
    {
        print(x/10);
        putchar(x%10+'0');
    }
}
int n;
int q;
LL a[500001],c[500001];
inline void change(LL i,LL delta)
{
    while(i<=n)
    {
        c[i]+=delta;
        c[i]%=mod;
        i+=lowbit(i);
    }
}
inline LL get(LL i)
{
    LL sum=0;
    while(i>0)
    {
        sum+=c[i];
        sum%=mod;
        i-=lowbit(i);
    }
    return sum;
}
inline LL get(LL l,LL r)
{
    return get(r)-get(l-1);
}
int main()
{
    read(n),read(q);
    LL f[n];
    f[1]=f[2]=1;
    for(int i=3;i<=n;i++)
    {
    	f[i]=(f[i-1]+f[i-2])%mod;
    }
    for(int i=1;i<=n;i++)
    {
        read(a[i]);
        change(i,a[i]);
    }
    int opt,x,y;
    while(q--)
    {
        read(opt),read(x),read(y);
        if(opt==1)
        {
        	for(int i=x;i<=y;i++)
        	{
        		change(i,f[i-x+1]);
            }
        }
        else
        print(get(x,y)%mod),puts("");
    }
    return 0;
}


#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

#define R register
#define LL long long
const int MAXN=3e5+10;
const int Mod=1e9+9;

inline int read() {
	int x=0,f=1; char a=getchar();
	for(;a>'9'||a<'0';a=getchar()) if(a=='-') f=-1;
	for(;a>='0'&&a<='9';a=getchar()) x=x*10+a-'0';
	return x*f;
}

inline int add(int x,int y) {
	int res=x+y;
	if(res<0) res+=Mod;
	return res>=Mod?res-Mod:res;
}

int n,m;
int f[MAXN];
inline int Fib(int x,int y,int id) {
	if(id==1) return x;
	if(id==2) return y;
	return (1LL*f[id-2]*x+1LL*f[id-1]*y)%Mod;
}
inline int Fibsum(int x,int y,int id) {
	if(id==1) return x;
	if(id==2) return add(x,y);
	return add(Fib(x,y,id+2),-Fib(x,y,2));
}

#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
struct Node {
	int v1,v2,sum;
}t[MAXN<<2];
#define v1(x) t[x].v1
#define v2(x) t[x].v2
#define sum(x) t[x].sum

inline void update(int x) { sum(x)=add(sum(ls(x)),sum(rs(x))); }

inline void get(int x,int a,int b,int l,int r) {
	v1(x)=add(a,v1(x)); v2(x)=add(b,v2(x));
	sum(x)=add(Fibsum(a,b,r-l+1),sum(x));
	//printf("%d\n",Fib(1,1,6));
	//printf("%d %d %d %d %d\n",x,a,b,l,r);
}

inline void pushdown(int x,int l,int r) {
	if(v1(x)) {
		int mid=((l+r)>>1);
		get(ls(x),v1(x),v2(x),l,mid);
		int a=Fib(v1(x),v2(x),mid-l+2),
			b=Fib(v1(x),v2(x),mid-l+3);
		get(rs(x),a,b,mid+1,r);
		v1(x)=v2(x)=0;
	}
}
inline void change(int x,int l,int r,int Le,int Ri) {
	if(l>=Le&&r<=Ri) {
		//printf("%d %d %d\n",x,f[l-Le+1],f[l-Le+2]);
		get(x,f[l-Le+1],f[l-Le+2],l,r);
		return ;
	}
	pushdown(x,l,r);
	int mid=l+r; mid>>=1;
	if(Le<=mid) change(ls(x),l,mid,Le,Ri);
	if(Ri>mid) change(rs(x),mid+1,r,Le,Ri);
	update(x);
}
inline int ask(int x,int l,int r,int Le,int Ri) {
	if(l>=Le&&r<=Ri) return sum(x);
	pushdown(x,l,r);
	int mid=l+r;mid>>=1; int ans=0;
	if(Le<=mid) ans=add(ans,ask(ls(x),l,mid,Le,Ri));
	if(Ri>mid) ans=add(ans,ask(rs(x),mid+1,r,Le,Ri));
	update(x); return ans;
}
int sm[MAXN];
int main() {
//	freopen("a.in","r",stdin);
//	freopen("a.out","w",stdout);
	n=read(); m=read();
	f[1]=f[2]=1;
	for(R int i=3;i<=n+3;i++) f[i]=add(f[i-1],f[i-2]);
	for(R int i=1;i<=n;i++) sm[i]=add(sm[i-1],read());
	//for(R int i=1;i<=n;i++) printf("%d\n",sm[i]);
	while(m--) {
		if(read()==1) {
			int x=read(),y=read();
			change(1,1,n,x,y);
		}
		else {
			int x=read(),y=read();
			printf("%d\n",add(ask(1,1,n,x,y),sm[y]-sm[x-1]));
		}
	}
	return 0;
}


#include<cstdio>
#include<iostream>
#define int long long
using namespace std;
const int mod = 1e9 + 7;
const int N = 300005;
int n,m;
long long f[N << 1],a[N],sum[N];
struct node{
	long long f1,f2,v;
	node(long long f1 = 0,long long f2 = 0,long long v = 0):f1(f1),f2(f2),v(v){};
}tr[N << 4];
void init()
{
	f[0] = 0;f[1] = 1;
	for(int i = 2;i <= 300000;i ++)	f[i] = (f[i - 1] + f[i - 2]) % mod;
}/*
void update(int k,int len)
{
	tr[k].f1 %= mod;	tr[k].f2 %= mod;
	tr[k].v = (((tr[k << 1].v + tr[k << 1 | 1].v) % mod + tr[k].f1 * f[len] % mod + tr[k].f2 * f[len + 1] % mod - tr[k].f2) % mod + mod) % mod;
}*//*
void down(int k,int l,int r)
{
	cout << k << endl;
	if(tr[k].f1 == 0 && tr[k].f2 == 0)	return;
	int mid = (l + r) >> 1;
	tr[k << 1].f1 += tr[k].f1;	tr[k << 1].f2 += tr[k].f2;
	tr[k << 1 | 1].f1 += (tr[k].f1 * f[mid - l] % mod + tr[k].f2 * f[mid - l + 1] % mod) % mod;
	tr[k << 1 | 1].f2 += (tr[k].f1 * f[mid - l + 1] % mod + tr[k].f2 * f[mid - l + 2] % mod) % mod;
	tr[k].f1 = tr[k].f2 = 0;
	update(k << 1,mid - l + 1);	update(k << 1 | 1,r - mid);
}*/
void update(int rt,int pos)
{
	int ls = (rt << 1),rs = (rt << 1 | 1);
    tr[rt].f1%=mod,tr[rt].f2%=mod;
    tr[rt].v=tr[ls].v+tr[rs].v+(tr[rt].f1*f[pos]+tr[rt].f2*f[pos+1]-tr[rt].f2),tr[rt].v%=mod;
//    cout <<t[ls].v << " " << t[rs].v << endl;
}
void down(int rt,int l,int r)
{
    if(tr[rt].f1==0&&tr[rt].f2==0)return ;
    int mid=(l+r)>>1;	int ls = (rt << 1),rs = (rt << 1 | 1);
    tr[ls].f1+=tr[rt].f1,tr[rs].f1+=tr[rt].f1*f[mid-l]+tr[rt].f2*f[mid-l+1];
    tr[ls].f2+=tr[rt].f2,tr[rs].f2+=tr[rt].f1*f[mid-l+1]+tr[rt].f2*f[mid-l+2];
    tr[rt].f1=tr[rt].f2=0;
    update(ls,mid-l+1),update(rs,r-mid);
}/*
long long ask(int k,int l,int r,int x,int y)
{
	if(x <= l && r <= y)	return tr[k].v %= mod;
	down(k,l,r);
	int mid = (l + r) >> 1;
	long long ans = 0;
	if(x <= mid)	ans = (ans + ask(k << 1,l,mid,x,y)) % mod;
	if(y > mid)		ans = (ans + ask(k << 1 | 1,mid + 1,r,x,y)) % mod;
	return ans;
}*/
int ask(int rt,int l,int r,int L,int R)
{
    if(L<=l&&r<=R)return tr[rt].v;
    down(rt,l,r);
    int res=0;
    int mid=(l+r)>>1;
    if(L<=mid)res+=ask(rt << 1,l,mid,L,R);
    if(mid<R)res+=ask(rt << 1 | 1,mid+1,r,L,R);
    return res%mod;
}/*
void change(int k,int l,int r,int x,int y,int em)
{
	if(x <= l && r <= y)
	{
		tr[k].f1 = (tr[k].f1 + f[em + l - x + 1]) % mod;
		tr[k].f2 = (tr[k].f2 + f[em + l - x + 2]) % mod;
		update(k,r - l + 1);
		return;
	}
	down(k,l,r);
	int mid = (l + r) >> 1;
	if(x <= mid)	change(k << 1,l,mid,x,y,em);
	if(y > mid)		change(k << 1 | 1,mid + 1,r,x,y,em);
	update(k,r - l + 1);
}*//*
signed main()
{
//	freopen("d.in","r",stdin);
//	freopen("d.out","w",stdout);
	init();
	scanf("%lld%lld",&n,&m);
	for(int i = 1;i <= n;i ++)
	{
		scanf("%lld",&a[i]);
		a[i] %= mod;
	}
	for(int i = 1;i <= n;i ++)	sum[i] = ((sum[i - 1] + a[i]) % mod + mod) % mod;

	for(int i = 1,opt,l,r,x;i <= m;i ++)
	{
		scanf("%lld%lld%lld",&opt,&l,&r);
		if(opt == 2)	printf("%lld\n",((ask(1,1,n,l,r) + sum[r] - sum[l - 1]) % mod + mod) % mod);
		else
		{
//			scanf("%d",&x);
			change(1,1,n,l,r,0);
		}
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}*/
void change(int rt,int l,int r,int L,int R)
{
    if(L<=l&&r<=R)//边界条件
    {
        tr[rt].f1+=f[l-L+1];
        tr[rt].f2+=f[l-L+2];
        tr[rt].f1%=mod,tr[rt].f2%=mod;
        update(rt,r-l+1);
        return ;
    }
    down(rt,l,r);
    int mid=(l+r)>>1,ls = (rt << 1),rs = (rt << 1 | 1);
    if(L<=mid)change(ls,l,mid,L,R);
    if(mid<R)change(rs,mid+1,r,L,R);
    update(rt,r-l+1);
}
signed main()
{
    scanf("%lld%lld",&n,&m);
    init();
    for(int i=1;i<=n;i++)scanf("%lld",&a[i]),sum[i]=sum[i-1]+a[i];//预处理前缀和

    while(m--)
    {
        int opt,l,r;
        scanf("%lld%lld%lld",&opt,&l,&r);
        if(opt==1)change(1,1,n,l,r);
        else printf("%lld\n",(ask(1,1,n,l,r)+sum[r]-sum[l-1]+mod)%mod);
//        for(int i = 1;i <= n * 4;i ++)	cout << t[i].f1 << " " << t[i].f2 << " " << t[i].v << endl;
    }

    return 0;
}
/*
5 3
1 2 3 4 5
1 1 5
2 1 5 2
1 1 5
*/
/*
5 3
1 2 3 4 5
1 1 5
2 1 1 2
1 1 5
*/


#include<bits/stdc++.h>
namespace my_std{
	using namespace std;
	#define pii pair<int,int>
	#define fir first
	#define sec second
	#define MP make_pair
	#define rep(i,x,y) for (int i=(x);i<=(y);i++)
	#define drep(i,x,y) for (int i=(x);i>=(y);i--)
	#define go(x) for (int i=head[x];i;i=edge[i].nxt)
	#define sz 303030
	typedef long long ll;
	const ll mod=1e9+9;
	template<typename T>
	inline void read(T& t)
	{
		t=0;char f=0,ch=getchar();
		double d=0.1;
		while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
		while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
		if(ch=='.')
		{
			ch=getchar();
			while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();
		}
		t=(f?-t:t);
	}
	template<typename T,typename... Args>
	inline void read(T& t,Args&... args){read(t); read(args...);}
	void file()
	{
		#ifndef ONLINE_JUDGE
		freopen("a.txt","r",stdin);
		#endif
	}
//	inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std;

int n,m;
int a[sz];

ll f[sz],ff[sz],F[sz];
void init()
{
	f[0]=0;F[1]=f[1]=1;
	rep(i,2,sz-1) F[i]=(F[i-1]+(f[i]=(f[i-1]+f[i-2])%mod))%mod;
	rep(i,1,sz-1) ff[i]=(i&1)?f[i]:mod-f[i];
}

ll tg1[sz<<1],tg2[sz<<1],sum[sz<<1];
#define ls k<<1
#define rs k<<1|1
#define lson k<<1,l,mid
#define rson k<<1|1,mid+1,r
#define S int k,int l,int r
#define I inline
I void Add1(S,ll s){(tg1[k]+=s)%=mod;(sum[k]+=s*(F[r]-F[l-1])%mod)%=mod;}
I void Add2(S,ll s){(tg2[k]+=s)%=mod;(sum[k]+=s*(F[r+1]-F[l])%mod)%=mod;}
I void pushdown(S)
{
	if (!(tg1[k]+tg2[k])) return;
	int mid=(l+r)>>1;
	ll &t1=tg1[k],&t2=tg2[k];
	Add1(lson,t1);Add1(rson,t1);
	Add2(lson,t2);Add2(rson,t2);
	t1=t2=0;
}
void pushup(int k){sum[k]=sum[ls]+sum[rs];}
void add(S,int x,int y,ll s1,ll s2)
{
	if (x<=l&&r<=y) return Add1(k,l,r,s1),Add2(k,l,r,s2);
	pushdown(k,l,r);
	int mid=(l+r)>>1;
	if (x<=mid) add(lson,x,y,s1,s2);
	if (y>mid) add(rson,x,y,s1,s2);
	pushup(k);
}
ll query(S,int x,int y)
{
	if (x<=l&&r<=y) return sum[k];
	pushdown(k,l,r);
	int mid=(l+r)>>1;
	ll ret=0;
	if (x<=mid) ret+=query(lson,x,y);
	if (y>mid) ret+=query(rson,x,y);
	return ret%mod;
}
void build(S)
{
	if (l==r) return (void)(sum[k]=a[l]);
	int mid=(l+r)>>1;
	build(lson);build(rson);
	pushup(k);
}

int main()
{
	file();
	int x,y,z;
	read(n,m);
	rep(i,1,n) read(a[i]);
	init();
	build(1,1,n);
	while (m--)
	{
		read(z,x,y);
		if (z==1) add(1,1,n,x,y,ff[x],ff[x-1]);
		else printf("%lld\n",query(1,1,n,x,y));
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
#define mid (l+r)/2
#define N 300300
using namespace std;
const ll mod=1e9+9;
ll n,m,fs[N*10],f[N*10],ff[N*10],t1[N*10],t2[N*10],tr[N*10],sum[N];
ll a[N];

void push(ll o,ll l,ll r){
	t1[o*2]=(t1[o*2]+t1[o])%mod;
	tr[o*2]=(tr[o*2]+((fs[mid+1]-fs[l+1-1]+mod)%mod*t1[o])%mod)%mod;
	t1[o*2+1]=(t1[o*2+1]+t1[o])%mod;
	tr[o*2+1]=(tr[o*2+1]+((fs[r+1]-fs[mid+2-1]+mod)%mod*t1[o])%mod)%mod;
	t1[o]=0;
}

void down(ll o,ll l,ll r){
	t2[o*2]=(t2[o*2]+t2[o])%mod;
	tr[o*2]=(tr[o*2]+((fs[mid]-fs[l-1]+mod)%mod*t2[o])%mod)%mod;
	t2[o*2+1]=(t2[o*2+1]+t2[o])%mod;
	tr[o*2+1]=(tr[o*2+1]+((fs[r]-fs[mid+1-1]+mod)%mod*t2[o])%mod)%mod;
	t2[o]=0;
}

void modify(ll l,ll r,ll o,ll i,ll j,ll d,ll e){
	if(i<=l&&r<=j){
		tr[o]=(tr[o]+(d*(fs[r+1]-fs[l+1-1]+mod)%mod)%mod)%mod;
		tr[o]=(tr[o]+(e*(fs[r]-fs[l-1]+mod)%mod)%mod)%mod;
		t1[o]=(t1[o]+d)%mod;
		t2[o]=(t2[o]+e)%mod;
		return ;
	}
	push(o,l,r);
	down(o,l,r);
	if(mid>=i)modify(l,mid,o*2,i,j,d,e);
	if(mid<j)modify(mid+1,r,o*2+1,i,j,d,e);
	tr[o]=(tr[o*2]+tr[o*2+1])%mod;
}

ll query(ll l,ll r,ll o,ll i,ll j){
	if(i<=l&&r<=j){
		return tr[o]%mod;
	}
	ll ret=0;
	push(o,l,r);
	down(o,l,r);
	if(mid>=i)ret=(ret+query(l,mid,o*2,i,j))%mod;
	if(mid<j)ret=(ret+query(mid+1,r,o*2+1,i,j))%mod;
	return ret;
}

int main(){
	freopen("D:/ex_czgj2.in","r",stdin);
	freopen("D:/11.txt","w",stdout);
	cin>>n>>m;
	f[1]=f[2]=1;
	for(ll i=3;i<=n*2;i++){
		f[i]=(f[i-1]+f[i-2])%mod;
	}
	for(ll i=1;i<=n*2;i++){
		fs[i]=(fs[i-1]+f[i])%mod;
	}
	for(ll i=-1;i>=-n*2;i--){
		ff[i+n]=(i%2==0?mod-f[-i]:f[-i]);
		//cout<<ff[i+n]<<endl;
	}
	for(ll i=1;i<=n;i++){
		scanf("%lld",&a[i]);
		sum[i]=(sum[i-1]+a[i])%mod;
	}
	while(m--){
		ll a1,a2,a3;
		scanf("%lld%lld%lld",&a1,&a2,&a3);
		if(a1==1){
			modify(1,n,1,a2,a3,ff[n+(1-a2)],ff[n+(-a2)]);
		}
		else {
			printf("%lld\n",(query(1,n,1,a2,a3)+sum[a3]-sum[a2-1]+2*mod)%mod);
		}
	}
}


#include<bits/stdc++.h>
#define LL __int128
const LL mod=1e9+9;
using namespace std;
inline int lowbit(int i)
{
    return i&-i;
}
template<typename T>inline void read(T&x)
{
    T ll=1;
    T res=0;
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch=='-')
        ll=-1;
        ch=getchar();
    }
    while(isdigit(ch))
    res=(res<<3)+(res<<1)+ch-'0',ch=getchar();
    x=res*ll;
}
template<typename T>void print(T x)
{
    if(x<0)putchar('-'),x=-x;
    if(x<10)
    putchar(x+'0');
    else
    {
        print(x/10);
        putchar(x%10+'0');
    }
}
int n;
int q;
LL a[500001],c[500001];
inline void change(LL i,LL delta)
{
    while(i<=n)
    {
        c[i]+=delta;
        c[i]%=mod;
        i+=lowbit(i);
    }
}
inline LL get(LL i)
{
    LL sum=0;
    while(i>0)
    {
        sum+=c[i];
        sum%=mod;
        i-=lowbit(i);
    }
    return sum;
}
inline LL get(LL l,LL r)
{
    return get(r)-get(l-1);
}
int main()
{
    read(n),read(q);
    LL f[n];
    f[1]=f[2]=1;
    for(int i=3;i<=n;i++)
    {
    	f[i]=(f[i-1]+f[i-2])%mod;
    }
    for(int i=1;i<=n;i++)
    {
        read(a[i]);
        change(i,a[i]);
    }
    int opt,x,y;
    while(q--)
    {
        read(opt),read(x),read(y);
        if(opt==1)
        {
        	for(int i=x;i<=y;i++)
        	{
        		change(i,f[i-x+1]);
            }
        }
        else
        print(get(x,y)%mod),puts("");
    }
    return 0;
}


#include<iostream>
#include<cstdio>
using namespace std;
#define mid ((l+r)>>1)
typedef long long ll;
const int maxn=3e5+10;
const int p=1e9+9;

ll fr[maxn],fib[maxn],sum[maxn];

struct ms {
	ll a,b;
	ms() {a=b=0;}
	ms(ll x,ll y):a(x),b(y) {}
	ms operator +(const ms &y) {
		return ms((a+y.a)%p,(b+y.b)%p);
	}
	ms operator +(const int &y) {
		return ms((fib[y-1]*a%p+fib[y]*b%p)%p,(fib[y]*a%p+fib[y+1]*b%p)%p);
	}
} tag[maxn];

int n,m,a[maxn],lson[maxn],rson[maxn],ttop=1;

ll getsum(ms ysj,int sjb) {
	if(sjb==1) return ysj.a;
	return ((fr[sjb-2]+1)*ysj.a%p+fr[sjb-1]*ysj.b%p)%p;
}

void pushdown(int t0,int l,int r) {
	if(!tag[t0].a&&!tag[t0].b) return ;
	tag[lson[t0]]=tag[lson[t0]]+tag[t0];
	tag[rson[t0]]=tag[rson[t0]]+(tag[t0]+(mid-l+1));
	sum[lson[t0]]=(sum[lson[t0]]+getsum(tag[t0],mid-l+1))%p;
 	sum[rson[t0]]=(sum[rson[t0]]+getsum(tag[t0]+(mid-l+1),r-mid))%p;
	tag[t0].a=tag[t0].b=0;
	return ;
}

void update(int t0,int l,int r,int l0,int r0) {
	if(l>=l0&&r<=r0) {
		tag[t0]=tag[t0]+ms(fib[l-l0+1],fib[l-l0+2]);
		sum[t0]=(sum[t0]+fr[r-l0+1]-fr[l-l0]+p)%p;
		return ;
	}
	pushdown(t0,l,r);
	if(l0<=mid) update(lson[t0],l,mid,l0,r0);
	if(r0>mid) update(rson[t0],mid+1,r,l0,r0);
	sum[t0]=(sum[lson[t0]]+sum[rson[t0]])%p;
	return ;
}

ll query(int t0,int l,int r,int l0,int r0) {
	if(l>=l0&&r<=r0) return sum[t0];
	pushdown(t0,l,r);
	ll res=0;
	if(l0<=mid) res=(res+query(lson[t0],l,mid,l0,r0))%p;
	if(r0>mid) res=(res+query(rson[t0],mid+1,r,l0,r0))%p;
	return res;
}

void build(int t0,int l,int r) {
	if(l==r) {sum[t0]=a[l];return ;}
	lson[t0]=++ttop;
	rson[t0]=++ttop;
	build(lson[t0],l,mid);
	build(rson[t0],mid+1,r);
	sum[t0]=(sum[lson[t0]]+sum[rson[t0]])%p;
	return ;
}

int main() {
	scanf("%d%d",&n,&m);
	fib[1]=fib[2]=1;
	for(int i=3;i<=n;i++) fib[i]=(fib[i-1]+fib[i-2])%p;
	for(int i=1;i<=n;i++) fr[i]=(fr[i-1]+fib[i])%p;
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	build(1,1,n);
	for(int i=0,op,l,r;i<m;i++) {
		scanf("%d%d%d",&op,&l,&r);if(l>r) swap(l,r);
		if(op==1) update(1,1,n,l,r);
		else printf("%lld\n",query(1,1,n,l,r));
	}
	return 0;
}