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

using namespace std;

typedef long long ll;

const int MOD = 1000000009, TOUR = 1<<19, MAX = 300100;

struct tour {
    int val, prop1, prop2;
} t[2*TOUR];

int pocmat[3][3] = {0, 1, 0,
                    1, 1, 0,
                    1, 1, 1};

int mat[MAX][3][3];

void mnoz(int a[3][3], int b[3][3], int c[3][3])
{
    int i, j, k;

    for (i=0; i<3; i++)
        for (j=0; j<3; j++) {
            c[i][j] = 0;
            for (k=0; k<3; k++)
                c[i][j] = (c[i][j] + (ll) a[i][k] * b[k][j]) % MOD;
        }
}

int pot(int poc1, int poc2, int eksp, int st) // 1 - zbroj, 0 - n-ti
{
    int indtmp=0, indp=0, i, j;

    if (!eksp)
        return 0;

    if (eksp == 1)
        return poc1;

    if (!st)
        eksp++;
    eksp -= 2;

    if (st == 1)
        return (((ll) mat[eksp][2][0] * poc1 + (ll) mat[eksp][2][1] * poc2) % MOD + (ll) mat[eksp][2][2] * (poc1 + poc2)) % MOD;
    return ((ll) mat[eksp][0][0] * poc1 + (ll) mat[eksp][0][1] * poc2) % MOD;
}

void Prop(int node, int lo, int hi)
{
    int p1=t[node].prop1, p2=t[node].prop2, t1, t2;

    //printf("DA\n");

    if (t[node].prop2) {
        t[2*node].prop1 = (t[2*node].prop1 + p1) % MOD;
        t[2*node].prop2 = (t[2*node].prop2 + p2) % MOD;
        //printf("POT %d %d %d %d %d %d\n", t[2*node].val, p1, p2, (hi-lo)/2, 1, pot(p1, p2, (hi-lo) / 2, 1));
        t[2*node].val = ((ll) t[2*node].val + pot(p1, p2, (hi-lo) / 2, 1)) % MOD;
        //printf("POT %d %d %d %d %d\n", p1, p2, (hi-lo)/2, 1, pot(p1, p2, (hi-lo) / 2, 1));
        t1 = pot(p1, p2, (hi-lo)/2 + 1, 0);
        t2 = pot(p1, p2, (hi-lo)/2 + 2, 0);
        t[2*node+1].prop1 = (t[2*node+1].prop1 + t1) % MOD;
        t[2*node+1].prop2 = (t[2*node+1].prop2 + t2) % MOD;
        t[2*node+1].val = ((ll) t[2*node+1].val + pot(t1, t2, (hi-lo)/2, 1)) % MOD;
        //printf("PROP %d %d %d %d\n", lo, hi, t[2*node].val, t[2*node+1].val);
    }

    t[node].prop1 = t[node].prop2 = 0;
}

void Stavi(int pos, int lo, int hi, int begin, int end, int p1, int p2)
{
    int poc1, poc2;

    if (lo >= end || hi <= begin)
        return;
    if (lo >= begin && hi <= end) {
        poc1 = pot(p1, p2, lo - begin + 1, 0);
        poc2 = pot(p1, p2, lo - begin + 2, 0);
        t[pos].prop1 = (t[pos].prop1 + poc1) % MOD;
        t[pos].prop2 = (t[pos].prop2 + poc2) % MOD;
        t[pos].val = (t[pos].val + pot(poc1, poc2, hi-lo, 1)) % MOD;
        //printf("STAVI %d %d %d %d %d\n", lo, hi, t[pos].val, t[pos].prop1, t[pos].prop2);
        return;
    }

    Prop(pos, lo, hi);

    Stavi(2*pos+0, lo, (lo+hi)/2, begin, end, p1, p2);
    Stavi(2*pos+1, (lo+hi)/2, hi, begin, end, p1, p2);
    t[pos].val = (t[2*pos+0].val + t[2*pos+1].val) % MOD;
}

int Vrati(int pos, int lo, int hi, int begin, int end)
{
    int r;

    if (lo >= end || hi <= begin)
        return 0;
    if (lo >= begin && hi <= end) {
        //printf("VRATI %d %d %d\n", lo, hi, t[pos].val);
        return t[pos].val;
    }

    Prop(pos, lo, hi);

    r = (Vrati(2*pos+0, lo, (lo+hi)/2, begin, end) +
         Vrati(2*pos+1, (lo+hi)/2, hi, begin, end)) % MOD;

    t[pos].val = (t[2*pos].val + t[2*pos+1].val) % MOD;

    return r;
}

int main()
{
    int n, q, i, st, tmp, l, r;

    /*for (i=0; i<3; i++)
        for (j=0; j<3; j++)
            mat[0][i][j] = pocmat[i][j];*/

    for (i=0; i<3; i++)
        mat[0][i][i] = 1;

    for (i=1; i<MAX; i++)
        mnoz(mat[i-1], pocmat, mat[i]);

    scanf("%d%d", &n, &q);

    for (i=0; i<n; i++) {
        scanf("%d", &tmp);
        Stavi(1, 0, TOUR, i, i+1, tmp, tmp);
    }

    for (i=0; i<q; i++) {
        scanf("%d%d%d", &st, &l, &r); l--;
        if (st == 1)
            Stavi(1, 0, TOUR, l, r, 1, 1);
        else
            printf("%d\n", Vrati(1, 0, TOUR, l, r));
    }

    //TOUR

    return 0;
}


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

using namespace std;

typedef long long ll;

const int MOD = 1000000009, TOUR = 1<<19;

struct tour {
    int val, prop1, prop2;
} t[2*TOUR];

int pocmat[3][3] = {0, 1, 0,
                    1, 1, 0,
                    1, 1, 1};

int mat[2][3][3], tmpmat[2][3][3];

void mnoz(int a[3][3], int b[3][3], int c[3][3])
{
    int i, j, k;

    for (i=0; i<3; i++)
        for (j=0; j<3; j++) {
            c[i][j] = 0;
            for (k=0; k<3; k++)
                c[i][j] = (c[i][j] + (ll) a[i][k] * b[k][j]) % MOD;
        }
}

int pot(int poc1, int poc2, int eksp, int st) // 1 - zbroj, 0 - n-ti
{
    int indtmp=0, indp=0, i, j;

    if (!eksp)
        return 0;

    if (eksp == 1)
        return poc1;

    memset(mat, 0, sizeof mat);
    memset(tmpmat, 0, sizeof tmpmat);

    for (i=0; i<3; i++)
        mat[0][i][i] = 1;

    for (i=0; i<3; i++)
        for (j=0; j<3; j++)
            tmpmat[0][i][j] = pocmat[i][j];

    if (!st)
        eksp++;

    for (eksp-=2; eksp; eksp >>= 1, indtmp = 1 - indtmp) {
        if (eksp & 1) {
            mnoz(tmpmat[indtmp], mat[indp], mat[1-indp]);
            indp = 1 - indp;
        }
        mnoz(tmpmat[indtmp], tmpmat[indtmp], tmpmat[1-indtmp]);
    }

    if (st == 1)
        return (((ll) mat[indp][2][0] * poc1 + (ll) mat[indp][2][1] * poc2) % MOD + (ll) mat[indp][2][2] * (poc1 + poc2)) % MOD;
    return ((ll) mat[indp][0][0] * poc1 + (ll) mat[indp][0][1] * poc2) % MOD;
}

void Prop(int node, int lo, int hi)
{
    int p1=t[node].prop1, p2=t[node].prop2, t1, t2;

    //printf("DA\n");

    if (t[node].prop2) {
        t[2*node].prop1 = (t[2*node].prop1 + p1) % MOD;
        t[2*node].prop2 = (t[2*node].prop2 + p2) % MOD;
        //printf("POT %d %d %d %d %d %d\n", t[2*node].val, p1, p2, (hi-lo)/2, 1, pot(p1, p2, (hi-lo) / 2, 1));
        t[2*node].val = ((ll) t[2*node].val + pot(p1, p2, (hi-lo) / 2, 1)) % MOD;
        //printf("POT %d %d %d %d %d\n", p1, p2, (hi-lo)/2, 1, pot(p1, p2, (hi-lo) / 2, 1));
        t1 = pot(p1, p2, (hi-lo)/2 + 1, 0);
        t2 = pot(p1, p2, (hi-lo)/2 + 2, 0);
        t[2*node+1].prop1 = (t[2*node+1].prop1 + t1) % MOD;
        t[2*node+1].prop2 = (t[2*node+1].prop2 + t2) % MOD;
        t[2*node+1].val = ((ll) t[2*node+1].val + pot(t1, t2, (hi-lo)/2, 1)) % MOD;
        //printf("PROP %d %d %d %d\n", lo, hi, t[2*node].val, t[2*node+1].val);
    }

    t[node].prop1 = t[node].prop2 = 0;
}

void Stavi(int pos, int lo, int hi, int begin, int end, int p1, int p2)
{
    int poc1, poc2;

    if (lo >= end || hi <= begin)
        return;
    if (lo >= begin && hi <= end) {
        poc1 = pot(p1, p2, lo - begin + 1, 0);
        poc2 = pot(p1, p2, lo - begin + 2, 0);
        t[pos].prop1 = (t[pos].prop1 + poc1) % MOD;
        t[pos].prop2 = (t[pos].prop2 + poc2) % MOD;
        t[pos].val = (t[pos].val + pot(poc1, poc2, hi-lo, 1)) % MOD;
        //printf("STAVI %d %d %d %d %d\n", lo, hi, t[pos].val, t[pos].prop1, t[pos].prop2);
        return;
    }

    Prop(pos, lo, hi);

    Stavi(2*pos+0, lo, (lo+hi)/2, begin, end, p1, p2);
    Stavi(2*pos+1, (lo+hi)/2, hi, begin, end, p1, p2);
    t[pos].val = (t[2*pos+0].val + t[2*pos+1].val) % MOD;
}

int Vrati(int pos, int lo, int hi, int begin, int end)
{
    int r;

    if (lo >= end || hi <= begin)
        return 0;
    if (lo >= begin && hi <= end) {
        //printf("VRATI %d %d %d\n", lo, hi, t[pos].val);
        return t[pos].val;
    }

    Prop(pos, lo, hi);

    r = (Vrati(2*pos+0, lo, (lo+hi)/2, begin, end) +
         Vrati(2*pos+1, (lo+hi)/2, hi, begin, end)) % MOD;

    t[pos].val = (t[2*pos].val + t[2*pos+1].val) % MOD;

    return r;
}

int main()
{
    int n, q, i, st, tmp, l, r;

    scanf("%d%d", &n, &q);

    //TOUR

    for (i=0; i<n; i++) {
        scanf("%d", &tmp);
        Stavi(1, 0, TOUR, i, i+1, tmp, tmp);
    }

    for (i=0; i<q; i++) {
        scanf("%d%d%d", &st, &l, &r); l--;
        if (st == 1)
            Stavi(1, 0, TOUR, l, r, 1, 1);
        else
            printf("%d\n", Vrati(1, 0, TOUR, l, r));
    }

    //TOUR

    return 0;
}


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

using namespace std;

typedef long long ll;

const int MOD = 1000000009, TOUR = 1<<19;

struct tour {
    int val, prop1, prop2;
} t[2*TOUR];

int pocmat[3][3] = {0, 1, 0,
                    1, 1, 0,
                    1, 1, 1};

int mat[2][3][3], tmpmat[2][3][3];

void mnoz(int a[3][3], int b[3][3], int c[3][3])
{
    int i, j, k;

    for (i=0; i<3; i++)
        for (j=0; j<3; j++) {
            c[i][j] = 0;
            for (k=0; k<3; k++)
                c[i][j] = (c[i][j] + (ll) a[i][k] * b[k][j]) % MOD;
        }
}

int pot(int poc1, int poc2, int eksp, int st) // 1 - zbroj, 0 - n-ti
{
    int indtmp=0, indp=0, i, j;

    if (eksp == 1)
        return poc1;

    memset(mat, 0, sizeof mat);
    memset(tmpmat, 0, sizeof tmpmat);

    for (i=0; i<3; i++)
        mat[0][i][i] = 1;

    for (i=0; i<3; i++)
        for (j=0; j<3; j++)
            tmpmat[0][i][j] = pocmat[i][j];

    if (!st)
        eksp++;

    for (eksp-=2; eksp; eksp >>= 1, indtmp = 1 - indtmp) {
        if (eksp & 1) {
            mnoz(tmpmat[indtmp], mat[indp], mat[1-indp]);
            indp = 1 - indp;
        }
        mnoz(tmpmat[indtmp], tmpmat[indtmp], tmpmat[1-indtmp]);
    }

    if (st == 1)
        return (((ll) mat[indp][2][0] * poc1 + (ll) mat[indp][2][1] * poc2) % MOD + (ll) mat[indp][2][2] * (poc1 + poc2)) % MOD;
    return ((ll) mat[indp][0][0] * poc1 + (ll) mat[indp][0][1] * poc2) % MOD;
}

void Prop(int node, int lo, int hi)
{
    int p1=t[node].prop1, p2=t[node].prop2;

    //printf("DA\n");

    if (t[node].prop2) {
        t[2*node].prop1 = p1;
        t[2*node].prop2 = p2;
        t[2*node].val = ((ll) t[2*node].val + pot(p1, p2, (hi-lo) / 2, 1)) % MOD;
        t[2*node+1].prop1 = pot(p1, p2, (hi-lo)/2 + 1, 0);
        t[2*node+1].prop2 = pot(p1, p2, (hi-lo)/2 + 2, 0);
        t[2*node+1].val = ((ll) t[2*node+1].val + pot(t[2*node+1].prop1, t[2*node+1].prop2, (hi-lo)/2, 1)) % MOD;
    }

    t[node].prop1 = t[node].prop2 = 0;
}

void Stavi(int pos, int lo, int hi, int begin, int end, int p1, int p2)
{
    int poc1, poc2;

    if (lo >= end || hi <= begin)
        return;
    if (lo >= begin && hi <= end) {
        poc1 = pot(p1, p2, lo - begin + 1, 0);
        poc2 = pot(p1, p2, lo - begin + 2, 0);
        t[pos].prop1 = (t[pos].prop1 + poc1) % MOD;
        t[pos].prop2 = (t[pos].prop2 + poc2) % MOD;
        t[pos].val = (t[pos].val + pot(poc1, poc2, hi-lo, 1)) % MOD;
        //printf("DADADA %d %d %d\n", lo, hi, t[pos].val);
        return;
    }

    Prop(pos, lo, hi);

    Stavi(2*pos+0, lo, (lo+hi)/2, begin, end, p1, p2);
    Stavi(2*pos+1, (lo+hi)/2, hi, begin, end, p1, p2);
    t[pos].val = (t[2*pos+0].val + t[2*pos+1].val) % MOD;
}

int Vrati(int pos, int lo, int hi, int begin, int end)
{
    int r;

    if (lo >= end || hi <= begin)
        return 0;
    if (lo >= begin && hi <= end) {
        //printf("VRATI %d %d %d\n", lo, hi, t[pos].val);
        return t[pos].val;
    }

    Prop(pos, lo, hi);

    r = (Vrati(2*pos+0, lo, (lo+hi)/2, begin, end) +
         Vrati(2*pos+1, (lo+hi)/2, hi, begin, end)) % MOD;

    t[pos].val = (t[2*pos].val + t[2*pos+1].val) % MOD;

    return r;
}

int main()
{
    int n, q, i, st, tmp, l, r;

    scanf("%d%d", &n, &q);

    //TOUR

    for (i=0; i<n; i++) {
        scanf("%d", &tmp);
        Stavi(1, 0, TOUR, i, i+1, tmp, tmp);
    }

    for (i=0; i<q; i++) {
        scanf("%d%d%d", &st, &l, &r); l--;
        if (st == 1)
            Stavi(1, 0, TOUR, l, r, 1, 1);
        else
            printf("%d\n", Vrati(1, 0, TOUR, l, r));
    }

    //TOUR

    return 0;
}


#include <cstdio>
#include <algorithm>

using namespace std;

typedef long long ll;

const int MOD = 1000000009, TOUR = 1<<19;

struct tour {
    int val, prop1, prop2;
} t[2*TOUR];

int pocmat[3][3] = {0, 1, 0,
                    1, 1, 0,
                    1, 1, 1};

int mat[2][3][3], tmpmat[2][3][3];

void mnoz(int a[3][3], int b[3][3], int c[3][3])
{
    int i, j, k;

    for (i=0; i<3; i++)
        for (j=0; j<3; j++) {
            c[i][j] = 0;
            for (k=0; k<3; k++)
                c[i][j] = (c[i][j] + (ll) a[i][k] * b[k][j]) % MOD;
        }
}

int pot(int poc1, int poc2, int eksp, int st) // 1 - zbroj, 0 - n-ti
{
    int indtmp=0, indp=0, i, j;

    if (eksp == 1)
        return poc1;

    memset(mat, 0, sizeof mat);
    memset(tmpmat, 0, sizeof tmpmat);

    for (i=0; i<3; i++)
        mat[0][i][i] = 1;

    for (i=0; i<3; i++)
        for (j=0; j<3; j++)
            tmpmat[0][i][j] = pocmat[i][j];

    if (!st)
        eksp++;

    for (eksp-=2; eksp; eksp >>= 1, indtmp = 1 - indtmp) {
        if (eksp & 1) {
            mnoz(tmpmat[indtmp], mat[indp], mat[1-indp]);
            indp = 1 - indp;
        }
        mnoz(tmpmat[indtmp], tmpmat[indtmp], tmpmat[1-indtmp]);
    }

    if (st == 1)
        return (((ll) mat[indp][2][0] * poc1 + (ll) mat[indp][2][1] * poc2) % MOD + (ll) mat[indp][2][2] * (poc1 + poc2)) % MOD;
    return ((ll) mat[indp][0][0] * poc1 + (ll) mat[indp][0][1] * poc2) % MOD;
}

void Prop(int node, int lo, int hi)
{
    int p1=t[node].prop1, p2=t[node].prop2;

    //printf("DA\n");

    if (t[node].prop2) {
        t[2*node].prop1 = p1;
        t[2*node].prop2 = p2;
        t[2*node].val = ((ll) t[2*node].val + pot(p1, p2, (hi-lo) / 2, 1)) % MOD;
        t[2*node+1].prop1 = pot(p1, p2, (hi-lo)/2 + 1, 0);
        t[2*node+1].prop2 = pot(p1, p2, (hi-lo)/2 + 2, 0);
        t[2*node+1].val = ((ll) t[2*node+1].val + pot(t[2*node+1].prop1, t[2*node+1].prop2, (hi-lo)/2, 1)) % MOD;
    }

    t[node].prop1 = t[node].prop2 = 0;
}

void Stavi(int pos, int lo, int hi, int begin, int end, int p1, int p2)
{
    int poc1, poc2;

    if (lo >= end || hi <= begin)
        return;
    if (lo >= begin && hi <= end) {
        poc1 = pot(p1, p2, lo - begin + 1, 0);
        poc2 = pot(p1, p2, lo - begin + 2, 0);
        t[pos].prop1 = (t[pos].prop1 + poc1) % MOD;
        t[pos].prop2 = (t[pos].prop2 + poc2) % MOD;
        t[pos].val = (t[pos].val + pot(poc1, poc2, hi-lo, 1)) % MOD;
        //printf("DADADA %d %d %d\n", lo, hi, t[pos].val);
        return;
    }

    Prop(pos, lo, hi);

    Stavi(2*pos+0, lo, (lo+hi)/2, begin, end, p1, p2);
    Stavi(2*pos+1, (lo+hi)/2, hi, begin, end, p1, p2);
    t[pos].val = (t[2*pos+0].val + t[2*pos+1].val) % MOD;
}

int Vrati(int pos, int lo, int hi, int begin, int end)
{
    int r;

    if (lo >= end || hi <= begin)
        return 0;
    if (lo >= begin && hi <= end) {
        //printf("VRATI %d %d %d\n", lo, hi, t[pos].val);
        return t[pos].val;
    }

    Prop(pos, lo, hi);

    r = (Vrati(2*pos+0, lo, (lo+hi)/2, begin, end) +
         Vrati(2*pos+1, (lo+hi)/2, hi, begin, end)) % MOD;

    t[pos].val = (t[2*pos].val + t[2*pos+1].val) % MOD;

    return r;
}

int main()
{
    int n, q, i, st, tmp, l, r;

    scanf("%d%d", &n, &q);

    //TOUR

    for (i=0; i<n; i++) {
        scanf("%d", &tmp);
        Stavi(1, 0, TOUR, i, i+1, tmp, tmp);
    }

    for (i=0; i<q; i++) {
        scanf("%d%d%d", &st, &l, &r); l--;
        if (st == 1)
            Stavi(1, 0, TOUR, l, r, 1, 1);
        else
            printf("%d\n", Vrati(1, 0, TOUR, l, r));
    }

    //TOUR

    return 0;
}


#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <cmath>
#include <sstream>
#include <map>
#include <set>
#include <numeric>
#include <memory.h>
#include <cstdio>
#include <assert.h>

using namespace std;

#define pb push_back
#define INF 1011111111
#define FOR(i, a, b) for (int _n(b), i(a); i < _n; i++)
#define rep(i, n) FOR(i, 0, n)
#define CL(a, v) memset((a), (v), sizeof(a))
#define mp make_pair
#define X first
#define Y second
#define all(c) (c).begin(), (c).end()
#define SORT(c) sort(all(c))

typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> pii;

/*** TEMPLATE CODE ENDS HERE */

const ll P = 1000000009;
const int N = 1200004;
struct rec {
  ll a[2][2];
} f[N], sf[N];
int n, m, a[N], ql, qr;
ll s[N], c1[N], c2[N], fib[N], sum[N];

void mul(rec &a, rec &b, rec &c) {
  for (int i = 0; i < 2; i++)
    for (int j = 0; j < 2; j++) {
      c.a[i][j] = 0;
      for (int k = 0; k < 2; k++) c.a[i][j] += a.a[i][k] * b.a[k][j];
      c.a[i][j] %= P;
    }
}

void build(int o, int l, int r) {
  c1[o] = c2[o] = 0;
  if (l == r) {
    s[o] = a[l];
    return;
  }
  int m = (l + r) / 2;
  build(o * 2, l, m);
  build(o * 2 + 1, m + 1, r);
  s[o] = (s[o * 2] + s[o * 2 + 1]) % P;
}

void add(int o, int l, int r, ll d1, ll d2) {
  s[o] = (s[o] + d1 * sf[r - l + 1].a[0][0] + d2 * sf[r - l + 1].a[0][1]) % P;
  c1[o] = (c1[o] + d1) % P;
  c2[o] = (c2[o] + d2) % P;
}

void down(int o, int l, int r) {
  int m = (l + r) / 2;
  add(o * 2, l, m, c1[o], c2[o]);
  ll d1 = (c1[o] * f[m + 1 - l].a[0][0] + c2[o] * f[m + 1 - l].a[0][1]) % P,
     d2 = (c1[o] * f[m + 1 - l].a[1][0] + c2[o] * f[m + 1 - l].a[1][1]) % P;
  add(o * 2 + 1, m + 1, r, d1, d2);
  c1[o] = c2[o] = 0;
}

void update(int o, int l, int r) {
  if ((ql <= l) && (r <= qr)) {
    add(o, l, r, fib[l - ql + 1], fib[l - ql]);
    return;
  }
  int m = (l + r) / 2;
  down(o, l, r);
  if (ql <= m) update(o * 2, l, m);
  if (m < qr) update(o * 2 + 1, m + 1, r);
  s[o] = (s[o * 2] + s[o * 2 + 1]) % P;
}

ll query(int o, int l, int r) {
  if ((ql <= l) && (r <= qr)) return s[o];
  int m = (l + r) / 2;
  down(o, l, r);
  ll ret = 0;
  if (ql <= m) ret += query(o * 2, l, m);
  if (m < qr) ret += query(o * 2 + 1, m + 1, r);
  return ret % P;
}

int main() {
#ifdef LOCAL_HOST
  freopen("input.txt", "r", stdin);
// freopen("output.txt","w",stdout);
#endif

  int i;
  scanf("%d%d", &n, &m);
  for (i = 1; i <= n; i++) scanf("%d", &a[i]);
  fib[0] = 0;
  fib[1] = 1;
  for (i = 2; i <= n; i++) fib[i] = (fib[i - 2] + fib[i - 1]) % P;
  f[1].a[0][0] = f[1].a[0][1] = f[1].a[1][0] = 1;
  f[1].a[1][1] = 0;
  for (i = 2; i <= n; i++) mul(f[i - 1], f[1], f[i]);
  sf[1].a[0][0] = 1;
  sf[1].a[0][1] = sf[1].a[1][0] = sf[1].a[1][1] = 0;
  for (i = 2; i <= n; i++)
    for (int j = 0; j < 2; j++)
      for (int k = 0; k < 2; k++)
        sf[i].a[j][k] = (sf[i - 1].a[j][k] + f[i - 1].a[j][k]) % P;
  build(1, 1, n);
  for (i = 1; i <= m; i++) {
    int op;
    scanf("%d%d%d", &op, &ql, &qr);
    if (op == 1)
      update(1, 1, n);
    else
      printf("%d\n", int(query(1, 1, n)));
  }
  return 0;

#ifdef LOCAL_HOST
  printf("TIME: %.3lf\n", double(clock()) / CLOCKS_PER_SEC);
#endif

  return 0;
}


#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <cmath>
#include <sstream>
#include <map>
#include <set>
#include <numeric>
#include <memory.h>
#include <cstdio>
#include <assert.h>

using namespace std;

#define pb push_back
#define INF 1011111111
#define FOR(i, a, b) for (int _n(b), i(a); i < _n; i++)
#define rep(i, n) FOR(i, 0, n)
#define CL(a, v) memset((a), (v), sizeof(a))
#define mp make_pair
#define X first
#define Y second
#define all(c) (c).begin(), (c).end()
#define SORT(c) sort(all(c))

typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> pii;

/*** TEMPLATE CODE ENDS HERE */

const int maxn = 4 * 300000 + 5;
const ll mod = 1000000009;

ll fib[maxn];
ll x0[maxn], x1[maxn], sum[maxn];

void UpdateS(int a, int b, ll y0, ll y1) {
  y0 %= mod;
  y1 %= mod;

  x0[a + b] += y0;
  if (x0[a + b] >= mod) x0[a + b] -= mod;

  x1[a + b] += y1;
  if (x1[a + b] >= mod) x1[a + b] -= mod;

  sum[a + b] += y0 * fib[b - a] + y1 * (fib[b - a + 1] - 1);
  sum[a + b] %= mod;
}

void Split(int a, int c, int b) {
  UpdateS(a, c, x0[a + b], x1[a + b]);
  UpdateS(c, b, x0[a + b] * fib[c - a - 1] + x1[a + b] * fib[c - a],
          x0[a + b] * fib[c - a] + x1[a + b] * fib[c - a + 1]);
  x0[a + b] = 0;
  x1[a + b] = 0;
  sum[a + b] = 0;
}

void Merge(int a, int c, int b) {
  sum[a + b] = 0;
  sum[a + b] += sum[a + c];
  sum[a + b] += sum[b + c];
  sum[a + b] %= mod;
}

void Update(int a, int b, int l, int r, int idx) {
  if (l <= a && b <= r) {
    UpdateS(a, b, fib[idx], fib[idx + 1]);
    return;
  }
  int m = (a + b) / 2;
  if (l < m) {
    Update(a, m, l, r, idx);
  }
  if (m < r) {
    Update(m, b, l, r, idx + (m - a));
  }
  Merge(a, m, b);
}

ll Query(int a, int b, int l, int r) {
  if (l <= a && b <= r) {
    return sum[a + b];
  }
  int m = (a + b) / 2;
  Split(a, m, b);
  ll ans = 0;
  if (l < m) {
    ans += Query(a, m, l, r);
  }
  if (m < r) {
    ans += Query(m, b, l, r);
  }
  Merge(a, m, b);
  return ans % mod;
}

void FullMerge(int a, int b) {
  if (a + 1 == b) {
    return;
  }
  int c = (a + b) / 2;
  FullMerge(a, c);
  FullMerge(c, b);
  Merge(a, c, b);
}

int main() {
#ifdef LOCAL_HOST
  freopen("input.txt", "r", stdin);
// freopen("output.txt","w",stdout);
#endif

  ios_base::sync_with_stdio(false);

  CL(x0, 0);
  CL(x1, 0);
  CL(sum, 0);

  fib[0] = 0;
  fib[1] = 1;
  for (int i = 2; i < maxn; ++i) {
    fib[i] = fib[i - 1] + fib[i - 2];
    fib[i] %= mod;
  }

  int n, m;
  cin >> n >> m;

  int b = 1;
  while (b < n) b *= 2;

  for (int i = 0; i < n; ++i) {
    cin >> sum[i + i + 1];
  }

  FullMerge(0, b);

  for (int q = 0; q < m; ++q) {
    int l, r, op;
    cin >> op >> l >> r;
    if (op == 1) {
      Update(0, b, l - 1, r, 1 - l + 1);
    } else {
      cout << Query(0, b, l - 1, r) << endl;
    }
  }

#ifdef LOCAL_HOST
  printf("TIME: %.3lf\n", double(clock()) / CLOCKS_PER_SEC);
#endif

  return 0;
}


#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <cmath>
#include <sstream>
#include <map>
#include <set>
#include <numeric>
#include <memory.h>
#include <cstdio>
#include <assert.h>

using namespace std;

#define pb push_back
#define INF 1011111111
#define FOR(i, a, b) for (int _n(b), i(a); i < _n; i++)
#define rep(i, n) FOR(i, 0, n)
#define CL(a, v) memset((a), (v), sizeof(a))
#define mp make_pair
#define X first
#define Y second
#define all(c) (c).begin(), (c).end()
#define SORT(c) sort(all(c))

typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> pii;

/*** TEMPLATE CODE ENDS HERE */

typedef long long LL;

const int mod = 1e9 + 9;

const int maxn = 400000;

LL f[maxn];

struct fib_calc {
  static void precalc() {
    f[1] = 1;
    f[2] = 1;
    for (int i = 3; i < maxn; ++i) {
      f[i] = (f[i - 1] + f[i - 2]) % mod;
    }
  }

  static LL get_k(ll f1, ll f2, int k) {
    if (k == 1) return f1;
    if (k == 2) return f2;

    LL cur = 0;
    cur += f[k - 2] * LL(f1) % mod;
    cur += f[k - 1] * LL(f2) % mod;
    cur %= mod;

    return cur;
  }

  static LL get_sum(ll f1, ll f2, int k) {
    f1 %= mod;
    f2 %= mod;
    LL sum = get_k(f1, f2, k + 2);
    sum -= f2;
    sum %= mod;
    if (sum < 0) sum += mod;
    return sum;
  }
};

struct node_t {
  LL sum;
  LL f1, f2;

  node_t(int val = 0, int f1 = 0, int f2 = 0) : sum(val), f1(f1), f2(f2) {}

  void add(ll k1, ll k2, int len) {
    f1 += k1;
    f1 %= mod;
    f2 += k2;
    f2 %= mod;
    sum += fib_calc::get_sum(k1, k2, len);
    sum %= mod;
  }
};

const int maxm = 4 * maxn;
node_t tree[maxm];
int n;
void tbuild(int idx, int l, int r, const vector<int> &a) {
  if (l == r) {
    tree[idx] = node_t(a[l] % mod);
    return;
  }

  int m = (l + r) >> 1;
  tbuild(2 * idx + 1, l, m, a);
  tbuild(2 * idx + 2, m + 1, r, a);
  tree[idx].sum = tree[2 * idx + 1].sum + tree[2 * idx + 2].sum;
  tree[idx].sum %= mod;
}

void tpush(int idx, int l, int r) {
  if (tree[idx].f1 == 0 && tree[idx].f2 == 0) return;

  int m = (l + r) >> 1;
  tree[2 * idx + 1].add(tree[idx].f1, tree[idx].f2, m - l + 1);
  ll nf1 = fib_calc::get_k(tree[idx].f1, tree[idx].f2, m + 2 - l);
  ll nf2 = fib_calc::get_k(tree[idx].f1, tree[idx].f2, m + 3 - l);
  tree[2 * idx + 2].add(nf1, nf2, r - m);

  tree[idx].sum = (tree[2 * idx + 1].sum + tree[2 * idx + 2].sum) % mod;
  tree[idx].f1 = tree[idx].f2 = 0;
}

void tadd_fib(ll f1, ll f2, int fl, int fr, int idx, int l, int r) {
  if (l == fl && r == fr) {
    tree[idx].add(f1, f2, fr - fl + 1);
    return;
  }
  tpush(idx, l, r);

  int m = (l + r) >> 1;
  if (fr <= m)
    tadd_fib(f1, f2, fl, fr, 2 * idx + 1, l, m);
  else if (fl > m)
    tadd_fib(f1, f2, fl, fr, 2 * idx + 2, m + 1, r);
  else {
    tadd_fib(f1, f2, fl, m, 2 * idx + 1, l, m);
    ll nf1 = fib_calc::get_k(f1, f2, m + 2 - fl);
    ll nf2 = fib_calc::get_k(f1, f2, m + 3 - fl);
    tadd_fib(nf1, nf2, m + 1, fr, 2 * idx + 2, m + 1, r);
  }

  tree[idx].sum = tree[2 * idx + 1].sum + tree[2 * idx + 2].sum;
  tree[idx].sum %= mod;
}

ll tget_sum(int fl, int fr, int idx, int l, int r) {
  if (fl == l && fr == r) return tree[idx].sum;
  tpush(idx, l, r);

  int m = (l + r) >> 1;
  if (fr <= m)
    return tget_sum(fl, fr, 2 * idx + 1, l, m);
  else if (fl > m)
    return tget_sum(fl, fr, 2 * idx + 2, m + 1, r);
  else {
    return (tget_sum(fl, m, 2 * idx + 1, l, m) +
            tget_sum(m + 1, fr, 2 * idx + 2, m + 1, r)) %
           mod;
  }
}

void add_fib(int l, int r) { tadd_fib(1, 1, l, r, 0, 0, n - 1); }

int get_sum(int l, int r) {
  int cur = (int)tget_sum(l, r, 0, 0, n - 1);
  return cur;
}

vector<int> calc(int f1, int f2, int k) {
  vector<int> f(k + 1);
  f[1] = f1;
  f[2] = f2;
  for (int i = 3; i <= k; ++i) {
    f[i] = (f[i - 1] + f[i - 2]) % mod;
  }
  return f;
}

int main() {
#ifdef LOCAL_HOST
  freopen("input.txt", "r", stdin);
// freopen("output.txt","w",stdout);
#endif

  fib_calc::precalc();

  int m;
  scanf("%d%d", &n, &m);
  vector<int> a(n);
  for (int i = 0; i < n; ++i) scanf("%d", &a[i]);

  tbuild(0, 0, n - 1, a);

  for (int i = 0; i < m; ++i) {
    int t, l, r;
    scanf("%d%d%d", &t, &l, &r);
    --l;
    --r;
    if (t == 1) {
      add_fib(l, r);

    } else {
      int sum = get_sum(l, r);
      printf("%d\n", sum);
    }
  }

  return 0;

#ifdef LOCAL_HOST
  printf("TIME: %.3lf\n", double(clock()) / CLOCKS_PER_SEC);
#endif

  return 0;
}


#include<algorithm>
#include<cassert>
#include<complex>
#include<map>
#include<iomanip>
#include<sstream>
#include<queue>
#include<set>
#include<string>
#include<vector>
#include<iostream>
#include<cstring>
#include<cstdio>
#define FOR(i, a, b) for(int i =(a); i <=(b); ++i)
#define FORD(i, a, b) for(int i = (a); i >= (b); --i)
#define fup FOR
#define fdo FORD
#define REP(i, n) for(int i = 0;i <(n); ++i)
#define VAR(v, i) __typeof(i) v=(i)
#define FORE(i, c) for(VAR(i, (c).begin()); i != (c).end(); ++i)
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
#define siz SZ
#define CLR(x) memset((x), 0, sizeof(x))
#define PB push_back
#define MP make_pair
#define FI first
#define SE second
#define X FI
#define Y SE.FI
#define Z SE.SE
#define SQR(a) ((a)*(a))
#define DE 1
#define E(x) {if (DE)cerr <<#x <<" = " <<x <<endl; }
#define E2(x, y) {if (DE)cerr <<#x <<" = " <<x << ", " << #y << " = " << y << endl; }
#define E3(x, y, z) {if (DE)cerr <<#x <<" = " <<x << ", " << #y << " = " << y << ", " << #z << " = " << z << endl; }
#define E4(x, y, z, u) {if (DE)cerr <<#x <<" = " <<x << ", " << #y << " = " << y << ", " << #z << " = " << z << ", " << #u << " = " << u << endl; }
#define E5(x, y, z, u, v) {if (DE)cerr <<#x <<" = " <<x << ", " << #y << " = " << y << ", " << #z << " = " << z << ", " << #u << " = " << u << ", " << #v << " = " << v << endl; }
#define E6(x, y, z, u, v, o) {if (DE)cerr <<#x <<" = " <<x << ", " << #y << " = " << y << ", " << #z << " = " << z << ", " << #u << " = " << u << ", " << #v << " = " << v << ", " << #o << " = " << o << endl; }
#define Ev(x) {if (DE) {cerr <<#x <<" = "; FORE(it, (x)) cerr <<*it <<", "; cout <<endl; }}

using namespace std;

typedef long long LL;
typedef long double LD;
typedef pair<int, int> P;
typedef pair<int, P> PP;
typedef vector<int> VI;
const LL INF64 = ((LL)1E18);
const int INF=1E9+7;
template<class C> void mini(C&a4, C b4) { a4 = min(a4, b4); }
template<class C> void maxi(C&a4, C b4) { a4 = max(a4, b4); }
template<typename T1, typename T2> ostream& operator<< (ostream &out, pair<T1, T2> pair) { out << "(" << pair.FI << ", " << pair.SE << ")"; return out; }

const LL mod = 1000000009;
const int W = 2;
struct M {
    LL t[W][W];
    M() { CLR(t); }
};

M operator*(const M& a, const M& b) {
    M c;
    fup(i, 0, W - 1) fup(j, 0, W - 1) fup(k, 0, W - 1) c.t[i][j] += a.t[i][k] * b.t[k][j];
    fup(i, 0, W - 1) fup(j, 0, W - 1) c.t[i][j] %= mod;
    return c;
}

M operator+(const M& a, const M& b) {
    M c;
    fup(i, 0, W - 1) fup(j, 0, W - 1) c.t[i][j] = (a.t[i][j] + b.t[i][j]) % mod;
    return c;
}

const int base = (1 << 19);
M q, id, qpot[2 * base + 5], qpotsum[2 * base + 5], zero;
struct geo_seq_tree {
    M sumq[2*base + 5], sum[2 * base + 5];

    geo_seq_tree(){CLR(sum);}

    void add(int l, int r, int x = 1, int ll = 1, int rr = base) {
        if(r < ll || rr < l) return;
        if(l <= ll && rr <= r) { //przedzial basowy
            M m = qpot[ll - l];
            sumq[x] = sumq[x] + m;
            sum[x] = sum[x] + m * qpotsum[rr - ll];
        } else { //nadprzedzial
            add(l, r, x+x, ll, (ll+rr)/2);
            add(l, r, x+x+1, (ll+rr+1)/2, rr);
            sum[x] = sumq[x] * qpotsum[rr - ll] + sum[x * 2] + sum[x * 2 + 1];
        }
    }

    M get(int l, int r, M actq, int x = 1, int ll = 1, int rr = base) {
        if(r < ll || rr < l) return zero;
        if(l <= ll && rr <= r) { //przedzial basowy
            return sum[x] + actq * qpotsum[rr - ll];
        } else { //nadprzedzial
            actq = actq + sumq[x];
            return get(l, r, actq, x+x, ll, (ll+rr)/2) +
                get(l, r, actq * qpot[(rr -ll+ 1) / 2], x+x+1, (ll+rr+1)/2, rr);
        }
    }

};

#define maxn 300005
LL a[maxn], suma[maxn];
geo_seq_tree tree;

int main(){
    ios_base::sync_with_stdio(false);
    id.t[0][0] = id.t[1][1] =1;
    q.t[0][0] = q.t[0][1] = q.t[1][0] = 1;

    qpot[0] = id;
    qpotsum[0] = id;
    fup(i, 1, 2 * base) qpot[i] = q * qpot[i - 1], qpotsum[i] = qpotsum[i - 1] + qpot[i];

    int n, m;
    cin >> n >> m;
    fup(i, 1, n) { cin >> a[i]; suma[i] = (suma[i - 1] + a[i]) % mod; }
    fup(i, 1, m) {
        int typ, l, r;
        cin >> typ >> l >> r;
        if (typ == 1) {
            tree.add(l, r);
        } else {
           LL s1 = (suma[r] - suma[l - 1] + mod) % mod;
           M s2 = tree.get(l, r, zero);
           cout << (s1 + s2.t[0][0]) % mod << endl;
        }
    }

    return 0;
}


#include<algorithm>
#include<cassert>
#include<complex>
#include<map>
#include<iomanip>
#include<sstream>
#include<queue>
#include<set>
#include<string>
#include<vector>
#include<iostream>
#include<cstring>
#include<cstdio>
#define FOR(i, a, b) for(int i =(a); i <=(b); ++i)
#define FORD(i, a, b) for(int i = (a); i >= (b); --i)
#define fup FOR
#define fdo FORD
#define REP(i, n) for(int i = 0;i <(n); ++i)
#define VAR(v, i) __typeof(i) v=(i)
#define FORE(i, c) for(VAR(i, (c).begin()); i != (c).end(); ++i)
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
#define siz SZ
#define CLR(x) memset((x), 0, sizeof(x))
#define PB push_back
#define MP make_pair
#define FI first
#define SE second
#define X FI
#define Y SE.FI
#define Z SE.SE
#define SQR(a) ((a)*(a))
#define DE 1
#define E(x) {if (DE)cerr <<#x <<" = " <<x <<endl; }
#define E2(x, y) {if (DE)cerr <<#x <<" = " <<x << ", " << #y << " = " << y << endl; }
#define E3(x, y, z) {if (DE)cerr <<#x <<" = " <<x << ", " << #y << " = " << y << ", " << #z << " = " << z << endl; }
#define E4(x, y, z, u) {if (DE)cerr <<#x <<" = " <<x << ", " << #y << " = " << y << ", " << #z << " = " << z << ", " << #u << " = " << u << endl; }
#define E5(x, y, z, u, v) {if (DE)cerr <<#x <<" = " <<x << ", " << #y << " = " << y << ", " << #z << " = " << z << ", " << #u << " = " << u << ", " << #v << " = " << v << endl; }
#define E6(x, y, z, u, v, o) {if (DE)cerr <<#x <<" = " <<x << ", " << #y << " = " << y << ", " << #z << " = " << z << ", " << #u << " = " << u << ", " << #v << " = " << v << ", " << #o << " = " << o << endl; }
#define Ev(x) {if (DE) {cerr <<#x <<" = "; FORE(it, (x)) cerr <<*it <<", "; cout <<endl; }}

using namespace std;

typedef long long LL;
typedef long double LD;
typedef pair<int, int> P;
typedef pair<int, P> PP;
typedef vector<int> VI;
const LL INF64 = ((LL)1E18);
const int INF=1E9+7;
template<class C> void mini(C&a4, C b4) { a4 = min(a4, b4); }
template<class C> void maxi(C&a4, C b4) { a4 = max(a4, b4); }
template<typename T1, typename T2> ostream& operator<< (ostream &out, pair<T1, T2> pair) { out << "(" << pair.FI << ", " << pair.SE << ")"; return out; }

const LL mod = 1000000009;
const int W = 2;
struct M {
    LL t[W][W];
    M() { CLR(t); }
};
M operator*(M a, M b) {
    M c;
    fup(i, 0, W - 1) fup(j, 0, W - 1) fup(k, 0, W - 1) c.t[i][j] += a.t[i][k] * b.t[k][j];
    fup(i, 0, W - 1) fup(j, 0, W - 1) c.t[i][j] %= mod;
    return c;
}

M operator+(M a, M b) {
    M c;
    fup(i, 0, W - 1) fup(j, 0, W - 1) c.t[i][j] = (a.t[i][j] + b.t[i][j]) % mod;
    return c;
}

const int base = (1 << 19);
M q, id, qpot[2 * base + 5], qpotsum[2 * base + 5], zero;
struct geo_seq_tree {
    M sumq[2*base + 5], sum[2 * base + 5];

    geo_seq_tree(){CLR(sum);}

    void add(int l, int r, int x = 1, int ll = 1, int rr = base) {
        if(r < ll || rr < l) return;
        if(l <= ll && rr <= r) { //przedzial basowy
            M m = qpot[ll - l];
            sumq[x] = sumq[x] + m;
            sum[x] = sum[x] + m * qpotsum[rr - ll];
        } else { //nadprzedzial
            add(l, r, x+x, ll, (ll+rr)/2);
            add(l, r, x+x+1, (ll+rr+1)/2, rr);
            sum[x] = sumq[x] * qpotsum[rr - ll] + sum[x * 2] + sum[x * 2 + 1];
        }
    }

    M get(int l, int r, M actq, int x = 1, int ll = 1, int rr = base) {
        if(r < ll || rr < l) return zero;
        if(l <= ll && rr <= r) { //przedzial basowy
            return sum[x] + actq * qpotsum[rr - ll];
        } else { //nadprzedzial
            actq = actq + sumq[x];
            return get(l, r, actq, x+x, ll, (ll+rr)/2) +
                get(l, r, actq * qpot[(rr -ll+ 1) / 2], x+x+1, (ll+rr+1)/2, rr);
        }
    }

};

#define maxn 300005
LL a[maxn], suma[maxn];
geo_seq_tree tree;

int main(){
    ios_base::sync_with_stdio(false);
    id.t[0][0] = id.t[1][1] =1;
    q.t[0][0] = q.t[0][1] = q.t[1][0] = 1;

    qpot[0] = id;
    qpotsum[0] = id;
    fup(i, 1, 2 * base) qpot[i] = q * qpot[i - 1], qpotsum[i] = qpotsum[i - 1] + qpot[i];

    int n, m;
    cin >> n >> m;
    fup(i, 1, n) { cin >> a[i]; suma[i] = (suma[i - 1] + a[i]) % mod; }
    fup(i, 1, m) {
        int typ, l, r;
        cin >> typ >> l >> r;
        if (typ == 1) {
            tree.add(l, r);
        } else {
           LL s1 = (suma[r] - suma[l - 1] + mod) % mod;
           M s2 = tree.get(l, r, zero);
           cout << (s1 + s2.t[0][0]) % mod << endl;
        }
    }

    return 0;
}


#include <iostream>
#include <fstream>
#include <vector>
#include <memory.h>
#include <string>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>
#include <assert.h>
#include <queue>
#include <sstream>

using namespace std;

const int MOD = 1000000009;

int treeSum[1500000];
pair <int, int> f[1500000];
int n, m, v, l, r;
int a[1000000];
int S[1000000], F[1000000];

void buildTree(int v, int l, int r) {
    f[v].first = -1;
    f[v].second = -1;
    if (l == r) {
        treeSum[v] = a[l];
        return;
    }
    int m = (l + r) / 2;
    buildTree(v + v, l, m);
    buildTree(v + v + 1, m + 1, r);
    treeSum[v] = (treeSum[v + v] + treeSum[v + v + 1]);
    if (treeSum[v] >= MOD) treeSum[v] -= MOD;
}

inline int get(int l, int r) {
    int e = S[r] - S[l - 1];
    if (e < 0) e += MOD;
    return e;
}

void add(int &a, int b) {
    a += b;
    if (a >= MOD) a -= MOD;
}

inline void push(int v, int l, int r) {
    if (l == r) return ;
    if (f[v].first != -1) {
        int m = (l + r) / 2;
        int cnt = m - l + 1;
        if (f[v + v].first != -1) push(v + v, l, m);
        if (f[v + v + 1].first != -1) push(v + v + 1, m + 1, r);
        f[v + v].first = f[v].first;
        f[v + v].second = f[v].first + cnt - 1;
        add(treeSum[v + v], get(f[v + v].first, f[v + v].second));
        f[v + v + 1].first = f[v].first + cnt;
        f[v + v + 1].second = f[v].second;
        add(treeSum[v + v + 1], get(f[v + v + 1].first, f[v + v + 1].second));
    }
    f[v].first = -1;
    f[v].second = -1;
}

void update(int v, int l, int r, int ll, int rr, int lFib, int rFib) {
    if (l != r) push(v, l, r);
    if (l == ll && r == rr) {
        f[v] = make_pair(lFib, rFib);
        if (l != r) push(v, l, r);
        int vv = v;
        int e = S[rFib] - S[lFib - 1];
        if (e < 0) e += MOD;
        while (vv >= 1) {
            add(treeSum[vv], e);
            vv /= 2;
        }
        return;
    }

    int m = (l + r) / 2;
    if (m >= rr) update(v + v, l, m, ll, rr, lFib, rFib);
    else if (m < ll) update(v + v + 1, m + 1, r, ll, rr, lFib, rFib);
    else {
        int cnt = m - ll + 1;
        update(v + v, l, m, ll, m, lFib, lFib + cnt - 1);
        update(v + v + 1, m + 1, r, m + 1, rr, lFib + cnt, rFib);
    }
    push(v, l, r);
    treeSum[v] = treeSum[v + v];
    add(treeSum[v], treeSum[v + v + 1]);
}

int getAnswer(int v, int l, int r, int ll, int rr) {
    if (l != r) push(v, l, r);
    if (l == ll && r == rr) return treeSum[v];
    int m = (l + r) / 2;
    if (m >= rr) return getAnswer(v + v, l, m, ll, rr);
    else if (m < ll) return getAnswer(v + v + 1, m + 1, r, ll, rr);
    else {
        int ret = getAnswer(v + v, l, m, ll, m), x = getAnswer(v + v + 1, m + 1, r, m + 1, rr);
        add(ret, x);
        return ret;
    }
}

void rebuild(int v, int l, int r) {
    push(v, l, r);
    if (l == r) return;
    int m = (l + r) / 2;
    rebuild(v + v, l, m);
    rebuild(v + v + 1, m + 1, r);
    treeSum[v] = treeSum[v + v];
    add(treeSum[v], treeSum[v + v + 1]);
}

int main(){
    scanf("%d%d",&n,&m);
    F[1] = 1;
    F[2] = 1;
    for (int i = 3; i <= n + n; ++i) {
        F[i] = F[i - 1] + F[i - 2];
        if (F[i] >= MOD) F[i] -= MOD;
    }
    for (int i = 1; i <= n + n; ++i) {
        S[i] = S[i - 1] + F[i];
        if (S[i] >= MOD) S[i] -= MOD;
    }
    for (int i = 0; i < n; ++i) {
        scanf("%d", &a[i]);
    }
    buildTree(1, 0, n - 1);
    for (int i = 0; i < m; ++i) {
        scanf("%d%d%d", &v, &l, &r);
        if (i % 1000 == 0) rebuild(1, 0, n - 1);
        l--; r--;
        if (v == 1) {
            update(1, 0, n - 1, l, r, 1, r - l + 1);
        }
        else {
            int ans = getAnswer(1, 0, n - 1, l, r);
            printf("%d\n", ans);
        }
    }
    return 0;
}


#include <iostream>
#include <fstream>
#include <vector>
#include <memory.h>
#include <string>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>
#include <assert.h>
#include <queue>
#include <sstream>

using namespace std;

const int MOD = 1000000009;

int treeSum[1500000];
pair <int, int> f[1500000];
int n, m, v, l, r;
int a[1000000];
int S[1000000], F[1000000];

void buildTree(int v, int l, int r) {
    f[v].first = 0;
    f[v].second = 0;
    if (l == r) {
        treeSum[v] = a[l];
        return;
    }
    int m = (l + r) / 2;
    buildTree(v + v, l, m);
    buildTree(v + v + 1, m + 1, r);
    treeSum[v] = (treeSum[v + v] + treeSum[v + v + 1]);
    if (treeSum[v] >= MOD) treeSum[v] -= MOD;
}

int get(long long a, long long b, int len) {
    len--;
    long long ret = a;
    ret = (ret + b * S[len]) % MOD;
    if (len > 0) ret = (ret + b * S[len - 1]) % MOD;
    return ret;
}

void add(int &a, int b) {
    a += b;
    if (a >= MOD) a -= MOD;
}

void push(int v, int l, int r) {
    if (f[v].first != 0) {
        add(f[v + v].first, f[v].first);
        add(f[v + v].second, f[v].second);
        int m = (l + r) / 2;
        int ret = get(f[v].first, f[v].second, m - l + 1);
        add(treeSum[v + v], ret);
        int len = m - l + 1;
        long long tmp = (1LL * f[v].first * F[len - 1] + 1LL * f[v].second * F[len]) % MOD;
        add(f[v + v + 1].first, tmp);
        tmp = (1LL * f[v].first * F[len] + 1LL * f[v].second * F[len + 1]) % MOD;
        add(f[v + v + 1].second, tmp);
        ret = get((1LL * f[v].first * F[len - 1] + 1LL * f[v].second * F[len]) % MOD,
                  (1LL * f[v].first * F[len] + 1LL * f[v].second * F[len + 1]) % MOD, r - m);
        add(treeSum[v + v + 1], ret);
    }
    f[v].first = 0;
    f[v].second = 0;
}

void update(int v, int l, int r, int ll, int rr, int lF) {
    if (l != r) push(v, l, r);
    if (l == ll && r == rr) {
        if (l == r) {
            int vv = v;
            while (vv > 0) {
                add(treeSum[vv], F[lF]);
                vv /= 2;
            }
            return;
        }
        add(f[v].first, F[lF]);
        add(f[v].second, F[lF+1]);
        int ret = get(f[v].first, f[v].second, r - l + 1);
        int vv = v;
        while (vv > 0) {
            add(treeSum[vv], ret);
            vv /= 2;
        }
        return ;
    }
    int m = (l + r) / 2;
    if (m >= rr) update(v + v, l, m, ll, rr, lF);
    else if (m < ll) update(v + v + 1, m + 1, r, ll, rr, lF);
    else {
        update(v + v, l, m, ll, m, lF);
        update(v + v + 1, m + 1, r, m + 1, rr, lF + m - ll + 1);
    }
    push(v, l, r);
}

int getA(int v, int l, int r, int ll, int rr) {
    if (l != r) push(v, l, r);
    if (l == ll && r == rr) {
    //        cout << treeSum[v] << " " << ll << " " << rr << endl;
            return treeSum[v];
    }
    int m = (l + r) / 2;
    if (m >= rr) return getA(v + v, l, m, ll, rr);
    else if (m < ll) return getA(v + v + 1, m + 1, r, ll, rr);
    else {
        int ret = getA(v + v, l, m, ll, m);
        int ans = getA(v + v + 1, m + 1, r, m + 1, rr);
        add(ret, ans);
        return ret;
    }
}

int main(){
    scanf("%d%d",&n,&m);
    F[1] = 1;
    F[2] = 1;
    for (int i = 3; i <= n + n; ++i) {
        F[i] = F[i - 1] + F[i - 2];
        if (F[i] >= MOD) F[i] -= MOD;
    }
    for (int i = 1; i <= n + n; ++i) {
        S[i] = S[i - 1] + F[i];
        if (S[i] >= MOD) S[i] -= MOD;
    }
    for (int i = 0; i < n; ++i) {
        scanf("%d", &a[i]);
    }
    buildTree(1, 0, n - 1);

    for (int i = 0; i < m; ++i) {
        scanf("%d%d%d",&v, &l, &r);
        l--; r--;
        if (v == 1) update(1, 0, n - 1, l, r, 1);
        else {
            int ret = getA(1, 0, n - 1, l, r);
            printf("%d\n", ret);
        }
    }
    return 0;
}


#include <iostream>
#include <fstream>
#include <vector>
#include <memory.h>
#include <string>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>
#include <assert.h>
#include <queue>
#include <sstream>

using namespace std;

const int MOD = 1000000009;

int treeSum[1500000];
pair <int, int> f[1500000];
int n, m, v, l, r;
int a[1000000];
int S[1000000], F[1000000];

void buildTree(int v, int l, int r) {
    f[v].first = -1;
    f[v].second = -1;
    if (l == r) {
        treeSum[v] = a[l];
        return;
    }
    int m = (l + r) / 2;
    buildTree(v + v, l, m);
    buildTree(v + v + 1, m + 1, r);
    treeSum[v] = (treeSum[v + v] + treeSum[v + v + 1]);
    if (treeSum[v] >= MOD) treeSum[v] -= MOD;
}

inline int get(int l, int r) {
    int e = S[r] - S[l - 1];
    if (e < 0) e += MOD;
    return e;
}

void add(int &a, int b) {
    a += b;
    if (a >= MOD) a -= MOD;
}

inline void push(int v, int l, int r) {
    if (l == r) return ;
    if (f[v].first != -1) {
        int m = (l + r) / 2;
        int cnt = m - l + 1;
        if (f[v + v].first != -1) push(v + v, l, m);
        if (f[v + v + 1].first != -1) push(v + v + 1, m + 1, r);
        f[v + v].first = f[v].first;
        f[v + v].second = f[v].first + cnt - 1;
        add(treeSum[v + v], get(f[v + v].first, f[v + v].second));
        f[v + v + 1].first = f[v].first + cnt;
        f[v + v + 1].second = f[v].second;
        add(treeSum[v + v + 1], get(f[v + v + 1].first, f[v + v + 1].second));
    }
    f[v].first = -1;
    f[v].second = -1;
}

void update(int v, int l, int r, int ll, int rr, int lFib, int rFib) {
    if (l != r) push(v, l, r);
    if (l == ll && r == rr) {
        f[v] = make_pair(lFib, rFib);
        if (l != r) push(v, l, r);
        int vv = v;
        int e = S[rFib] - S[lFib - 1];
        if (e < 0) e += MOD;
        while (vv >= 1) {
            add(treeSum[vv], e);
            vv /= 2;
        }
        return;
    }

    int m = (l + r) / 2;
    if (m >= rr) update(v + v, l, m, ll, rr, lFib, rFib);
    else if (m < ll) update(v + v + 1, m + 1, r, ll, rr, lFib, rFib);
    else {
        int cnt = m - ll + 1;
        update(v + v, l, m, ll, m, lFib, lFib + cnt - 1);
        update(v + v + 1, m + 1, r, m + 1, rr, lFib + cnt, rFib);
    }
    push(v, l, r);
    treeSum[v] = treeSum[v + v];
    add(treeSum[v], treeSum[v + v + 1]);
}

int getAnswer(int v, int l, int r, int ll, int rr) {
    if (l != r) push(v, l, r);
    if (l == ll && r == rr) return treeSum[v];
    int m = (l + r) / 2;
    if (m >= rr) return getAnswer(v + v, l, m, ll, rr);
    else if (m < ll) return getAnswer(v + v + 1, m + 1, r, ll, rr);
    else {
        int ret = getAnswer(v + v, l, m, ll, m), x = getAnswer(v + v + 1, m + 1, r, m + 1, rr);
        add(ret, x);
        return ret;
    }
}

void rebuild(int v, int l, int r) {
    push(v, l, r);
    if (l == r) return;
    int m = (l + r) / 2;
    rebuild(v + v, l, m);
    rebuild(v + v + 1, m + 1, r);
    treeSum[v] = treeSum[v + v];
    add(treeSum[v], treeSum[v + v + 1]);
}

int main(){
    scanf("%d%d",&n,&m);
    F[1] = 1;
    F[2] = 1;
    for (int i = 3; i <= n + n; ++i) {
        F[i] = F[i - 1] + F[i - 2];
        if (F[i] >= MOD) F[i] -= MOD;
    }
    for (int i = 1; i <= n + n; ++i) {
        S[i] = S[i - 1] + F[i];
        if (S[i] >= MOD) S[i] -= MOD;
    }
    for (int i = 0; i < n; ++i) {
        scanf("%d", &a[i]);
    }
    buildTree(1, 0, n - 1);
    for (int i = 0; i < m; ++i) {
        scanf("%d%d%d", &v, &l, &r);
        if (i % 300 == 0) rebuild(1, 0, n - 1);
        l--; r--;
        if (v == 1) {
            update(1, 0, n - 1, l, r, 1, r - l + 1);
        }
        else {
            int ans = getAnswer(1, 0, n - 1, l, r);
            printf("%d\n", ans);
        }
    }
    return 0;
}


#include <iostream>
#include <fstream>
#include <vector>
#include <memory.h>
#include <string>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>
#include <assert.h>
#include <queue>
#include <sstream>

using namespace std;

const int MOD = 1000000009;

int treeSum[1500000];
pair <int, int> f[1500000];
int n, m, v, l, r;
int a[1000000];
int S[1000000], F[1000000];

void buildTree(int v, int l, int r) {
    f[v].first = 0;
    f[v].second = 0;
    if (l == r) {
        treeSum[v] = a[l];
        return;
    }
    int m = (l + r) / 2;
    buildTree(v + v, l, m);
    buildTree(v + v + 1, m + 1, r);
    treeSum[v] = (treeSum[v + v] + treeSum[v + v + 1]);
    if (treeSum[v] >= MOD) treeSum[v] -= MOD;
}

int get(long long a, long long b, int len) {
    len--;
    long long ret = a;
    ret = (ret + b * S[len]) % MOD;
    if (len > 0) ret = (ret + b * S[len - 1]) % MOD;
    return ret;
}

void add(int &a, int b) {
    a += b;
    if (a >= MOD) a -= MOD;
}

void push(int v, int l, int r) {
    if (f[v].first != 0) {
        add(f[v + v].first, f[v].first);
        add(f[v + v].second, f[v].second);
        int m = (l + r) / 2;
        int ret = get(f[v].first, f[v].second, m - l + 1);
        add(treeSum[v + v], ret);
        int len = m - l + 1;
        long long tmp = (1LL * f[v].first * F[len - 1] + 1LL * f[v].second * F[len]) % MOD;
        add(f[v + v + 1].first, tmp);
        tmp = (1LL * f[v].first * F[len] + 1LL * f[v].second * F[len + 1]) % MOD;
        add(f[v + v + 1].second, tmp);
        ret = get(f[v].first, f[v].second, r - m);
        add(treeSum[v + v + 1], ret);
    }
    f[v].first = 0;
    f[v].second = 0;
}

void update(int v, int l, int r, int ll, int rr, int lF) {
    if (l != r) push(v, l, r);
    if (l == ll && r == rr) {
        if (l == r) {
            int vv = v;
            while (vv > 0) {
                add(treeSum[vv], F[lF]);
                vv /= 2;
            }
            return;
        }
        add(f[v].first, F[lF]);
        add(f[v].second, F[lF+1]);
        int ret = get(f[v].first, f[v].second, r - l + 1);
        int vv = v;
        while (vv > 0) {
            add(treeSum[vv], ret);
            vv /= 2;
        }
        return ;
    }
    int m = (l + r) / 2;
    if (m >= rr) update(v + v, l, m, ll, rr, lF);
    else if (m < ll) update(v + v + 1, m + 1, r, ll, rr, lF);
    else {
        update(v + v, l, m, ll, m, lF);
        update(v + v + 1, m + 1, r, m + 1, r, lF + m - ll + 1);
    }
    push(v, l, r);
}

int getA(int v, int l, int r, int ll, int rr) {
    if (l != r) push(v, l, r);
    if (l == ll && r == rr) {
    //        cout << treeSum[v] << " " << ll << " " << rr << endl;
            return treeSum[v];
    }
    int m = (l + r) / 2;
    if (m >= rr) return getA(v + v, l, m, ll, rr);
    else if (m < ll) return getA(v + v + 1, m + 1, r, ll, rr);
    else {
        int ret = getA(v + v, l, m, ll, m);
        int ans = getA(v + v + 1, m + 1, r, m + 1, rr);
        add(ret, ans);
        return ret;
    }
}

int main(){
    scanf("%d%d",&n,&m);
    F[1] = 1;
    F[2] = 1;
    for (int i = 3; i <= n + n; ++i) {
        F[i] = F[i - 1] + F[i - 2];
        if (F[i] >= MOD) F[i] -= MOD;
    }
    for (int i = 1; i <= n + n; ++i) {
        S[i] = S[i - 1] + F[i];
        if (S[i] >= MOD) S[i] -= MOD;
    }
    for (int i = 0; i < n; ++i) {
        scanf("%d", &a[i]);
    }
    buildTree(1, 0, n - 1);
    for (int i = 0; i < m; ++i) {
        scanf("%d%d%d",&v, &l, &r);
        l--; r--;
        if (v == 1) update(1, 0, n - 1, l, r, 1);
        else {
            int ret = getA(1, 0, n - 1, l, r);
            printf("%d\n", ret);
        }
    }
    return 0;
}


#include <iostream>
#include <fstream>
#include <vector>
#include <memory.h>
#include <string>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>
#include <assert.h>
#include <queue>
#include <sstream>

using namespace std;

const int MOD = 1000000009;

int treeSum[1500000];
pair <int, int> f[1500000];
int n, m, v, l, r;
int a[1000000];
int S[1000000], F[1000000];

void buildTree(int v, int l, int r) {
    f[v].first = -1;
    f[v].second = -1;
    if (l == r) {
        treeSum[v] = a[l];
        return;
    }
    int m = (l + r) / 2;
    buildTree(v + v, l, m);
    buildTree(v + v + 1, m + 1, r);
    treeSum[v] = (treeSum[v + v] + treeSum[v + v + 1]);
    if (treeSum[v] >= MOD) treeSum[v] -= MOD;
}

inline int get(int l, int r) {
    int e = S[r] - S[l - 1];
    if (e < 0) e += MOD;
    return e;
}

void add(int &a, int b) {
    a += b;
    if (a >= MOD) a -= MOD;
}

inline void push(int v, int l, int r) {
    if (l == r) return ;
    if (f[v].first != -1) {
        int m = (l + r) / 2;
        int cnt = m - l + 1;
        if (f[v + v].first != -1) push(v + v, l, m);
        if (f[v + v + 1].first != -1) push(v + v + 1, m + 1, r);
        f[v + v].first = f[v].first;
        f[v + v].second = f[v].first + cnt - 1;
        add(treeSum[v + v], get(f[v + v].first, f[v + v].second));
        f[v + v + 1].first = f[v].first + cnt;
        f[v + v + 1].second = f[v].second;
        add(treeSum[v + v + 1], get(f[v + v + 1].first, f[v + v + 1].second));
    }
    f[v].first = -1;
    f[v].second = -1;
}

void update(int v, int l, int r, int ll, int rr, int lFib, int rFib) {
    if (l != r) push(v, l, r);
    if (l == ll && r == rr) {
        f[v] = make_pair(lFib, rFib);
        if (l != r) push(v, l, r);
        int vv = v;
        int e = S[rFib] - S[lFib - 1];
        if (e < 0) e += MOD;
        while (vv >= 1) {
            add(treeSum[vv], e);
            vv /= 2;
        }
        return;
    }

    int m = (l + r) / 2;
    if (m >= rr) update(v + v, l, m, ll, rr, lFib, rFib);
    else if (m < ll) update(v + v + 1, m + 1, r, ll, rr, lFib, rFib);
    else {
        int cnt = m - ll + 1;
        update(v + v, l, m, ll, m, lFib, lFib + cnt - 1);
        update(v + v + 1, m + 1, r, m + 1, rr, lFib + cnt, rFib);
    }
}

int getAnswer(int v, int l, int r, int ll, int rr) {
    if (l == ll && r == rr) return treeSum[v];
    if (l != r) push(v, l, r);
    int m = (l + r) / 2;
    if (m >= rr) return getAnswer(v + v, l, m, ll, rr);
    else if (m < ll) return getAnswer(v + v + 1, m + 1, r, ll, rr);
    else {
        int ret = getAnswer(v + v, l, m, ll, m), x = getAnswer(v + v + 1, m + 1, r, m + 1, rr);
        add(ret, x);
        return ret;
    }
}

int main(){
    scanf("%d%d",&n,&m);
    F[1] = 1;
    F[2] = 1;
    for (int i = 3; i <= n + n; ++i) {
        F[i] = F[i - 1] + F[i - 2];
        if (F[i] >= MOD) F[i] -= MOD;
    }
    for (int i = 1; i <= n + n; ++i) {
        S[i] = S[i - 1] + F[i];
        if (S[i] >= MOD) S[i] -= MOD;
    }
    for (int i = 0; i < n; ++i) {
        scanf("%d", &a[i]);
    }
    buildTree(1, 0, n - 1);
    for (int i = 0; i < m; ++i) {
        scanf("%d%d%d", &v, &l, &r);
        l--; r--;
        if (v == 1) {
            update(1, 0, n - 1, l, r, 1, r - l + 1);
        }
        else {
            int ans = getAnswer(1, 0, n - 1, l, r);
            printf("%d\n", ans);
        }
    }
    return 0;
}


#include <iostream>
#include <fstream>
#include <vector>
#include <memory.h>
#include <string>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>
#include <assert.h>
#include <queue>
#include <sstream>

using namespace std;

const int MOD = 1000000009;

int treeSum[1500000];
pair <int, int> f[1500000];
int n, m, v, l, r;
int a[1000000];
int S[1000000], F[1000000];

void buildTree(int v, int l, int r) {
    f[v].first = 0;
    f[v].second = 0;
    if (l == r) {
        treeSum[v] = a[l];
        return;
    }
    int m = (l + r) / 2;
    buildTree(v + v, l, m);
    buildTree(v + v + 1, m + 1, r);
    treeSum[v] = (treeSum[v + v] + treeSum[v + v + 1]);
    if (treeSum[v] >= MOD) treeSum[v] -= MOD;
}

int get(long long a, long long b, int len) {
    len--;
    long long ret = a;
    ret = (ret + b * S[len]) % MOD;
    if (len > 0) ret = (ret + a * S[len - 1]) % MOD;
    return ret;
}

void add(int &a, int b) {
    a += b;
    if (a >= MOD) a -= MOD;
}

void push(int v, int l, int r) {
    if (f[v].first != 0) {
        add(f[v + v].first, f[v].first);
        add(f[v + v].second, f[v].second);
        int m = (l + r) / 2;
        int ret = get(f[v].first, f[v].second, m - l + 1);
        add(treeSum[v + v], ret);
        int len = m - l + 1;
        long long tmp = (1LL * f[v].first * F[len - 1] + 1LL * f[v].second * F[len]) % MOD;
        add(f[v + v + 1].first, tmp);
        tmp = (1LL * f[v].first * F[len] + 1LL * f[v].second * F[len + 1]) % MOD;
        add(f[v + v + 1].second, tmp);
        ret = get((1LL * f[v].first * F[len - 1] + 1LL * f[v].second * F[len]) % MOD,
                  (1LL * f[v].first * F[len] + 1LL * f[v].second * F[len + 1]) % MOD, r - m);
        add(treeSum[v + v + 1], ret);
    }
    f[v].first = 0;
    f[v].second = 0;
}

void update(int v, int l, int r, int ll, int rr, int lF) {
    if (l != r) push(v, l, r);
    if (l == ll && r == rr) {
        if (l == r) {
            int vv = v;
            while (vv > 0) {
                add(treeSum[vv], F[lF]);
                vv /= 2;
            }
            return;
        }
        add(f[v].first, F[lF]);
        add(f[v].second, F[lF+1]);
        int ret = get(F[lF], F[lF+1], r - l + 1);
        int vv = v;
        while (vv > 0) {
            add(treeSum[vv], ret);
            vv /= 2;
        }
        return ;
    }
    int m = (l + r) / 2;
    if (m >= rr) update(v + v, l, m, ll, rr, lF);
    else if (m < ll) update(v + v + 1, m + 1, r, ll, rr, lF);
    else {
        update(v + v, l, m, ll, m, lF);
        update(v + v + 1, m + 1, r, m + 1, rr, lF + m - ll + 1);
    }
    push(v, l, r);
}

int getA(int v, int l, int r, int ll, int rr) {
    if (l != r) push(v, l, r);
    if (l == ll && r == rr) {
            return treeSum[v];
    }
    int m = (l + r) / 2;
    if (m >= rr) return getA(v + v, l, m, ll, rr);
    else if (m < ll) return getA(v + v + 1, m + 1, r, ll, rr);
    else {
        int ret = getA(v + v, l, m, ll, m);
        int ans = getA(v + v + 1, m + 1, r, m + 1, rr);
        add(ret, ans);
        return ret;
    }
}

int main(){
    scanf("%d%d",&n,&m);
    F[1] = 1;
    F[2] = 1;
    for (int i = 3; i <= n + n; ++i) {
        F[i] = F[i - 1] + F[i - 2];
        if (F[i] >= MOD) F[i] -= MOD;
    }
    for (int i = 1; i <= n + n; ++i) {
        S[i] = S[i - 1] + F[i];
        if (S[i] >= MOD) S[i] -= MOD;
    }
    for (int i = 0; i < n; ++i) {
        scanf("%d", &a[i]);
    }
    buildTree(1, 0, n - 1);

    for (int i = 0; i < m; ++i) {
        scanf("%d%d%d",&v, &l, &r);
        l--; r--;
        if (v == 1) update(1, 0, n - 1, l, r, 1);
        else {
            int ret = getA(1, 0, n - 1, l, r);
            printf("%d\n", ret);
        }
    }
    return 0;
}


#include <iostream>
#include <fstream>
#include <vector>
#include <memory.h>
#include <string>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>
#include <assert.h>
#include <queue>
#include <sstream>

using namespace std;

const int MOD = 1000000009;

int treeSum[1500000];
pair <int, int> f[1500000];
int n, m, v, l, r;
int a[1000000];
int S[1000000], F[1000000];

void buildTree(int v, int l, int r) {
    f[v].first = 0;
    f[v].second = 0;
    if (l == r) {
        treeSum[v] = a[l];
        return;
    }
    int m = (l + r) / 2;
    buildTree(v + v, l, m);
    buildTree(v + v + 1, m + 1, r);
    treeSum[v] = (treeSum[v + v] + treeSum[v + v + 1]);
    if (treeSum[v] >= MOD) treeSum[v] -= MOD;
}

int get(long long a, long long b, int len) {
    len--;
    long long ret = a;
    ret = (ret + b * S[len]) % MOD;
    if (len > 0) ret = (ret + b * S[len - 1]) % MOD;
    return ret;
}

void add(int &a, int b) {
    a += b;
    if (a >= MOD) a -= MOD;
}

void push(int v, int l, int r) {
    if (f[v].first != 0) {
        add(f[v + v].first, f[v].first);
        add(f[v + v].second, f[v].second);
        int m = (l + r) / 2;
        int ret = get(f[v].first, f[v].second, m - l + 1);
        add(treeSum[v + v], ret);
        int len = m - l + 1;
        long long tmp = (1LL * f[v].first * F[len - 1] + 1LL * f[v].second * F[len]) % MOD;
        add(f[v + v + 1].first, tmp);
        tmp = (1LL * f[v].first * F[len] + 1LL * f[v].second * F[len + 1]) % MOD;
        add(f[v + v + 1].second, tmp);
        ret = get((1LL * f[v].first * F[len - 1] + 1LL * f[v].second * F[len]) % MOD,
                  (1LL * f[v].first * F[len] + 1LL * f[v].second * F[len + 1]) % MOD, r - m);
        add(treeSum[v + v + 1], ret);
    }
    f[v].first = 0;
    f[v].second = 0;
}

void update(int v, int l, int r, int ll, int rr, int lF) {
    if (l != r) push(v, l, r);
    if (l == ll && r == rr) {
        if (l == r) {
            int vv = v;
            while (vv > 0) {
                add(treeSum[vv], F[lF]);
                vv /= 2;
            }
            return;
        }
        add(f[v].first, F[lF]);
        add(f[v].second, F[lF+1]);
        int ret = get(F[lF], F[lF+1], r - l + 1);
        int vv = v;
        while (vv > 0) {
            add(treeSum[vv], ret);
            vv /= 2;
        }
        return ;
    }
    int m = (l + r) / 2;
    if (m >= rr) update(v + v, l, m, ll, rr, lF);
    else if (m < ll) update(v + v + 1, m + 1, r, ll, rr, lF);
    else {
        update(v + v, l, m, ll, m, lF);
        update(v + v + 1, m + 1, r, m + 1, rr, lF + m - ll + 1);
    }
    push(v, l, r);
}

int getA(int v, int l, int r, int ll, int rr) {
    if (l != r) push(v, l, r);
    if (l == ll && r == rr) {
            return treeSum[v];
    }
    int m = (l + r) / 2;
    if (m >= rr) return getA(v + v, l, m, ll, rr);
    else if (m < ll) return getA(v + v + 1, m + 1, r, ll, rr);
    else {
        int ret = getA(v + v, l, m, ll, m);
        int ans = getA(v + v + 1, m + 1, r, m + 1, rr);
        add(ret, ans);
        return ret;
    }
}

int main(){
    scanf("%d%d",&n,&m);
    F[1] = 1;
    F[2] = 1;
    for (int i = 3; i <= n + n; ++i) {
        F[i] = F[i - 1] + F[i - 2];
        if (F[i] >= MOD) F[i] -= MOD;
    }
    for (int i = 1; i <= n + n; ++i) {
        S[i] = S[i - 1] + F[i];
        if (S[i] >= MOD) S[i] -= MOD;
    }
    for (int i = 0; i < n; ++i) {
        scanf("%d", &a[i]);
    }
    buildTree(1, 0, n - 1);

    for (int i = 0; i < m; ++i) {
        scanf("%d%d%d",&v, &l, &r);
        l--; r--;
        if (v == 1) update(1, 0, n - 1, l, r, 1);
        else {
            int ret = getA(1, 0, n - 1, l, r);
            printf("%d\n", ret);
        }
    }
    return 0;
}


#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <queue>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <memory.h>
#include <ctime>
#include <bitset>
#include <unordered_map>

using namespace std;

#define ABS(a) ((a>0)?a:-(a))
#define MIN(a,b) ((a<b)?(a):(b))
#define MAX(a,b) ((a<b)?(b):(a))
#define FOR(i,a,n) for (int i=(a);i<(n);++i)
#define FI(i,n) for (int i=0; i<(n); ++i)
#define pnt pair <int, int>
#define mp make_pair
#define PI 3.1415926535897
#define MEMS(a,b) memset(a,b,sizeof(a))
#define LL long long
#define U unsigned

const int N = 900;
const int M = 300100;
int mod = 1000000009;

int fib[300100];
int sfib[300100];
int add[300100];
int a[300100];
int sum[300100];
int oldsum[300100];
vector<pnt > q;
int n, m;
void build()
{
	FOR(i, 1, n + 1)
		add[i] = 0;
	FOR(i, 0, q.size())
	{
		int l = q[i].first;
		int r = q[i].second;
		add[l]++;
		if (add[l] >= mod)
			add[l] -= mod;
		add[r + 1] -= fib[r - l + 2];
		if (add[r + 1] < 0)
			add[r + 1] += mod;
		add[r + 2] -= fib[r - l + 1];
		if (add[r + 2] < 0)
			add[r + 2] += mod;
	}
	FOR(i, 2, n + 1)
	{
		add[i] += add[i - 1];
		if (add[i] >= mod)
			add[i] -= mod;
		add[i] += add[i - 2];
		if (add[i] >= mod)
			add[i] -= mod;
	}
	int v = 0;
	FOR(i, 1, n + 1)
	{
		oldsum[i] = sum[i];
	}
	FOR(i, 1, n + 1)
	{
		v = add[i];
		if (v >= mod)
			v -= mod;
		sum[i] = v;
		if (sum[i] >= mod)
			sum[i] -= mod;
		sum[i] += sum[i - 1];
		if (sum[i] >= mod)
			sum[i] -= mod;
	}
	FOR(i, 1, n + 1)
	{
		sum[i] += oldsum[i];
		if (sum[i] >= mod)
			sum[i] -= mod;
	}
}

int main()
{
#ifdef Fcdkbear
	freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);
	double beg = clock();
#endif

	fib[1] = 1;
	fib[2] = 1;
	FOR(i, 3, M)
	{
		fib[i] = fib[i - 1] + fib[i - 2];
		if (fib[i] >= mod)
			fib[i] -= mod;
	}
	FOR(i, 1, M)
	{
		sfib[i] = fib[i] + sfib[i - 1];
		if (sfib[i] >= mod)
			sfib[i] -= mod;
	}
	scanf("%d%d", &n, &m);
	FOR(i, 0, n)
	{
		scanf("%d", &a[i + 1]);
	}
	FOR(i, 1, n + 1)
	{
		sum[i] = a[i] + sum[i - 1];
		if (sum[i] >= mod)
			sum[i] -= mod;
	}
	FOR(i, 0, m)
	{
		if ((i%N) == 0)
		{
			build();
			q.clear();
		}
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		if (t == 1)
		{
			q.push_back(mp(l, r));
		}
		else
		{
			int res = sum[r] - sum[l - 1];
			if (res < 0)
				res += mod;
			FOR(j, 0, q.size())
			{
				int L = MAX(q[j].first, l);
				int R = MIN(q[j].second, r);
				if (R >= L)
				{
					int st = L - q[j].first + 1;
					int en = st + R - L;
					res += sfib[en];
					if (res >= mod)
						res -= mod;
					res -= sfib[st - 1];
					if (res < 0)
						res += mod;
				}
			}
			printf("%d\n", res);
		}
	}

#ifdef Fcdkbear
	double end = clock();
	fprintf(stderr, "*** Total time = %.3lf ***\n", (end - beg) / CLOCKS_PER_SEC);
#endif
	return 0;
}


//
//  B_543_div3.cpp
//  codeforses
//
//  Created by Regina on 07.03.2019.
//  Copyright © 2019 Regina. All rights reserved.
//

#include <stdio.h>
#include <iostream>
#include <vector>
#include <map>

int main() {
    int n, k;
    std::cin >> n >> k;
    int candy;
    std::map<int, int> map;
    for (int i = 0; i < n; ++i) {
        std::cin >> candy;
        map[candy % k]++;
    }
    int result = 0;
    if (map.find(0) != map.end()) {
        result += ((map[0] / 2) * 2);
        map[0] -= result;
    }
    for (auto& item : map) {
        if (map.find(k - item.first) != map.end()) {
            if (k - item.first != item.first) {
                result += (map[k - item.first] > map[item.first] ? 2 * map[item.first] : 2 * map[k - item.first]);
            }
            else {
                result += map[item.first];
            }
//            for (int i = 0; i < item.second; ++i) {
//                if (map[k - item.first] > 1) {
//                    result += 2;
//                    map[k - item.first]--;
//                }
//                else {
//                    break;
//                }
//            }
        }
        map[k - item.first] = 0;
        map[item.first] = 0;
    }
    std::cout << (result % 2 == 0 ? result : result - 1);
    return 0;
}


//
//  B_543_div3.cpp
//  codeforses
//
//  Created by Regina on 07.03.2019.
//  Copyright © 2019 Regina. All rights reserved.
//

#include <stdio.h>
#include <iostream>
#include <vector>

int main() {
    int n, k;
    std::cin >> n >> k;
    std::vector<int> candy(n);
    for (auto& can : candy) {
        std::cin >> can;
    }
    int result = 0, temp = -1;
    for (int i = 0; i < n - 1; ++i) {
        if ((candy[i] + candy[i + 1]) % k == 0) {
            result += 2;
            ++i;
        }
        else if (temp != -1) {
            if ((temp + candy[i]) % k == 0) {
                result += 2;
                temp = -1;
            }
        }
        else {
            temp = candy[i];
        }
    }
    std::cout << result;
    return 0;
}


//
//  B_543_div3.cpp
//  codeforses
//
//  Created by Regina on 07.03.2019.
//  Copyright © 2019 Regina. All rights reserved.
//

#include <stdio.h>
#include <iostream>
#include <vector>
#include <map>

int main() {
    int n, k;
    std::cin >> n >> k;
    int candy;
    std::map<int, int> map;
    for (int i = 0; i < n; ++i) {
        std::cin >> candy;
        map[candy % k] += 1;
    }
    int result = 0;
    if (map.find(0) != map.end()) {
        result += (map[0] / 2) * 2;
    }

    for (auto& item : map) {
        for (int i = 0; i < item.second; ++i) {
            if (map.find(k - item.first) != map.end()) {
                if (map[k - item.first] != 0) {
                    result += 2;
                    map[k - item.first] -= 1;
                }
            }
        }
        item.second = 0;
    }
    std::cout << result;
    return 0;
}


//
//  B_543_div3.cpp
//  codeforses
//
//  Created by Regina on 07.03.2019.
//  Copyright © 2019 Regina. All rights reserved.
//

#include <stdio.h>
#include <iostream>
#include <vector>
#include <map>

int main() {
    int n, k;
    std::cin >> n >> k;
    int candy;
    std::map<int, int> map;
    for (int i = 0; i < n; ++i) {
        std::cin >> candy;
        map[candy % k]++;
    }
    int result = 0;
    if (map.find(0) != map.end()) {
        result += ((map[0] / 2) * 2);
    }
    for (auto& item : map) {
        if (map.find(k - item.first) != map.end()) {
            for (int i = 0; i < item.second; ++i) {
                if (map[k - item.first] > 1) {
                    result += 2;
                    map[k - item.first] -= 1;
                }
                else {
                    break;
                }
            }
        }
        map[item.first] = 0;
    }
    std::cout << result;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){

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

ll n,k,x;
cin>>n>>k;
vector<ll>ch(n);
for(int i=0;i<n;i++){
    cin>>x;
    ++ch[x%k];
}
ll ans = 0;
ans += ch[0]/2;
if(k%2==0)
    ans+=ch[k/2]/2;
for(int i=1;i<(k+1)/2;++i){
    int j = k-i;
    ans+=min(ch[i],ch[j]);
}
cout<<ans*2<<endl;

return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main(){

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

int n,k;
cin>>n>>k;
vector<int>ch(n);
map<int,int>res;
for(int i=0;i<n;i++){
    cin>>ch[i];
    ch[i]=ch[i]%k;
    res[ch[i]]++;
}

int sum1=0,sum2=0;
for(int i=0;i<n;i++){
    if(ch[i]==0)
    {
        sum1++;
        continue;
    }
    if(res[ch[i]]>0 && res[k-ch[i]]>0)
    {
        sum2++;
        res[ch[i]]--;
        res[k-ch[i]]--;
    }
}

//cout<<sum1<<" "<<sum2<<endl;
cout<<(sum1/2)*2 + sum2*2<<endl;

return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){

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

 ll n,k;
cin>>n>>k;
vector<ll>ch(n);
map<ll,ll>res;
for(int i=0;i<n;i++){
    cin>>ch[i];
    ch[i]=ch[i]%k;
    res[ch[i]]++;
}

ll sum1=0,sum2=0;
for(int i=0;i<n;i++){
    if(ch[i]==0)
    {
        sum1++;
        continue;
    }
    if(res[ch[i]]>0 && res[k-ch[i]]>0)
    {
        sum2++;
        res[ch[i]]--;
        res[k-ch[i]]--;
    }
}

//cout<<sum1<<" "<<sum2<<endl;
cout<<(sum1/2)*2 + sum2*2<<endl;

return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){

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

ll n,k,x;
cin>>n>>k;
vector<ll>ch(n);
for(int i=0;i<n;i++){
    cin>>x;
    ch[x%k]++;
}
ll ans = 0;
ans += ch[0]/2;
if(k%2==0)
    ans+=ch[k/2]/2;
for(int i=1;i<(k+1)/2;i++){
    int j = k-i;
    ans+=min(ch[i],ch[j]);
}
cout<<ans*2<<endl;

return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){

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

ll n,k,x;
cin>>n>>k;
vector<ll>ch(n);
for(int i=0;i<n;i++){
    cin>>x;
    ++ch[x%k];
}
ll ans = 0;
ans += ch[0]/2;
if(k%2==0)
    ans+=ch[k/2]/2;
for(int i=1;i<(n+1)/2;++i){
    int j = k-i;
    ans+=min(ch[i],ch[j]);
}
cout<<ans*2<<endl;

return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){

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

ll n,k,x;
cin>>n>>k;
vector<ll>ch(n);
for(int i=0;i<n;i++){
    cin>>x;
    ++ch[x%k];
}
ll ans = 0;
ans += ch[0]/2;
if(k%2==0)
    ans+=ch[k/2]/2;
for(int i=1;i<(k+1)/2;i++){
    int j = k-i;
    ans+=min(ch[i],ch[j]);
}
cout<<ans*2<<endl;

return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){

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

ll n,k,x;
cin>>n>>k;
vector<ll>ch(n);
for(int i=0;i<n;i++){
    cin>>x;
    ch[x%k]++;
}

ll ans = ch[0]/2;
if(k%2==0)
    ans+=ch[k/2]/2;
for(int i=1;i<(k+1)/2;i++){
    int j = k-i;
    ans+=min(ch[i],ch[j]);
}
cout<<ans*2<<endl;

return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){

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

ll n,k,x;
cin>>n>>k;
vector<ll>ch(k);
for(int i=0;i<n;i++){
    cin>>x;
    ++ch[x%k];
}
ll ans = 0;
ans += ch[0]/2;
if(k%2==0)
    ans+=ch[k/2]/2;
for(int i=1;i<(k+1)/2;++i){
    int j = k-i;
    ans+=min(ch[i],ch[j]);
}
cout<<ans*2<<endl;

return 0;
}


#include <iostream>
#include <cmath>
#include <algorithm>
#include <stdio.h>
#include <cstring>
#include <string>
#include <cstdlib>
#include <vector>
#include <bitset>
#include <map>
#include <queue>
#include <ctime>
#include <stack>
#include <set>
#include <list>
#include <deque>
#include <iomanip>
#include <sstream>
#include <fstream>

#define pb push_back
#define mp make_pair
#define ll long long
using namespace std;
int res[1000];
int main()
{
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);
	int n, k;
	cin >> n >> k;
	int a;
	for (int i = 0; i < n; i++)
	{
		cin >> a;
		res[a%k]++;
	}
	int ans = res[0] / 2;
	for (int i = 1; i < (k + 1)/2; i++)
		ans += min(res[i], res[k - i]);
	cout << ans * 2<< '\n';
}


#include <iostream>
#include <cmath>
#include <algorithm>
#include <stdio.h>
#include <cstring>
#include <string>
#include <cstdlib>
#include <vector>
#include <bitset>
#include <map>
#include <queue>
#include <ctime>
#include <stack>
#include <set>
#include <list>
#include <deque>
#include <iomanip>
#include <sstream>
#include <fstream>

#define pb push_back
#define mp make_pair
#define ll long long
using namespace std;
int res[1000];
int main()
{
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);
	int n, k;
	cin >> n >> k;
	int a;
	for (int i = 0; i < n; i++)
	{
		cin >> a;
		res[a%k]++;
	}
	int ans = res[0] / 2 * 2;
	for (int i = 1; i <= k/2; i++)
		ans += max(res[i], res[k - i]) / 2 * 2;
	cout << ans << '\n';
}


#include <iostream>
#include <cmath>
#include <algorithm>
#include <stdio.h>
#include <cstring>
#include <string>
#include <cstdlib>
#include <vector>
#include <bitset>
#include <map>
#include <queue>
#include <ctime>
#include <stack>
#include <set>
#include <list>
#include <deque>
#include <iomanip>
#include <sstream>
#include <fstream>

#define pb push_back
#define mp make_pair
#define ll long long
using namespace std;
int res[1000];
int main()
{
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);
	int n, k;
	cin >> n >> k;
	int a;
	for (int i = 0; i < n; i++)
	{
		cin >> a;
		res[a%k]++;
	}
	int ans = res[0] /2 *2;
	for (int i = 1; i < k; i++)
		ans += max(res[i], res[k - i])/2;
	if(k%2 == 0)
		ans += res[k/2] / 2;
	cout << ans << '\n';
}


#include <iostream>
#include <cmath>
#include <algorithm>
#include <stdio.h>
#include <cstring>
#include <string>
#include <cstdlib>
#include <vector>
#include <bitset>
#include <map>
#include <queue>
#include <ctime>
#include <stack>
#include <set>
#include <list>
#include <deque>
#include <iomanip>
#include <sstream>
#include <fstream>

#define pb push_back
#define mp make_pair
#define ll long long
using namespace std;
int res[1000];
int main()
{
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);
	int n, k;
	cin >> n >> k;
	int a;
	for (int i = 0; i < n; i++)
	{
		cin >> a;
		res[a%k]++;
	}
	int ans = res[0] / 2;
	if (k % 2 == 0) ans += res[k / 2] / 2;
	for (int i = 1; i < (k + 1)/2; i++)
		ans += min(res[i], res[k - i]);
	cout << ans * 2<< '\n';
}


#include <iostream>
#include <cmath>
#include <algorithm>
#include <stdio.h>
#include <cstring>
#include <string>
#include <cstdlib>
#include <vector>
#include <bitset>
#include <map>
#include <queue>
#include <ctime>
#include <stack>
#include <set>
#include <list>
#include <deque>
#include <iomanip>
#include <sstream>
#include <fstream>

#define pb push_back
#define mp make_pair
#define ll long long
using namespace std;
int res[1000];
int main()
{
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);
	int n, k;
	cin >> n >> k;
	int a;
	for (int i = 0; i < n; i++)
	{
		cin >> a;
		res[a%k]++;
	}
	int ans = res[0] / 2 * 2;
	for (int i = 1; i < (k + 1) /2; i++)
		ans += max(res[i], res[k - i]) / 2 * 2;
	cout << ans << '\n';
}


#include <iostream>
#include <cmath>
#include <algorithm>
#include <stdio.h>
#include <cstring>
#include <string>
#include <cstdlib>
#include <vector>
#include <bitset>
#include <map>
#include <queue>
#include <ctime>
#include <stack>
#include <set>
#include <list>
#include <deque>
#include <iomanip>
#include <sstream>
#include <fstream>

#define pb push_back
#define mp make_pair
#define ll long long
using namespace std;
int res[1000];
int main()
{
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);
	int n, k;
	cin >> n >> k;
	int a;
	for (int i = 0; i < n; i++)
	{
		cin >> a;
		res[a%k]++;
	}
	int ans = res[0] / 2 * 2;
	for (int i = 1; i < (k + 1)/2; i++)
		ans += min(res[i], res[k - i]) / 2 * 2;
	cout << ans << '\n';
}


#include <iostream>
#include <cmath>
#include <algorithm>
#include <stdio.h>
#include <cstring>
#include <string>
#include <cstdlib>
#include <vector>
#include <bitset>
#include <map>
#include <queue>
#include <ctime>
#include <stack>
#include <set>
#include <list>
#include <deque>
#include <iomanip>
#include <sstream>
#include <fstream>

#define pb push_back
#define mp make_pair
#define ll long long
using namespace std;
int res[1000];
int main()
{
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);
	int n, k;
	cin >> n >> k;
	int a;
	for (int i = 0; i < n; i++)
	{
		cin >> a;
		res[a%k]++;
	}
	int ans = res[0] / 2 * 2;
	for (int i = 1; i <= k/2; i++)
		ans += min(res[i], res[k - i]) / 2 * 2;
	cout << ans << '\n';
}


#include<bits/stdc++.h>
using namespace std;
int main()
 {
	int t,n,i,j,k,e,val;

	cin>>n>>k;
vector<int>v(k,0);

	for(i=0;i<n;i++){
cin>>e;
		v[(e%k)]++;
	}
//if(v[0]==n){
//		int total=v[0]/2;
//	total=total*2;
//		cout<<total<<endl;
//		return 0;
//}
	int total=v[0]/2;
	total=total*2;
	for(i=1;i<k/2;i++){
		total+=min(v[i],v[k-i])*2;
	}
	if(k&1){
		total+=min(v[k/2],v[(k/2)+1])*2;
	}else{
		val=(v[k/2]/2);
		total+=val*2;
	}
	cout<<total<<endl;

}


#include<bits/stdc++.h>
using namespace std;
int main()
 {
	int t,n,i,j,k,e,val;

	cin>>n>>k;
vector<int>v(k,0);
	for(i=0;i<n;i++){
		scanf("%d",&e);
		v[(e%k)]++;
	}
	int total=v[0]/2;
	total=total*2;
	for(i=1;i<k/2;i++){
		total+=min(v[i],v[k-i])*2;
	}
	if(k&1){
		total+=min(v[k/2],v[(k/2)+1])*2;
	}else{
		val=(v[k/2]/2);
		total+=val*2;
	}
	cout<<total<<endl;

}


#include<bits/stdc++.h>
using namespace std;
int main()
 {
	int t,n,i,j,k,e,val;

	cin>>n>>k;
vector<int>v(k,0);
//for(i=0;i<k;i++)v[i]=0;
	for(i=0;i<n;i++){
//		scanf("%d",&e);
cin>>e;
		v[(e%k)]++;
	}
if(v[0]==n){
		int total=v[0]/2;
	total=total*2;
		cout<<total<<endl;
		return 0;
}
	int total=v[0]/2;
	total=total*2;
	for(i=1;i<k/2;i++){
		total+=min(v[i],v[k-i])*2;
	}
	if(k&1){
		total+=min(v[k/2],v[(k/2)+1])*2;
	}else{
		val=(v[k/2]/2);
		total+=val*2;
	}
	cout<<total<<endl;

}


#include<bits/stdc++.h>
using namespace std;
int main()
 {
	int t,n,i,j,k,e,val;

	cin>>n>>k;
vector<int>v(k,0);

	for(i=0;i<n;i++){
cin>>e;
		v[(e%k)]++;
	}
//if(v[0]==n){
//		int total=v[0]/2;
//	total=total*2;
//		cout<<total<<endl;
//		return 0;
//}
	int total=v[0]/2;
	total=total*2;
	for(i=1;i<k/2;i++){
		total+=min(v[i],v[k-i])*2;
	}
	if(k%2!=0){
		total+=min(v[k/2],v[(k/2)+1])*2;
	}else{
		val=(v[k/2]/2);
		total+=val*2;
	}
	cout<<total<<endl;

return 0;

}


#include<bits/stdc++.h>
using namespace std;
int main()
 {
	int t,n,i,j,k,e,val;

	cin>>n>>k;
vector<int>v(k,0);

//	for(i=0;i<n;i++){
//cin>>e;
//		v[(e%k)]++;
//	}
v[0]=2000;
//if(v[0]==n){
//		int total=v[0]/2;
//	total=total*2;
//		cout<<total<<endl;
//		return 0;
//}
	int total=v[0]/2;
	total=total*2;
	for(i=1;i<k/2;i++){
		total+=min(v[i],v[k-i])*2;
	}
	if(k&1){
		if(k==1)cout<<v[(k/2)+1]<<" "<<endl;
		total+=min(v[k/2],v[(k/2)+1])*2;
	}else{
		val=(v[k/2]/2);
		total+=val*2;
	}
	cout<<total<<endl;

return 0;

}


#include<bits/stdc++.h>
using namespace std;
int main()
 {
	int t,n,i,j,k,e,val;

	cin>>n>>k;
vector<int>v(k,0);

	for(i=0;i<n;i++){
cin>>e;
		v[(e%k)]++;
	}
if(v[0]==n){
		int total=v[0]/2;
	total=total*2;
		cout<<total<<endl;
		return 0;
}
	int total=v[0]/2;
	total=total*2;
	for(i=1;i<k/2;i++){
		total+=min(v[i],v[k-i])*2;
	}
	if(k&1){
		total+=min(v[k/2],v[(k/2)+1])*2;
	}else{
		val=(v[k/2]/2);
		total+=val*2;
	}
	cout<<total<<endl;

return 0;

}


#include<bits/stdc++.h>
using namespace std;
int main()
 {
	int t,n,i,j,k,e,val;

	cin>>n>>k;
vector<int>v(k,0);

	for(i=0;i<n;i++){
cin>>e;
		v[(e%k)]++;
	}
//if(v[0]==n){
//		int total=v[0]/2;
//	total=total*2;
//		cout<<total<<endl;
//		return 0;
//}
	int total=v[0]/2;
	total=total*2;
	for(i=1;i<k/2;i++){
		total+=min(v[i],v[k-i])*2;
	}
	if(k&1){
		total+=min(v[k/2],v[(k/2)+1])*2;
	}else{
		val=(v[k/2]/2);
		total+=val*2;
	}
	cout<<total<<endl;

return 0;

}


#include<bits/stdc++.h>
using namespace std;
int main()
 {
	int t,n,i,j,k,e;

	cin>>n>>k;
vector<int>v(k,0);
	for(i=0;i<n;i++){
		scanf("%d",&e);
		v[e%k]++;
	}
	int total=v[0]/2;
	total=total*2;
	for(i=1;i<k/2;i++){
		total+=min(v[i],v[k-i])*2;
	}
	if(k&1){
		total+=min(v[k/2],v[(k/2)+1])*2;
	}else{
		total+=(v[k/2]/2)*2;
	}
	cout<<total<<endl;

}


#include<bits/stdc++.h>
using namespace std;
int main()
 {
	int t,n,i,j,k,e,val;

	cin>>n>>k;
vector<int>v(k,0);

	for(i=0;i<n;i++){
cin>>e;
		v[(e%k)]++;
	}

//if(v[0]==n){
//		int total=v[0]/2;
//	total=total*2;
//		cout<<total<<endl;
//		return 0;
//}
	int total=v[0]/2;
	total=total*2;
	for(i=1;i<k/2;i++){
		total+=min(v[i],v[k-i])*2;
	}
	if(k&1){
		if(k==1)cout<<v[(k/2)+1]<<" "<<endl;
		total+=min(v[k/2],v[(k/2)+1])*2;
	}else{
		val=(v[k/2]/2);
		total+=val*2;
	}
	cout<<total<<endl;

return 0;

}


#include<bits/stdc++.h>
using namespace std;
int main()
 {
	int t,n,i,j,k,e,val;

	cin>>n>>k;
vector<int>v(k+1,0);

	for(i=0;i<n;i++){
cin>>e;
		v[(e%k)]++;
	}

//if(v[0]==n){
//		int total=v[0]/2;
//	total=total*2;
//		cout<<total<<endl;
//		return 0;
//}
	int total=v[0]/2;
	total=total*2;
	for(i=1;i<k/2;i++){
		total+=min(v[i],v[k-i])*2;
	}
	if(k&1){
		if(k>1)total+=min(v[k/2],v[(k/2)+1])*2;
	}else{
		val=(v[k/2]/2);
		total+=val*2;
	}
	cout<<total<<endl;

return 0;

}


#include<bits/stdc++.h>
using namespace std;
int main()
 {
	int t,n,i,j,k,e;

	cin>>n>>k;
	vector<int>v(k,0);
	for(i=0;i<n;i++){
		scanf("%d",&e);
		v[e%k]++;
	}
	int total=0;
	total=v[0]/2;
	if(k&1){
		for(i=1;i<=((k/2));i++){
		total+=min(v[i],v[k-i]);
	}

cout<<total<<endl;
	}else{
			for(i=1;i<((k/2));i++){
		total+=min(v[i],v[k-i]);
	}
	total+=v[k/2]/2;
cout<<total<<endl;
	}

}


#include<bits/stdc++.h>
using namespace std;
int main()
 {
	int t,n,i,j,k,e,val;

	cin>>n>>k;
vector<int>v(k,0);
for(i=0;i<k;i++)v[i]=0;
	for(i=0;i<n;i++){
		scanf("%d",&e);
		v[(e%k)]++;
	}
//v[0]=n;
	int total=v[0]/2;
	total=total*2;
	for(i=1;i<k/2;i++){
		total+=min(v[i],v[k-i])*2;
	}
	if(k&1){
		total+=min(v[k/2],v[(k/2)+1])*2;
	}else{
		val=(v[k/2]/2);
		total+=val*2;
	}
	cout<<total<<endl;

}


#include<bits/stdc++.h>
using namespace std;
int main()
{
        int n,k;
        cin>>n>>k;
        int a[n];
        vector<int>v;
        int count=0;
        for(int i=0;i<n;i++)
        {
                cin>>a[i];
                int vagsesh=a[i]%k;
                if(vagsesh==0) count++;
                else v.push_back(vagsesh);
        }
        int ans=0;
        if(count%2==0)ans+=(count);
        else ans+=(count-1);
        //cout<<ans<<endl;
        bool check[v.size()-1]={false};
        for(int i=0;i<v.size();i++)
        {
                if(check[i]==true) continue;
                for(int j=i+1;j<v.size();j++)
                {
                        //cout<<v[j]<<endl;
                        if((v[i]+v[j])%k==0 && check[i]==false && check[j]==false)
                        {
                                ans+=2;
                                check[i]=true;
                                check[j]=true;
                                break;
                        }
                }
        }
        cout<<ans<<endl;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
        int n,k;
        cin>>n>>k;
        int a[n];
        vector<int>v;
        int count=0;
        for(int i=0;i<n;i++)
        {
                cin>>a[i];
                int vagsesh=a[i]%k;
                if(vagsesh==0) count++;
                else v.push_back(vagsesh);
        }
        int ans=0;
        if(count%2==0)ans+=(count);
        else ans+=(count-1);
        //cout<<ans<<endl;
        bool check[v.size()-1]={false};
        for(int i=0;i<v.size();i++)
        {
                if(check[i]==true) continue;
                for(int j=i+1;j<v.size();j++)
                {
                        //cout<<v[j]<<endl;
                        if((v[i]+v[j])%k==0 && check[i]==false && check[j]==false)
                        {
                                ans+=2;
                                check[i]=true;
                                check[j]=true;
                                break;
                        }
                }
        }
        cout<<ans<<endl;
        return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{

        int n,k;
        cin>>n>>k;
        int a[n];
        vector<int>v;
        int count=0;
        for(int i=0;i<n;i++)
        {
                cin>>a[i];
                int vagsesh=a[i]%k;
                if(vagsesh==0) count++;
                else v.push_back(vagsesh);
        }
        int ans=0;
        if(count%2==0)ans+=(count);
        else ans+=(count-1);
        //cout<<ans<<endl;
        bool check[v.size()-1]={false};
        for(int i=0;i<v.size();i++)
        {
                if(check[i]==true) continue;
                for(int j=i+1;j<v.size();j++)
                {
                        //cout<<v[j]<<endl;
                        int raka=v[i]+v[j];
                        if((raka)%k==0 && check[i]==false && check[j]==false)
                        {
                                ans+=2;
                                check[i]=true;
                                check[j]=true;
                                break;
                        }
                }
        }
        cout<<ans<<endl;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{

        int n,k;
        cin>>n>>k;
        int a[n];
        vector<int>v;
        int count=0;
        for(int i=0;i<n;i++)
        {
                cin>>a[i];
                int vagsesh=a[i]%k;
                if(vagsesh==0) count++;
                else v.push_back(vagsesh);
        }
        int ans=0;
        if(count%2==0)ans+=(count);
        else ans+=(count-1);
        //cout<<ans<<endl;
        bool check[v.size()-1]={false};
        for(int i=0;i<v.size();i++)
        {
                if(check[i]==true) continue;
                for(int j=i+1;j<v.size();j++)
                {
                        //cout<<v[j]<<endl;
                        int raka=v[i]+v[j];
                        if((raka)%k==0 && check[i]==false && check[j]==false)
                        {
                                ans+=2;
                                check[i]=true;
                                check[j]=true;
                                break;
                        }
                }
        }
        cout<<ans<<endl;
        return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{

        int n,k;
        cin>>n>>k;
        int a[n];
        vector<int>v;
        int count=0;
        for(int i=0;i<n;i++)
        {
                cin>>a[i];
                int vagsesh=a[i]%k;
                if(vagsesh==0) count++;
                else v.push_back(vagsesh);
        }
        int ans=0;
        if(count%2==0)ans+=(count);
        else ans+=(count-1);
        //cout<<ans<<endl;
        bool check[v.size()-1]={false};
        for(int i=0;i<v.size();i++)
        {
                if(check[i]==true) continue;
                for(int j=i+1;j<v.size();j++)
                {
                        //cout<<v[j]<<endl;
                        int raka=(v[i]+v[j])%k;
                        if(raka==0 && check[i]==false && check[j]==false)
                        {
                                ans+=2;
                                check[i]=true;
                                check[j]=true;
                                break;
                        }
                }
        }
        cout<<ans<<endl;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{

        int n,k;
        cin>>n>>k;
        int a[n];
        vector<int>v;
        int count=0;
        for(int i=0;i<n;i++)
        {
                cin>>a[i];
                int vagsesh=a[i]%k;
                if(vagsesh==0) count++;
                else v.push_back(vagsesh);
        }
        int ans=0;
        if(count%2==0)ans+=(count);
        else ans+=(count-1);
        //cout<<ans<<endl;
        bool check[v.size()-1]={false};
        for(int i=0;i<v.size();i++)
        {
                if(check[i]==true) continue;
                for(int j=i+1;j<v.size();j++)
                {
                        //cout<<v[j]<<endl;
                        if((v[i]+v[j])%k==0 && check[i]==false && check[j]==false)
                        {
                                ans+=2;
                                check[i]=true;
                                check[j]=true;
                                break;
                        }
                }
        }
        cout<<ans<<endl;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{

        int n,k;
        cin>>n>>k;
        int freq[k+1]={0};
        int a[n];
        vector<int>v;
        int count=0;
        for(int i=0;i<n;i++)
        {
                cin>>a[i];
                int vagsesh=a[i]%k;
                if(vagsesh==0) count++;
                else freq[vagsesh]++;
        }
        int ans=0;
        if(count%2==0)ans+=(count/2);
        else ans+=((count-1)/2);
        //cout<<ans<<endl;
        for(int i=1;i<=(k/2);i++)
        {
                int raka=min(freq[i],freq[k-i]);
                if(i==k-i)
                {
                        ans+=(raka/2);
                }
                else ans+=raka;
        }

        cout<<ans*2<<endl;
}


#include <bits/stdc++.h>
using namespace std;
int n,k;

int main()
{cin>>n>>k;vector <int> vec(k);
    ios::sync_with_stdio(0);
    long long x;
    for(int i=0;i<n;i++)
    {
        cin>>x;++vec[x%k];
    }
    int ans=vec[0]/2;
    if(k%2==0) ans+=vec[k/2]/2;
    for(int i=1;i<(k+1)/2;i++)
    {
        int j=k-i;
        ans+=min(vec[i],vec[j]);
    }
    cout<<ans*2<<endl;
}


#include <bits/stdc++.h>
using namespace std;
long long a[100000*2+5];
int main()
{
    int n,k,sum=0;
    ios::sync_with_stdio(0);
    cin>>n>>k;
    for(int i=1; i<=n; i++)
    {
        cin>>a[i];
        if(a[i]%k==0)
            sum++;
        a[i]%=k;
    }
    sort(a+1,a+1+n);
    for(int i=1; i<=n; i++)
    {
        if(a[i]==0)
            continue;
        else
        {
            for(int j=i+1; j<=n; j++)
            {
                if(!a[j])
                    continue;
                if(a[i]+a[j]>k)
                {
                    break;
                }
                else if(a[i]+a[j]==k)
                {
                    a[j]=0;
                    sum++;
                }
            }

        }

    }
    cout<<sum<<endl;
}


#include <bits/stdc++.h>
using namespace std;
long long a[100000*2+5];
bool cmp(int a,int b)
{
    return a<b;
}
int main()
{
    int n,k,sum=0;
    ios::sync_with_stdio(0);
    cin>>n>>k;
    for(int i=0; i<n; i++)
    {
        cin>>a[i];
        if(a[i]%k==0)
        {
            a[i]=k;
        }
        else
        {
            a[i]%=k;
        }
    }
    sort(a,a+n,cmp);
    for(int i=0;i<n;i++)
    {
        cout<<a[i]<<" ";
    }cout<<endl;
    for(int i=0; i<n; i++)
    {
        if(a[i]==0)
            continue;
        else
        {
            for(int j=0; j<n; j++)
            {
                if(a[j]==0||i==j)
                    continue;
                if((a[i]+a[j])%k==0)
                {
                    a[j]=0;a[i]=0;sum+=2;
                    break;
                }
            }
        }
    }
    cout<<sum<<endl;
}


#include <bits/stdc++.h>
using namespace std;
long long a[100000*2+5];
bool cmp(int a,int b)
{
    return a<b;
}
int main()
{
    int n,k,sum=0;
    ios::sync_with_stdio(0);
    cin>>n>>k;
    for(int i=0; i<n; i++)
    {
        cin>>a[i];
        if(a[i]%k==0)
        {
            a[i]=k;
        }
        else
        {
            a[i]%=k;
        }
    }
    sort(a,a+n,cmp);
    for(int i=0;i<n;i++)
    {
        cout<<a[i]<<" ";
    }cout<<endl;
    for(int i=0; i<n; i++)
    {
        if(a[i]==0)
            continue;
        else
        {
            for(int j=0; j<n; j++)
            {
                if(a[j]==0||i==j)
                    continue;
                if((a[i]+a[j])%k==0)
                {
                    a[j]=0;a[i]=0;sum+=2;
                    break;
                }
            }
        }
    }
    cout<<sum;
}


#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n,k;
    cin>>n>>k;
    vector <int> vec(k);
    ios::sync_with_stdio(0);
    for(int i=0; i<n; i++)
    {
        int x;
        cin>>x;
        ++vec[x%k];
    }
    int ans=vec[0]/2;
    if(k%2==0)
        ans+=vec[k/2]/2;
    for(int i=1; i<(k+1)/2; i++)
    {
        int j=k-i;
        ans+=min(vec[i],vec[j]);
    }
    cout<<ans*2<<endl;
}


#include <bits/stdc++.h>
using namespace std;
int main()
{
    /*int n,k;
    cin>>n>>k;
    vector <int> vec(k);
    ios::sync_with_stdio(0);
    for(int i=0; i<n; i++)
    {
        int x;
        cin>>x;
        ++vec[x%k];
    }
    int ans=vec[0]/2;
    if(k%2==0)
        ans+=vec[k/2]/2;
    for(int i=1; i<(k+1)/2; i++)
    {
        int j=k-i;
        ans+=min(vec[i],vec[j]);
    }
    cout<<ans*2<<endl;*/
    int n, k;
	cin >> n >> k;
	vector<int> cnt(k);
	for (int i = 0; i < n; ++i) {
		int x;
		cin >> x;
		++cnt[x % k];
	}
	int ans = cnt[0] / 2;
	if (k % 2 == 0) ans += cnt[k / 2] / 2;
	for (int i = 1; i < (k + 1) / 2; ++i) {
		int j = k - i;
		ans += min(cnt[i], cnt[j]);
	}

	cout << ans * 2 << endl;

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
#endif

	int n, k;
	cin >> n >> k;
	vector<int> cnt(k);
	for (int i = 0; i < n; ++i) {
		int x;
		cin >> x;
		++cnt[x % k];
	}
	int ans = cnt[0] / 2;
	if (k % 2 == 0) ans += cnt[k / 2] / 2;
	for (int i = 1; i < (k + 1) / 2; ++i) {
		int j = k - i;
		ans += min(cnt[i], cnt[j]);
	}

	cout << ans * 2 << endl;

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n,k;
    cin>>n>>k;
    vector <int> vec(k);
    ios::sync_with_stdio(0);
    for(int i=0; i<n; i++)
    {
        int x;
        cin>>x;
        ++vec[x%k];
    }
    int ans=vec[0]/2;
    if(k%2==0)
        ans+=vec[k/2]/2;
    for(int i=1; i<(k+1)/2; i++)
    {
        int j=k-i;
        ans+=min(vec[i],vec[j]);
    }
    cout<<ans*2;
}


#include <bits/stdc++.h>
using namespace std;
long long a[100000*2+5];
bool cmp(int a,int b)
{
    return a<b;
}
int main()
{
    int n,k,sum=0;
    ios::sync_with_stdio(0);
    cin>>n>>k;
    for(int i=0; i<n; i++)
    {
        cin>>a[i];
        if(a[i]%k==0)
        {
            a[i]=k;
        }
        else
        {
            a[i]%=k;
        }
    }
    sort(a,a+n,cmp);
    for(int i=0; i<n; i++)
    {
        if(a[i]==0)
            continue;
        else
        {
            for(int j=0; j<n; j++)
            {
                if(a[j]==0||i==j)
                    continue;
                if((a[i]+a[j])%k==0)
                {
                    a[j]=0;a[i]=0;sum+=2;
                    break;
                }
            }
        }
    }
    cout<<sum;
}


/**
    हमने तुम्हे जिस सिद्दत से चाहा वो हम जानते हैं,
    पड़ जिसकी तुम हो उसके मोहब्बत की ताकत क्या रही होगी.
**/
/**

**/

#include <bits/stdc++.h>

#define ll                   long long
#define MOD                  (ll)(1e9 + 7)
#define INF                  (ll)1e18
#define fast()               ios_base::sync_with_stdio(false);  cin.tie(NULL);
#define loop(i,a,b)          for(ll i=(ll)a;i<(ll)b;i++)
#define pool(i,a,b)          for(ll i=(ll)a;i>=(ll)b;i--)
#define pb                   push_back
#define vi                   vector<ll>
#define endl                 "\n"
#define param                greater<ll>()
#define ff                   first
#define ss                   second
#define all(v)               v.begin(),v.end()
#define dbg(x)               cout<<#x<<" is: "<<x<<endl;

using namespace std;

bool isvowel(char c){if(c=='a' || c=='e' || c=='i' || c=='o' || c=='u' || c=='A' || c=='E' || c=='I' || c=='O' || c=='U')return true;return false;}

ll fast_exp(ll x,ll n){ll ans=1;while(n){if(n&1)ans*=x;n=n>>1;x=x*x;}return ans;}

ll mod_exp(ll x, ll y,ll p){ll res = 1;x = x % p;while(y>0){if(y&1)res = (res*x) % p;y = y>>1;x=(x*x)%p;}return res;}

ll sod(ll n){ll sum = 0;    while(n!=0){sum=sum+(n%10);n=n/10;}     return sum;}

ll modInverse(ll a, ll m){  return mod_exp(a, m-2, m);}

ll nCrModpDP(ll n,ll r,ll p)
{
    ll C[r+1];
    memset(C,0,sizeof(C));
    C[0]=1;
    for(ll i=1;i<=n;i++)
    {
        for (ll j=min(i,r);j>0;j--)
            C[j]=(C[j]+C[j-1])%p;
    }
    return C[r];
}

ll nCrModpLucas(ll n,ll r,ll p)
{
    if(r==0)
        return 1;
    ll ni=n%p,ri=r%p;
    return(nCrModpLucas(n/p,r/p,p)*nCrModpDP(ni,ri,p))%p;

    //O(p2 * logp(n))
}

/*End of template */

void solve()
{
    ll n,k;

    cin >> n >> k;

    vector<ll> a(n);
    loop(i,0,n)     cin >> a[i];
    loop(i,0,n)     a[i]=a[i]%k;

    map<ll,ll> mp;
    loop(i,0,n)     mp[a[i]]+=1;

    ll ans = 0;

    if(k%2==0)
        ans += (mp[k/2]/2);

    ll x;
    for(x=1; x<(k+1)/2; x++)
    {
        ll foo = min(mp[x],mp[k-x]);
        ans+=foo;
    }

    cout << 2*(ans + (mp[0]/2));
}

int main()
{

    #ifndef ONLINE_JUDGE
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
    #endif

    fast()

    ll t;
    // cin>>t;
    t=1;
    while(t--)
        solve();

    #ifndef ONLINE_JUDGE
        cout<<"\nTime Elapsed: " << 1.0*clock() / CLOCKS_PER_SEC << " sec\n";
    #endif

}


/**
    हमने तुम्हे जिस सिद्दत से चाहा वो हम जानते हैं,
    पड़ जिसकी तुम हो उसके मोहब्बत की ताकत क्या रही होगी.
**/
/**

**/

#include <bits/stdc++.h>

#define ll                   long long
#define MOD                  (ll)(1e9 + 7)
#define INF                  (ll)1e18
#define fast()               ios_base::sync_with_stdio(false);  cin.tie(NULL);
#define loop(i,a,b)          for(ll i=(ll)a;i<(ll)b;i++)
#define pool(i,a,b)          for(ll i=(ll)a;i>=(ll)b;i--)
#define pb                   push_back
#define vi                   vector<ll>
#define endl                 "\n"
#define param                greater<ll>()
#define ff                   first
#define ss                   second
#define all(v)               v.begin(),v.end()
#define dbg(x)               cout<<#x<<" is: "<<x<<endl;

using namespace std;

bool isvowel(char c){if(c=='a' || c=='e' || c=='i' || c=='o' || c=='u' || c=='A' || c=='E' || c=='I' || c=='O' || c=='U')return true;return false;}

ll fast_exp(ll x,ll n){ll ans=1;while(n){if(n&1)ans*=x;n=n>>1;x=x*x;}return ans;}

ll mod_exp(ll x, ll y,ll p){ll res = 1;x = x % p;while(y>0){if(y&1)res = (res*x) % p;y = y>>1;x=(x*x)%p;}return res;}

ll sod(ll n){ll sum = 0;    while(n!=0){sum=sum+(n%10);n=n/10;}     return sum;}

ll modInverse(ll a, ll m){  return mod_exp(a, m-2, m);}

ll nCrModpDP(ll n,ll r,ll p)
{
    ll C[r+1];
    memset(C,0,sizeof(C));
    C[0]=1;
    for(ll i=1;i<=n;i++)
    {
        for (ll j=min(i,r);j>0;j--)
            C[j]=(C[j]+C[j-1])%p;
    }
    return C[r];
}

ll nCrModpLucas(ll n,ll r,ll p)
{
    if(r==0)
        return 1;
    ll ni=n%p,ri=r%p;
    return(nCrModpLucas(n/p,r/p,p)*nCrModpDP(ni,ri,p))%p;

    //O(p2 * logp(n))
}

/*End of template */

void solve()
{
    ll n,k;

    cin >> n >> k;

    vector<ll> a(n);
    loop(i,0,n)		cin >> a[i];
    loop(i,0,n)		a[i]=a[i]%k;

    map<ll,ll> mp;
    loop(i,0,n)		mp[a[i]]+=1;

    ll ans = 0;

    if(k%2==0)
        cout << (mp[k/2]/2)*2;
    else
    {
        ll x,ans=0;
        for(x=1; x<=k/2; x++)
        {
            ll foo = min(mp[x],mp[k-x]);
            ans+=foo;
        }

        cout << ans*2 + (mp[0]/2)*2;
    }
}

int main()
{

	#ifndef ONLINE_JUDGE
    	freopen("input.txt", "r", stdin);
    	freopen("output.txt", "w", stdout);
	#endif

    fast()

    ll t;
    // cin>>t;
    t=1;
    while(t--)
        solve();

    #ifndef ONLINE_JUDGE
    	cout<<"\nTime Elapsed: " << 1.0*clock() / CLOCKS_PER_SEC << " sec\n";
	#endif

}