//#pragma GCC optimize("O3")
//#pragma GCC target("arch=native,tune=native")
#include <bits/stdc++.h>
#ifndef ONLINE_JUDGE
# include <sys/time.h>
# include <sys/resource.h>
#endif

/*** TEMPLATE CODE STARTS HERE ***/

#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795028841971693993751
#endif

using namespace std;

typedef vector<string> vs;
typedef long long ll;
typedef complex<double> pnt;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define RA(x) begin(x), end(x)
#define FE(i, x) for (auto i = begin(x); i != end(x); ++i)
#define SZ(x) ((ll) (x).size())

template<class T>
void splitstr(const string &s, vector<T> &out)
{
    istringstream in(s);
    out.clear();
    copy(istream_iterator<T>(in), istream_iterator<T>(), back_inserter(out));
}

static void redirect(int argc, const char **argv)
{
#ifndef ONLINE_JUDGE
    struct rlimit rlim;
    getrlimit(RLIMIT_STACK, &rlim);
    rlim.rlim_cur = 256 * 1024 * 1024;
    setrlimit(RLIMIT_STACK, &rlim);
#ifndef __SANITIZE_ADDRESS__
    getrlimit(RLIMIT_DATA, &rlim);
    rlim.rlim_cur = 256 * 1024 * 1024;
    setrlimit(RLIMIT_DATA, &rlim);
#endif
#endif

    ios::sync_with_stdio(false);
    cin.tie(NULL);
    if (argc > 1)
    {
        static filebuf f;
        f.open(argv[1], ios::in);
        cin.rdbuf(&f);
        if (!cin)
        {
            cerr << "Failed to open '" << argv[1] << "'" << endl;
            exit(1);
        }
    }

    if (argc > 2)
    {
        static filebuf f;
        f.open(argv[2], ios::out | ios::trunc);
        cout.rdbuf(&f);
        if (!cout)
        {
            cerr << "Failed to open '" << argv[2] << "'" << endl;
        }
    }
}

/*** TEMPLATE CODE ENDS HERE */

// Undefined sign for negative inputs
template<typename T>
static T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }

// m must be positive
template<typename T>
static T mod(T a, T m)
{
    a %= m;
    if (a < 0)
        a += m;
    return a;
}

// a must be relatively prime to m
template<typename T>
static T inverse(T a, T m)
{
    a = mod(a, m);
    if (a <= 1)
        return a;
    return mod((1 - inverse(m, a) * m) / a, m);
}

template<typename T, typename C, T Modulus>
class MR
{
private:
    struct tag_plus {}; // indicates value is in range [0, 2 * Modulus)
    struct tag_minus {}; // indicates value is in range (-Modulus, Modulus)
    struct tag_good {}; // indicates value is in range

    T value;

    static_assert(std::numeric_limits<C>::max() / Modulus / Modulus > 0, "compute type is too small");
    static_assert(Modulus < std::numeric_limits<T>::max() / 2, "storage type is too small");

    void reduce(tag_plus)
    {
        if (value >= Modulus)
            value -= Modulus;
    }

    void reduce(tag_minus)
    {
        if (value < 0)
            value += Modulus;
    }

    void reduce(tag_good) {}

public:
    typedef T value_type;
    typedef C compute_type;
    static const T modulus = Modulus;

    MR() : value(0) {}
    MR(C value) : value(value % Modulus) { reduce(tag_minus()); }
    template<typename tag_t>
    MR(T value, tag_t tag) : value(value) { reduce(tag); }

    MR &operator=(C value) { this->value = value % Modulus; reduce(tag_minus()); return *this; }

    MR operator +(MR b) const { return MR(value + b.value, tag_plus()); }
    MR operator -(MR b) const { return MR(value - b.value, tag_minus()); }
    MR operator *(MR b) const { return MR(C(value) * C(b.value) % Modulus, tag_good()); }
    MR operator -() const { return MR(-value, tag_minus()); }

    MR &operator +=(MR b) { value += b.value; reduce(tag_plus()); return *this; }
    MR &operator -=(MR b) { value -= b.value; reduce(tag_minus()); return *this; }
    MR &operator *=(MR b) { value = C(value) * C(b.value) % Modulus; return *this; }

    bool operator==(MR b) const { return value == b.value; }
    bool operator!=(MR b) const { return value != b.value; }

    T get() const { return value; }

    // These are only valid if the Modulus is prime, or at least if
    // the dividend is relatively prime to the modulus
    MR inverse() const
    {
        assert(value);
        return MR(::inverse(C(value), C(Modulus)), tag_good());
    }
    MR operator /(MR b) const { return *this * b.inverse(); }
    MR &operator /=(MR b) { return *this *= b.inverse(); }
};

template<typename T, typename C, T Modulus>
static inline std::ostream &operator<<(std::ostream &o, MR<T, C, Modulus> mr)
{
    return o << mr.get();
}

template<typename Traits>
class FFT
{
public:
    typedef typename Traits::type type;

private:
    template<typename It>
    static It fft_r(It first, It last, It tmp_first, It tmp_last, type g)
    {
        std::size_t S = last - first;
        if (S == 1)
            return first;
        else if (S == 2)
        {
            type a = *first;
            type b = *(first + 1);
            *first = a + b;
            *(first + 1) = a - b;
            return first;
        }
        std::size_t H = S / 2;
        It even = tmp_first;
        It odd = tmp_first + H;
        for (std::size_t i = 0; i < H; i++)
        {
            *(even + i) = *(first + 2 * i);
            *(odd + i) = *(first + 2 * i + 1);
        }
        type g2 = g * g;
        even = fft_r(even, odd, first, first + H, g2);
        odd = fft_r(odd, tmp_last, first, first + H, g2);
        if (&*even == &*first)
        {
            swap(first, tmp_first);
            swap(last, tmp_last);
        }
        type p = 1;
        for (std::size_t i = 0; i < H; i++)
        {
            type q = even[i];
            type r = p * odd[i];
            *(first + i) = q + r;
            *(first + i + H) = q - r;
            p *= g;
        }
        return first;
    }

public:
    static std::vector<type> fft(std::vector<type> a)
    {
        std::size_t S = a.size();
        assert(S > 0 && (S & (S - 1)) == 0); // power of 2
        std::vector<type> tmp(S);
        auto pos = fft_r(a.begin(), a.end(), tmp.begin(), tmp.end(), Traits::generator(S, true));
        if (&*pos == &*tmp.begin())
            a.swap(tmp);
        return a;
    }

    static std::vector<type> rfft(std::vector<type> a)
    {
        std::size_t S = a.size();
        assert(S > 0 && (S & (S - 1)) == 0); // power of 2
        std::vector<type> tmp(S);
        auto pos = fft_r(a.begin(), a.end(), tmp.begin(), tmp.end(), Traits::generator(S, false));
        if (&*pos == &*tmp.begin())
            a.swap(tmp);
        type iS = Traits::inverse(S);
        for (std::size_t i = 0; i < S; i++)
            a[i] *= iS;
        return a;
    }

    template<typename U>
    static std::vector<type> convolve(const std::vector<U> &a, const std::vector<U> &b)
    {
        assert(!a.empty());
        assert(!b.empty());
        std::size_t S = 1;
        while (S < a.size() + b.size() - 1)
            S *= 2;

        std::vector<type> pa(S), pb(S);
        std::copy(a.begin(), a.end(), pa.begin());
        std::copy(b.begin(), b.end(), pb.begin());
        std::vector<type> A = fft(pa);
        std::vector<type> B = fft(pb);
        for (std::size_t i = 0; i < S; i++)
            A[i] *= B[i];
        pa = rfft(A);
        pa.resize(a.size() + b.size() - 1);
        return pa;
    }
};

template<typename T>
class fft_traits_complex
{
public:
    typedef std::complex<T> type;

    static type inverse(type value)
    {
        return 1.0 / value;
    }

    static type generator(std::size_t S, bool invert)
    {
        type g = std::polar(1.0, 2 * M_PI / S);
        if (invert)
            g = conj(g);
        return g;
    }
};

typedef FFT<fft_traits_complex<double>> FFTd;

static vi convolve(const vi &a, const vi &b)
{
    auto c1 = FFTd::convolve(a, b);
    vi c(SZ(c1));
    for (int i = 0; i < SZ(c); i++)
        c[i] = ll(round(c1[i].real())) % 1009;
    return c;
}

struct compare_len
{
    bool operator()(const vi &a, const vi &b) const
    {
        return a.size() > b.size();
    }
};

int main(int argc, const char **argv)
{
    redirect(argc, argv);
    int N, M, K;
    cin >> N >> M >> K;
    priority_queue<vi, vector<vi>, compare_len> q;
    vi freq(M);
    for (int i = 0; i < N; i++)
    {
        int x;
        cin >> x;
        freq[x - 1]++;
    }
    for (int x : freq)
    {
        if (x > 0)
            q.push(vi(x + 1, 1));
    }
    while (SZ(q) >= 2)
    {
        vi a = q.top(); q.pop();
        vi b = q.top(); q.pop();
        q.push(convolve(a, b));
    }
    vi c = q.top();
    int ans = (K < SZ(c)) ? c[K] : 0;
    cout << ans << '\n';

    return 0;
}


//#pragma GCC optimize("O3")
//#pragma GCC target("arch=native,tune=native")
#include <bits/stdc++.h>
#ifndef ONLINE_JUDGE
# include <sys/time.h>
# include <sys/resource.h>
#endif

/*** TEMPLATE CODE STARTS HERE ***/

#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795028841971693993751
#endif

using namespace std;

typedef vector<string> vs;
typedef long long ll;
typedef complex<double> pnt;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define RA(x) begin(x), end(x)
#define FE(i, x) for (auto i = begin(x); i != end(x); ++i)
#define SZ(x) ((ll) (x).size())

template<class T>
void splitstr(const string &s, vector<T> &out)
{
    istringstream in(s);
    out.clear();
    copy(istream_iterator<T>(in), istream_iterator<T>(), back_inserter(out));
}

static void redirect(int argc, const char **argv)
{
#ifndef ONLINE_JUDGE
    struct rlimit rlim;
    getrlimit(RLIMIT_STACK, &rlim);
    rlim.rlim_cur = 256 * 1024 * 1024;
    setrlimit(RLIMIT_STACK, &rlim);
#ifndef __SANITIZE_ADDRESS__
    getrlimit(RLIMIT_DATA, &rlim);
    rlim.rlim_cur = 256 * 1024 * 1024;
    setrlimit(RLIMIT_DATA, &rlim);
#endif
#endif

    ios::sync_with_stdio(false);
    cin.tie(NULL);
    if (argc > 1)
    {
        static filebuf f;
        f.open(argv[1], ios::in);
        cin.rdbuf(&f);
        if (!cin)
        {
            cerr << "Failed to open '" << argv[1] << "'" << endl;
            exit(1);
        }
    }

    if (argc > 2)
    {
        static filebuf f;
        f.open(argv[2], ios::out | ios::trunc);
        cout.rdbuf(&f);
        if (!cout)
        {
            cerr << "Failed to open '" << argv[2] << "'" << endl;
        }
    }
}

/*** TEMPLATE CODE ENDS HERE */

// Undefined sign for negative inputs
template<typename T>
static T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }

// m must be positive
template<typename T>
static T mod(T a, T m)
{
    a %= m;
    if (a < 0)
        a += m;
    return a;
}

// a must be relatively prime to m
template<typename T>
static T inverse(T a, T m)
{
    a = mod(a, m);
    if (a <= 1)
        return a;
    return mod((1 - inverse(m, a) * m) / a, m);
}

template<typename T, typename C, T Modulus>
class MR
{
private:
    struct tag_plus {}; // indicates value is in range [0, 2 * Modulus)
    struct tag_minus {}; // indicates value is in range (-Modulus, Modulus)
    struct tag_good {}; // indicates value is in range

    T value;

    static_assert(std::numeric_limits<C>::max() / Modulus / Modulus > 0, "compute type is too small");
    static_assert(Modulus < std::numeric_limits<T>::max() / 2, "storage type is too small");

    void reduce(tag_plus)
    {
        if (value >= Modulus)
            value -= Modulus;
    }

    void reduce(tag_minus)
    {
        if (value < 0)
            value += Modulus;
    }

    void reduce(tag_good) {}

public:
    typedef T value_type;
    typedef C compute_type;
    static const T modulus = Modulus;

    MR() : value(0) {}
    MR(C value) : value(value % Modulus) { reduce(tag_minus()); }
    template<typename tag_t>
    MR(T value, tag_t tag) : value(value) { reduce(tag); }

    MR &operator=(C value) { this->value = value % Modulus; reduce(tag_minus()); return *this; }

    MR operator +(MR b) const { return MR(value + b.value, tag_plus()); }
    MR operator -(MR b) const { return MR(value - b.value, tag_minus()); }
    MR operator *(MR b) const { return MR(C(value) * C(b.value) % Modulus, tag_good()); }
    MR operator -() const { return MR(-value, tag_minus()); }

    MR &operator +=(MR b) { value += b.value; reduce(tag_plus()); return *this; }
    MR &operator -=(MR b) { value -= b.value; reduce(tag_minus()); return *this; }
    MR &operator *=(MR b) { value = C(value) * C(b.value) % Modulus; return *this; }

    bool operator==(MR b) const { return value == b.value; }
    bool operator!=(MR b) const { return value != b.value; }

    T get() const { return value; }

    // These are only valid if the Modulus is prime, or at least if
    // the dividend is relatively prime to the modulus
    MR inverse() const
    {
        assert(value);
        return MR(::inverse(C(value), C(Modulus)), tag_good());
    }
    MR operator /(MR b) const { return *this * b.inverse(); }
    MR &operator /=(MR b) { return *this *= b.inverse(); }
};

template<typename T, typename C, T Modulus>
static inline std::ostream &operator<<(std::ostream &o, MR<T, C, Modulus> mr)
{
    return o << mr.get();
}

template<typename Traits>
class FFT
{
public:
    typedef typename Traits::type type;

private:
    template<typename It>
    static It fft_r(It first, It last, It tmp_first, It tmp_last, type g)
    {
        std::size_t S = last - first;
        if (S == 1)
            return first;
        else if (S == 2)
        {
            type a = *first;
            type b = *(first + 1);
            *first = a + b;
            *(first + 1) = a - b;
            return first;
        }
        std::size_t H = S / 2;
        It even = tmp_first;
        It odd = tmp_first + H;
        for (std::size_t i = 0; i < H; i++)
        {
            *(even + i) = *(first + 2 * i);
            *(odd + i) = *(first + 2 * i + 1);
        }
        type g2 = g * g;
        even = fft_r(even, odd, first, first + H, g2);
        odd = fft_r(odd, tmp_last, first, first + H, g2);
        if (&*even == &*first)
        {
            swap(first, tmp_first);
            swap(last, tmp_last);
        }
        type p = 1;
        for (std::size_t i = 0; i < H; i++)
        {
            type q = even[i];
            type r = p * odd[i];
            *(first + i) = q + r;
            *(first + i + H) = q - r;
            p *= g;
        }
        return first;
    }

public:
    static std::vector<type> fft(std::vector<type> a)
    {
        std::size_t S = a.size();
        assert(S > 0 && (S & (S - 1)) == 0); // power of 2
        std::vector<type> tmp(S);
        auto pos = fft_r(a.begin(), a.end(), tmp.begin(), tmp.end(), Traits::generator(S, true));
        if (&*pos == &*tmp.begin())
            a.swap(tmp);
        return a;
    }

    static std::vector<type> rfft(std::vector<type> a)
    {
        std::size_t S = a.size();
        assert(S > 0 && (S & (S - 1)) == 0); // power of 2
        std::vector<type> tmp(S);
        auto pos = fft_r(a.begin(), a.end(), tmp.begin(), tmp.end(), Traits::generator(S, false));
        if (&*pos == &*tmp.begin())
            a.swap(tmp);
        type iS = Traits::inverse(S);
        for (std::size_t i = 0; i < S; i++)
            a[i] *= iS;
        return a;
    }

    static std::vector<type> convolve(const std::vector<type> &a, const std::vector<type> &b)
    {
        assert(!a.empty());
        assert(!b.empty());
        std::size_t S = 1;
        while (S < a.size() + b.size() - 1)
            S *= 2;

        std::vector<type> pa(S), pb(S);
        std::copy(a.begin(), a.end(), pa.begin());
        std::copy(b.begin(), b.end(), pb.begin());
        std::vector<type> A = fft(pa);
        std::vector<type> B = fft(pb);
        for (std::size_t i = 0; i < S; i++)
            A[i] *= B[i];
        pa = rfft(A);
        pa.resize(a.size() + b.size() - 1);
        return pa;
    }
};

/* These must satisfy:
 * - len is a power of 2
 * - mod is a prime
 * - len divides mod - 1
 * - gen has order len modulo mod
 */
template<typename T, typename C, T mod, T len, T gen>
class fft_traits_mod
{
public:
    typedef MR<T, C, mod> type;

    static type inverse(type value)
    {
        return value.inverse();
    }

    static type generator(std::size_t S, bool invert)
    {
        assert(len % S == 0);
        type g = gen;
        // compute 2^(len / S)
        T s = S;
        for (; s < len; s <<= 1)
            g *= g;
        if (invert)
            g = g.inverse();
        return g;
    }
};

typedef FFT<fft_traits_mod<int, ll, 998244353, 8388608, 15311432> > FFT2p23;

static vi convolve(const vi &a, const vi &b)
{
    typedef FFT2p23::type T;
    vector<T> at(RA(a)), bt(RA(b));
    auto ct = FFT2p23::convolve(at, bt);
    vi c(SZ(ct));
    for (int i = 0; i < SZ(ct); i++)
        c[i] = ct[i].get() % 1009;
    return c;
}

struct compare_len
{
    bool operator()(const vi &a, const vi &b) const
    {
        return a.size() > b.size();
    }
};

int main(int argc, const char **argv)
{
    redirect(argc, argv);
    int N, M, K;
    cin >> N >> M >> K;
    priority_queue<vi, vector<vi>, compare_len> q;
    vi freq(M);
    for (int i = 0; i < N; i++)
    {
        int x;
        cin >> x;
        freq[x - 1]++;
    }
    for (int x : freq)
    {
        if (x > 0)
            q.push(vi(x + 1, 1));
    }
    while (SZ(q) >= 2)
    {
        vi a = q.top(); q.pop();
        vi b = q.top(); q.pop();
        q.push(convolve(a, b));
    }
    vi c = q.top();
    int ans = (K < SZ(c)) ? c[K] : 0;
    cout << ans << '\n';

    return 0;
}


//#pragma GCC optimize("O3")
//#pragma GCC target("arch=native,tune=native")
#include <bits/stdc++.h>
#ifndef ONLINE_JUDGE
# include <sys/time.h>
# include <sys/resource.h>
#endif

/*** TEMPLATE CODE STARTS HERE ***/

#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795028841971693993751
#endif

using namespace std;

typedef vector<string> vs;
typedef long long ll;
typedef complex<double> pnt;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define RA(x) begin(x), end(x)
#define FE(i, x) for (auto i = begin(x); i != end(x); ++i)
#define SZ(x) ((ll) (x).size())

template<class T>
void splitstr(const string &s, vector<T> &out)
{
    istringstream in(s);
    out.clear();
    copy(istream_iterator<T>(in), istream_iterator<T>(), back_inserter(out));
}

static void redirect(int argc, const char **argv)
{
#ifndef ONLINE_JUDGE
    struct rlimit rlim;
    getrlimit(RLIMIT_STACK, &rlim);
    rlim.rlim_cur = 256 * 1024 * 1024;
    setrlimit(RLIMIT_STACK, &rlim);
#ifndef __SANITIZE_ADDRESS__
    getrlimit(RLIMIT_DATA, &rlim);
    rlim.rlim_cur = 256 * 1024 * 1024;
    setrlimit(RLIMIT_DATA, &rlim);
#endif
#endif

    ios::sync_with_stdio(false);
    cin.tie(NULL);
    if (argc > 1)
    {
        static filebuf f;
        f.open(argv[1], ios::in);
        cin.rdbuf(&f);
        if (!cin)
        {
            cerr << "Failed to open '" << argv[1] << "'" << endl;
            exit(1);
        }
    }

    if (argc > 2)
    {
        static filebuf f;
        f.open(argv[2], ios::out | ios::trunc);
        cout.rdbuf(&f);
        if (!cout)
        {
            cerr << "Failed to open '" << argv[2] << "'" << endl;
        }
    }
}

/*** TEMPLATE CODE ENDS HERE */

// Undefined sign for negative inputs
template<typename T>
static T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }

// m must be positive
template<typename T>
static T mod(T a, T m)
{
    a %= m;
    if (a < 0)
        a += m;
    return a;
}

// a must be relatively prime to m
template<typename T>
static T inverse(T a, T m)
{
    a = mod(a, m);
    if (a <= 1)
        return a;
    return mod((1 - inverse(m, a) * m) / a, m);
}

template<typename T, typename C, T Modulus>
class MR
{
private:
    struct tag_plus {}; // indicates value is in range [0, 2 * Modulus)
    struct tag_minus {}; // indicates value is in range (-Modulus, Modulus)
    struct tag_good {}; // indicates value is in range

    T value;

    static_assert(std::numeric_limits<C>::max() / Modulus / Modulus > 0, "compute type is too small");
    static_assert(Modulus < std::numeric_limits<T>::max() / 2, "storage type is too small");

    void reduce(tag_plus)
    {
        if (value >= Modulus)
            value -= Modulus;
    }

    void reduce(tag_minus)
    {
        if (value < 0)
            value += Modulus;
    }

    void reduce(tag_good) {}

public:
    typedef T value_type;
    typedef C compute_type;
    static const T modulus = Modulus;

    MR() : value(0) {}
    MR(C value) : value(value % Modulus) { reduce(tag_minus()); }
    template<typename tag_t>
    MR(T value, tag_t tag) : value(value) { reduce(tag); }

    MR &operator=(C value) { this->value = value % Modulus; reduce(tag_minus()); return *this; }

    MR operator +(MR b) const { return MR(value + b.value, tag_plus()); }
    MR operator -(MR b) const { return MR(value - b.value, tag_minus()); }
    MR operator *(MR b) const { return MR(C(value) * C(b.value) % Modulus, tag_good()); }
    MR operator -() const { return MR(-value, tag_minus()); }

    MR &operator +=(MR b) { value += b.value; reduce(tag_plus()); return *this; }
    MR &operator -=(MR b) { value -= b.value; reduce(tag_minus()); return *this; }
    MR &operator *=(MR b) { value = C(value) * C(b.value) % Modulus; return *this; }

    bool operator==(MR b) const { return value == b.value; }
    bool operator!=(MR b) const { return value != b.value; }

    T get() const { return value; }

    // These are only valid if the Modulus is prime, or at least if
    // the dividend is relatively prime to the modulus
    MR inverse() const
    {
        assert(value);
        return MR(::inverse(C(value), C(Modulus)), tag_good());
    }
    MR operator /(MR b) const { return *this * b.inverse(); }
    MR &operator /=(MR b) { return *this *= b.inverse(); }
};

template<typename T, typename C, T Modulus>
static inline std::ostream &operator<<(std::ostream &o, MR<T, C, Modulus> mr)
{
    return o << mr.get();
}

template<typename Traits>
class FFT
{
public:
    typedef typename Traits::type type;

private:
    template<typename It>
    static It fft_r(It first, It last, It tmp_first, It tmp_last, type g)
    {
        std::size_t S = last - first;
        if (S == 1)
            return first;
        else if (S == 2)
        {
            type a = *first;
            type b = *(first + 1);
            *first = a + b;
            *(first + 1) = a - b;
            return first;
        }
        std::size_t H = S / 2;
        It even = tmp_first;
        It odd = tmp_first + H;
        for (std::size_t i = 0; i < H; i++)
        {
            *(even + i) = *(first + 2 * i);
            *(odd + i) = *(first + 2 * i + 1);
        }
        type g2 = g * g;
        even = fft_r(even, odd, first, first + H, g2);
        odd = fft_r(odd, tmp_last, first, first + H, g2);
        if (&*even == &*first)
        {
            swap(first, tmp_first);
            swap(last, tmp_last);
        }
        type p = 1;
        for (std::size_t i = 0; i < H; i++)
        {
            type q = even[i];
            type r = p * odd[i];
            *(first + i) = q + r;
            *(first + i + H) = q - r;
            p *= g;
        }
        return first;
    }

public:
    static std::vector<type> fft(std::vector<type> a)
    {
        std::size_t S = a.size();
        assert(S > 0 && (S & (S - 1)) == 0); // power of 2
        std::vector<type> tmp(S);
        auto pos = fft_r(a.begin(), a.end(), tmp.begin(), tmp.end(), Traits::generator(S, true));
        if (&*pos == &*tmp.begin())
            a.swap(tmp);
        return a;
    }

    static std::vector<type> rfft(std::vector<type> a)
    {
        std::size_t S = a.size();
        assert(S > 0 && (S & (S - 1)) == 0); // power of 2
        std::vector<type> tmp(S);
        auto pos = fft_r(a.begin(), a.end(), tmp.begin(), tmp.end(), Traits::generator(S, false));
        if (&*pos == &*tmp.begin())
            a.swap(tmp);
        type iS = Traits::inverse(S);
        for (std::size_t i = 0; i < S; i++)
            a[i] *= iS;
        return a;
    }

    template<typename U>
    static std::vector<type> convolve(const std::vector<U> &a, const std::vector<U> &b)
    {
        assert(!a.empty());
        assert(!b.empty());
        std::size_t S = 1;
        while (S < a.size() + b.size() - 1)
            S *= 2;

        std::vector<type> pa(S), pb(S);
        std::copy(a.begin(), a.end(), pa.begin());
        std::copy(b.begin(), b.end(), pb.begin());
        std::vector<type> A = fft(pa);
        std::vector<type> B = fft(pb);
        for (std::size_t i = 0; i < S; i++)
            A[i] *= B[i];
        pa = rfft(A);
        pa.resize(a.size() + b.size() - 1);
        return pa;
    }
};

/* These must satisfy:
 * - len is a power of 2
 * - mod is a prime
 * - len divides mod - 1
 * - gen has order len modulo mod
 */
template<typename T, typename C, T mod, T len, T gen>
class fft_traits_mod
{
public:
    typedef MR<T, C, mod> type;

    static type inverse(type value)
    {
        return value.inverse();
    }

    static type generator(std::size_t S, bool invert)
    {
        assert(len % S == 0);
        type g = gen;
        // compute 2^(len / S)
        T s = S;
        for (; s < len; s <<= 1)
            g *= g;
        if (invert)
            g = g.inverse();
        return g;
    }
};

static const ll P1 = 786433;
static const ll P2 = 5767169;
static const ll P12 = P1 * P2;
typedef FFT<fft_traits_mod<int, ll, P1, 262144, 5> > FFT1;
typedef FFT<fft_traits_mod<int, ll, P2, 262144, 74> > FFT2;

static ll inv1, inv2;

static vi convolve(const vi &a, const vi &b)
{
    auto c1 = FFT1::convolve(a, b);
    auto c2 = FFT2::convolve(a, b);
    vi c(SZ(c1));
    for (int i = 0; i < SZ(c); i++)
    {
        ll v = (c1[i].get() * inv2 + c2[i].get() * inv1) % P12;
        c[i] = v % 1009;
    }
    return c;
}

struct compare_len
{
    bool operator()(const vi &a, const vi &b) const
    {
        return a.size() > b.size();
    }
};

int main(int argc, const char **argv)
{
#if 0
    for (int i = 2; i < 1000; i++)
    {
        FFT2::type test(i);
        for (int j = 0; j < 17; j++)
            test *= test;
        if (test == FFT2::type(-1))
            cout << i << '\n';
    }
    return 0;
#endif
    inv1 = inverse(P1, P2) * P1;
    inv2 = inverse(P2, P1) * P2;
    //cerr << inv1 << ' ' << inv2 << '\n';

    redirect(argc, argv);
    int N, M, K;
    cin >> N >> M >> K;
    priority_queue<vi, vector<vi>, compare_len> q;
    vi freq(M);
    for (int i = 0; i < N; i++)
    {
        int x;
        cin >> x;
        freq[x - 1]++;
    }
    for (int x : freq)
    {
        if (x > 0)
            q.push(vi(x + 1, 1));
    }
    while (SZ(q) >= 2)
    {
        vi a = q.top(); q.pop();
        vi b = q.top(); q.pop();
        q.push(convolve(a, b));
    }
    vi c = q.top();
    int ans = (K < SZ(c)) ? c[K] : 0;
    cout << ans << '\n';

    return 0;
}


#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define per(i, a, b) for (int i = (a); i >= (b); --i)
#define pb push_back
#define mp make_pair
#define pr pair<int, int>
#define x first
#define y second
using namespace std;

template<typename T>
void read(T& n){
	char ch; int sign = 1;
	while (!isdigit(ch = getchar())) if (ch == '-') sign = -1;
	n = ch - '0';
	while (isdigit(ch = getchar())) n = n * 10 + ch - '0';
	n *= sign;
}
typedef long long ll;
typedef complex<double> cd;
const int INF = 1e9 + 7;
const double pi = acos(-1);
const int N = 211111;
const int MOD = 1009;
int n, m, k;
int a[N], cnt[N];
priority_queue<pair<int, vector<int> > > heap;

void upd(int& x, int y){x += y; if (x >= MOD) x -= MOD;}
namespace fft{
	cd a[N], b[N];
	int rev[N];
	void dft(cd f[], int n, int sign){
		rep(i, 0, n - 1) if (i < rev[i]) swap(f[i], f[rev[i]]);
		for (int len = 1; len <= n; len <<= 1)
			for (int i = 0; i < n; i += len){
				cd wn(cos(2 * pi / len), sign * sin(2 * pi / len)), w = 1;
				for (int j = 0; j < len / 2; j++, w *= wn){
					int l = i + j, r = i + j + len / 2;
					cd t = f[r] * w;
					f[r] = f[l] - t, f[l] += t;
				}
			}
		if (sign == -1) rep(i, 0, n - 1) f[i] /= n;
	}
	vector<int> main(vector<int> l, vector<int> r){
		int n = l.size(), m = r.size(), len = 1, p = 0;
		for (; len <= n + m - 1; len <<= 1, p++) ;
		rep(i, 1, len - 1) rev[i] = (rev[i>>1] >> 1) + ((i & 1) << p - 1);
		rep(i, 0, len - 1) a[i] = b[i] = 0;
		rep(i, 0, n - 1) a[i] = l[i];
		rep(i, 0, m - 1) b[i] = r[i];
		dft(a, len, 1), dft(b, len, 1);
		rep(i, 0, len - 1) a[i] *= b[i];
		dft(a, len, -1);
		vector<int> ret;
		rep(i, 0, n + m - 2) ret.pb((int)(a[i].real() + .5) % MOD);
		return ret;
	}
};

int main(){
	read(n), read(m), read(k);
	rep(i, 1, n) read(a[i]), cnt[a[i]]++;
	rep(i, 1, m){
		vector<int> v;
		rep(j, 0, cnt[i]) v.pb(1);
		heap.push(mp(cnt[i], v));
	}
	vector<int> l, r;
	while(!heap.empty()){
		l = heap.top().y; heap.pop();
		if (heap.empty()) break;
		r = heap.top().y; heap.pop();
		l = fft::main(l, r);
		int len = l.size() - 1;
		heap.push(mp(len, l));
	}
	printf("%d\n", l[k]);
	return 0;
}


#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define per(i, a, b) for (int i = (a); i >= (b); --i)
#define pb push_back
#define mp make_pair
#define pr pair<int, int>
#define x first
#define y second
using namespace std;

template<typename T>
void read(T& n){
	char ch; int sign = 1;
	while (!isdigit(ch = getchar())) if (ch == '-') sign = -1;
	n = ch - '0';
	while (isdigit(ch = getchar())) n = n * 10 + ch - '0';
	n *= sign;
}
typedef long long ll;
typedef complex<double> cd;
typedef pair<int, vector<int> > piv;
const int INF = 1e9 + 7;
const double pi = acos(-1);
const int N = 811111;
const int MOD = 1009;
int n, m, k;
int a[N], cnt[N];
priority_queue<piv, vector<piv>, greater<piv> > heap;

void upd(int& x, int y){x += y; if (x >= MOD) x -= MOD;}
namespace fft{
	cd a[N], b[N];
	int rev[N];
	void dft(cd f[], int n, int sign){
		rep(i, 0, n - 1) if (i < rev[i]) swap(f[i], f[rev[i]]);
		for (int len = 1; len <= n; len <<= 1)
			for (int i = 0; i < n; i += len){
				cd wn(cos(2 * pi / len), sign * sin(2 * pi / len)), w = 1;
				for (int j = 0; j < len / 2; j++, w *= wn){
					int l = i + j, r = i + j + len / 2;
					cd t = f[r] * w;
					f[r] = f[l] - t, f[l] += t;
				}
			}
		if (sign == -1) rep(i, 0, n - 1) f[i] /= n;
	}
	vector<int> main(vector<int> l, vector<int> r){
		int n = l.size(), m = r.size(), len = 1, p = 0;
		for (; len <= n + m - 1; len <<= 1, p++) ;
		rep(i, 1, len - 1) rev[i] = (rev[i>>1] >> 1) + ((i & 1) << p - 1);
		rep(i, 0, len - 1) a[i] = b[i] = 0;
		rep(i, 0, n - 1) a[i] = l[i];
		rep(i, 0, m - 1) b[i] = r[i];
		dft(a, len, 1), dft(b, len, 1);
		rep(i, 0, len - 1) a[i] *= b[i];
		dft(a, len, -1);
		vector<int> ret;
		rep(i, 0, n + m - 2) ret.pb(ll(a[i].real() + .5) % MOD);
		return ret;
	}
};

int main(){
	read(n), read(m), read(k);
	rep(i, 1, n) read(a[i]), cnt[a[i]]++;
	rep(i, 1, m){
		vector<int> v;
		rep(j, 0, cnt[i]) v.pb(1);
		heap.push(mp(cnt[i] + 1, v));
	}
	vector<int> l, r;
	while(!heap.empty()){
		l = heap.top().y; heap.pop();
		if (heap.empty()) break;
		r = heap.top().y; heap.pop();
		l = fft::main(l, r);
		int len = l.size();
		heap.push(mp(len, l));
	}
	printf("%d\n", l[k]);
	return 0;
}


#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define per(i, a, b) for (int i = (a); i >= (b); --i)
#define pb push_back
#define mp make_pair
#define pr pair<int, int>
#define x first
#define y second
using namespace std;

template<typename T>
void read(T& n){
	char ch; int sign = 1;
	while (!isdigit(ch = getchar())) if (ch == '-') sign = -1;
	n = ch - '0';
	while (isdigit(ch = getchar())) n = n * 10 + ch - '0';
	n *= sign;
}
typedef long long ll;
typedef complex<double> cd;
typedef pair<int, vector<int> > piv;
const int INF = 1e9 + 7;
const double pi = acos(-1);
const int N = 211111;
const int MOD = 1009;
int n, m, k;
int a[N], cnt[N];
priority_queue<piv, vector<piv>, greater<piv> > heap;

void upd(int& x, int y){x += y; if (x >= MOD) x -= MOD;}
namespace fft{
	cd a[N], b[N];
	int rev[N];
	void dft(cd f[], int n, int sign){
		rep(i, 0, n - 1) if (i < rev[i]) swap(f[i], f[rev[i]]);
		for (int len = 1; len <= n; len <<= 1)
			for (int i = 0; i < n; i += len){
				cd wn(cos(2 * pi / len), sign * sin(2 * pi / len)), w = 1;
				for (int j = 0; j < len / 2; j++, w *= wn){
					int l = i + j, r = i + j + len / 2;
					cd t = f[r] * w;
					f[r] = f[l] - t, f[l] += t;
				}
			}
		if (sign == -1) rep(i, 0, n - 1) f[i] /= n;
	}
	vector<int> main(vector<int> l, vector<int> r){
		int n = l.size(), m = r.size(), len = 1, p = 0;
		for (; len <= n + m - 1; len <<= 1, p++) ;
		rep(i, 1, len - 1) rev[i] = (rev[i>>1] >> 1) + ((i & 1) << p - 1);
		rep(i, 0, len - 1) a[i] = b[i] = 0;
		rep(i, 0, n - 1) a[i] = l[i];
		rep(i, 0, m - 1) b[i] = r[i];
		dft(a, len, 1), dft(b, len, 1);
		rep(i, 0, len - 1) a[i] *= b[i];
		dft(a, len, -1);
		vector<int> ret;
		rep(i, 0, n + m - 2) ret.pb(ll(a[i].real() + .5) % MOD);
		return ret;
	}
};

int main(){
	read(n), read(m), read(k);
	rep(i, 1, n) read(a[i]), cnt[a[i]]++;
	rep(i, 1, m){
		vector<int> v;
		rep(j, 0, cnt[i]) v.pb(1);
		heap.push(mp(cnt[i] + 1, v));
	}
	vector<int> l, r;
	while(!heap.empty()){
		l = heap.top().y; heap.pop();
		if (heap.empty()) break;
		r = heap.top().y; heap.pop();
		l = fft::main(l, r);
		int len = l.size();
		heap.push(mp(len, l));
	}
	printf("%d\n", l[k]);
	return 0;
}


#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define per(i, a, b) for (int i = (a); i >= (b); --i)
#define pb push_back
#define mp make_pair
#define pr pair<int, int>
#define x first
#define y second
using namespace std;

template<typename T>
void read(T& n){
	char ch; int sign = 1;
	while (!isdigit(ch = getchar())) if (ch == '-') sign = -1;
	n = ch - '0';
	while (isdigit(ch = getchar())) n = n * 10 + ch - '0';
	n *= sign;
}
typedef long long ll;
typedef complex<double> cd;
typedef pair<int, vector<int> > piv;
const int INF = 1e9 + 7;
const double pi = acos(-1);
const int N = 211111;
const int MOD = 1009;
int n, m, k;
int a[N], cnt[N];
priority_queue<piv, vector<piv>, greater<piv> > heap;

void upd(int& x, int y){x += y; if (x >= MOD) x -= MOD;}
namespace fft{
	cd a[N], b[N];
	int rev[N];
	void dft(cd f[], int n, int sign){
		rep(i, 0, n - 1) if (i < rev[i]) swap(f[i], f[rev[i]]);
		for (int len = 1; len <= n; len <<= 1)
			for (int i = 0; i < n; i += len){
				cd wn(cos(2 * pi / len), sign * sin(2 * pi / len)), w = 1;
				for (int j = 0; j < len / 2; j++, w *= wn){
					int l = i + j, r = i + j + len / 2;
					cd t = f[r] * w;
					f[r] = f[l] - t, f[l] += t;
				}
			}
		if (sign == -1) rep(i, 0, n - 1) f[i] /= n;
	}
	vector<int> main(vector<int> l, vector<int> r){
		int n = l.size(), m = r.size(), len = 1, p = 0;
		for (; len <= n + m - 1; len <<= 1, p++) ;
		rep(i, 1, len - 1) rev[i] = (rev[i>>1] >> 1) + ((i & 1) << p - 1);
		rep(i, 0, len - 1) a[i] = b[i] = 0;
		rep(i, 0, n - 1) a[i] = l[i];
		rep(i, 0, m - 1) b[i] = r[i];
		dft(a, len, 1), dft(b, len, 1);
		rep(i, 0, len - 1) a[i] *= b[i];
		dft(a, len, -1);
		vector<int> ret;
		rep(i, 0, n + m - 2) ret.pb((int)(a[i].real() + .5) % MOD);
		return ret;
	}
};

int main(){
	read(n), read(m), read(k);
	rep(i, 1, n) read(a[i]), cnt[a[i]]++;
	rep(i, 1, m){
		vector<int> v;
		rep(j, 0, cnt[i]) v.pb(1);
		heap.push(mp(cnt[i] + 1, v));
	}
	vector<int> l, r;
	while(!heap.empty()){
		l = heap.top().y; heap.pop();
		if (heap.empty()) break;
		r = heap.top().y; heap.pop();
		l = fft::main(l, r);
		int len = l.size();
		heap.push(mp(len, l));
	}
	printf("%d\n", l[k]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
struct comp
{
    double x,y;
    comp(double xi,double yi) {
        x=xi;
        y=yi;
    }
    comp(double xi) {
        x=xi;
        y=0.0;
    }
    comp() {
        x=0.0;
        y=0.0;
    }
};
comp operator + (comp a,comp b) {
    return comp(a.x+b.x,a.y+b.y);
}
comp operator - (comp a,comp b) {
    return comp(a.x-b.x,a.y-b.y);
}
comp operator * (comp a,comp b) {
    return comp(a.x*b.x-a.y*b.y,a.x*b.y+b.x*a.y);
}
comp polarcomp (double r,double arg){
    return comp(r*cos(arg),r*sin(arg));
}
int n,m,k;
vector<int> a[200005];
int ps[1000000];
vector<int> z;
int f;
vector<comp> pm[3];
int inverse(int i)
{
    int j=1;
    int rt=0;
    int l=f>>1;
    while(j<l) {
        if((i&j)) rt+=l;
        if((i&l)) rt+=j;
        j=(j<<1);
        l=(l>>1);
    }
    if(j==l && (i&j)==l) rt+=l;
    return rt;
}
void dft(int ind,bool inv) {
    for(int i=0;i<pm[ind].size();i++) {
        if(i<inverse(i)) swap(pm[ind][i],pm[ind][inverse(i)]);
    }
    comp d,w,x,y;
    for(int l=2;l<=f;l=(l<<1)) {
        if(!inv) w=polarcomp(1.0,2.00*acos(-1.0)/double(l));
        else w=polarcomp(1.0,-2.00*acos(-1.0)/double(l));
        //cout<<w.x<<" "<<w.y<<endl;
        for(int i=0;i<f;i=i+l) {
            d=comp(1.0,0.0);
            for(int j=i;j<i+(l>>1);j++) {
                x=pm[ind][j];
                y=pm[ind][j+(l>>1)]*d;
                pm[ind][j]=x+y;
                pm[ind][j+(l>>1)]=x-y;
                d=d*w;
            }
        }
        /*for(int i=0;i<pm[ind].size();i++) cout<<"("<<pm[ind][i].x<<","<<pm[ind][i].y<<") ";
        cout<<endl;*/
    }
}
vector<int> fft(vector<int> x,vector<int> y) {
    pm[0].clear();
    f=ps[x.size()+y.size()];
    while(pm[0].size()<f) pm[0].push_back(0.00);
    pm[1].clear();
    while(pm[1].size()<f) pm[1].push_back(0.00);
    pm[2].clear();
    while(pm[2].size()<f) pm[2].push_back(0.00);
    for(int i=0;i<x.size();i++) pm[0][i]=x[i];
    for(int i=0;i<y.size();i++) pm[1][i]=y[i];
    dft(0,false);
    dft(1,false);
    for(int i=0;i<pm[2].size();i++) pm[2][i]=pm[0][i]*pm[1][i];
    //for(int i=0;i<pm[0].size();i++) cout<<"("<<pm[0][i].x<<","<<pm[0][i].y<<") ("<<pm[1][i].x<<","<<pm[1][i].y<<") ("<<pm[2][i].x<<","<<pm[2][i].y<<")"<<endl;
    dft(2,true);
    for(int i=0;i<pm[2].size();i++) pm[2][i]=comp(pm[2][i].x/((double)(f)),pm[2][i].y/((double)(f)));
    //f=(f>>1);
    z.resize(pm[2].size());
    //cout<<f<<" "<<x.size()<<" "<<y.size()<<endl;
    for(int i=0;i<z.size();i++) {
        z[i]=((int)round(pm[2][i].x))%1009;
        //cout<<"("<<pm[2][i].x<<","<<pm[2][i].y<<")"<<endl;
    }
    return z;

}
vector<int> mul(int l,int r){
    //cout<<l<<" "<<r<<endl;
    if(l==r) return a[l];
    return fft(mul(l,((l+r)>>1)),mul(((l+r)>>1)+1,r));
}
int main()
{
    int x;
    scanf("%d %d %d",&n,&m,&k);
    ps[1]=1;
    for(int i=2;i<1e6;i++) {
        ps[i]=ps[i-1];
        if(i>ps[i]) ps[i]=2*ps[i];
        //cout<<i<<" "<<ps[i]<<endl;
    }
    for(int i=1;i<=m;i++) a[i].push_back(1);
    for(int i=0;i<n;i++) {
        scanf("%d",&x);
        a[x].push_back(1);
    }
    printf("%d",mul(1,m)[k]);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
struct comp
{
    double x,y;
    comp(double xi,double yi) {
        x=xi;
        y=yi;
    }
    comp(double xi) {
        x=xi;
        y=0.0;
    }
    comp() {
        x=0.0;
        y=0.0;
    }
};
comp operator + (comp a,comp b) {
    return comp(a.x+b.x,a.y+b.y);
}
comp operator - (comp a,comp b) {
    return comp(a.x-b.x,a.y-b.y);
}
comp operator * (comp a,comp b) {
    return comp(a.x*b.x-a.y*b.y,a.x*b.y+b.x*a.y);
}
comp polarcomp (double r,double arg){
    return comp(r*cos(arg),r*sin(arg));
}
int n,m,k;
vector<int> a[2000005];
int ps[10000000];
vector<int> z;
int f;
vector<comp> pm[3];
int inverse(int i)
{
    int j=1;
    int rt=0;
    int l=f>>1;
    while(j<l) {
        if((i&j)) rt+=l;
        if((i&l)) rt+=j;
        j=(j<<1);
        l=(l>>1);
    }
    if(j==l && (i&j)==l) rt+=l;
    return rt;
}
void dft(int ind,bool inv) {
    for(int i=0;i<pm[ind].size();i++) {
        if(i<inverse(i)) swap(pm[ind][i],pm[ind][inverse(i)]);
    }
    comp d,w,x,y;
    for(int l=2;l<=f;l=(l<<1)) {
        if(!inv) w=polarcomp(1.0,2.00*acos(-1.0)/double(l));
        else w=polarcomp(1.0,-2.00*acos(-1.0)/double(l));
        //cout<<w.x<<" "<<w.y<<endl;
        for(int i=0;i<f;i=i+l) {
            d=comp(1.0,0.0);
            for(int j=i;j<i+(l>>1);j++) {
                x=pm[ind][j];
                y=pm[ind][j+(l>>1)]*d;
                pm[ind][j]=x+y;
                pm[ind][j+(l>>1)]=x-y;
                d=d*w;
            }
        }
        /*for(int i=0;i<pm[ind].size();i++) cout<<"("<<pm[ind][i].x<<","<<pm[ind][i].y<<") ";
        cout<<endl;*/
    }
}
vector<int> fft(vector<int> x,vector<int> y) {
    pm[0].clear();
    f=ps[x.size()+y.size()];
    while(pm[0].size()<f) pm[0].push_back(0.00);
    pm[1].clear();
    while(pm[1].size()<f) pm[1].push_back(0.00);
    pm[2].clear();
    while(pm[2].size()<f) pm[2].push_back(0.00);
    for(int i=0;i<x.size();i++) pm[0][i]=x[i];
    for(int i=0;i<y.size();i++) pm[1][i]=y[i];
    dft(0,false);
    dft(1,false);
    for(int i=0;i<pm[2].size();i++) pm[2][i]=pm[0][i]*pm[1][i];
    //for(int i=0;i<pm[0].size();i++) cout<<"("<<pm[0][i].x<<","<<pm[0][i].y<<") ("<<pm[1][i].x<<","<<pm[1][i].y<<") ("<<pm[2][i].x<<","<<pm[2][i].y<<")"<<endl;
    dft(2,true);
    for(int i=0;i<pm[2].size();i++) pm[2][i]=comp(pm[2][i].x/((double)(f)),pm[2][i].y/((double)(f)));
    //f=(f>>1);
    z.resize(pm[2].size());
    //cout<<f<<" "<<x.size()<<" "<<y.size()<<endl;
    for(int i=0;i<z.size();i++) {
        z[i]=((int)round(pm[2][i].x))%1009;
        if(z[i]<0) z[i]+=1009;
        //cout<<"("<<pm[2][i].x<<","<<pm[2][i].y<<")"<<endl;
    }
    while(z[z.size()-1]==0) z.pop_back();
    return z;

}
vector<int> mul(int l,int r){
    //cout<<l<<" "<<r<<endl;
    if(l==r) return a[l];
    return fft(mul(l,((l+r)>>1)),mul(((l+r)>>1)+1,r));
}
int main()
{
    int x;
    scanf("%d %d %d",&n,&m,&k);
    ps[1]=1;
    for(int i=2;i<1e7;i++) {
        ps[i]=ps[i-1];
        if(i>ps[i]) ps[i]=2*ps[i];
        //cout<<i<<" "<<ps[i]<<endl;
    }
    for(int i=1;i<=m;i++) a[i].push_back(1);
    for(int i=0;i<n;i++) {
        scanf("%d",&x);
        a[x].push_back(1);
    }
    printf("%d",mul(1,m)[k]);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
struct comp
{
    double x,y;
    comp(double xi,double yi) {
        x=xi;
        y=yi;
    }
    comp(double xi) {
        x=xi;
        y=0.0;
    }
    comp() {
        x=0.0;
        y=0.0;
    }
};
comp operator + (comp a,comp b) {
    return comp(a.x+b.x,a.y+b.y);
}
comp operator - (comp a,comp b) {
    return comp(a.x-b.x,a.y-b.y);
}
comp operator * (comp a,comp b) {
    return comp(a.x*b.x-a.y*b.y,a.x*b.y+b.x*a.y);
}
comp polarcomp (double r,double arg){
    return comp(r*cos(arg),r*sin(arg));
}
long long n,m,k;
vector<long long> a[2000005];
long long ps[10000000];
vector<long long> z;
long long f;
vector<comp> pm[3];
long long inverse(long long i)
{
    long long j=1;
    long long rt=0;
    long long l=f>>1;
    while(j<l) {
        if((i&j)) rt+=l;
        if((i&l)) rt+=j;
        j=(j<<1);
        l=(l>>1);
    }
    if(j==l && (i&j)==l) rt+=l;
    return rt;
}
void dft(long long ind,bool inv) {
    for(long long i=0;i<pm[ind].size();i++) {
        if(i<inverse(i)) swap(pm[ind][i],pm[ind][inverse(i)]);
    }
    comp d,w,x,y;
    for(long long l=2;l<=f;l=(l<<1)) {
        if(!inv) w=polarcomp(1.0,2.00*acos(-1.0)/double(l));
        else w=polarcomp(1.0,-2.00*acos(-1.0)/double(l));
        //cout<<w.x<<" "<<w.y<<endl;
        for(long long i=0;i<f;i=i+l) {
            d=comp(1.0,0.0);
            for(long long j=i;j<i+(l>>1);j++) {
                x=pm[ind][j];
                y=pm[ind][j+(l>>1)]*d;
                pm[ind][j]=x+y;
                pm[ind][j+(l>>1)]=x-y;
                d=d*w;
            }
        }
        /*for(int i=0;i<pm[ind].size();i++) cout<<"("<<pm[ind][i].x<<","<<pm[ind][i].y<<") ";
        cout<<endl;*/
    }
}
vector<long long> fft(vector<long long> x,vector<long long> y) {
    pm[0].clear();
    f=ps[x.size()+y.size()];
    while(pm[0].size()<f) pm[0].push_back(0.00);
    pm[1].clear();
    while(pm[1].size()<f) pm[1].push_back(0.00);
    pm[2].clear();
    while(pm[2].size()<f) pm[2].push_back(0.00);
    for(long long i=0;i<x.size();i++) pm[0][i]=x[i];
    for(long long i=0;i<y.size();i++) pm[1][i]=y[i];
    dft(0,false);
    dft(1,false);
    for(long long i=0;i<pm[2].size();i++) pm[2][i]=pm[0][i]*pm[1][i];
    //for(int i=0;i<pm[0].size();i++) cout<<"("<<pm[0][i].x<<","<<pm[0][i].y<<") ("<<pm[1][i].x<<","<<pm[1][i].y<<") ("<<pm[2][i].x<<","<<pm[2][i].y<<")"<<endl;
    dft(2,true);
    for(long long i=0;i<pm[2].size();i++) pm[2][i]=comp(pm[2][i].x/((double)(f)),pm[2][i].y/((double)(f)));
    //f=(f>>1);
    z.resize(pm[2].size());
    //cout<<f<<" "<<x.size()<<" "<<y.size()<<endl;
    for(long long i=0;i<z.size();i++) {
        z[i]=((long long)round(pm[2][i].x))%1009;
        if(z[i]<0) z[i]+=1009;
        //cout<<"("<<pm[2][i].x<<","<<pm[2][i].y<<")"<<endl;
    }
    while(z[z.size()-1]==0) z.pop_back();
    return z;

}
vector<long long> mul(long long l,long long r){
    //cout<<l<<" "<<r<<endl;
    if(l==r) return a[l];
    return fft(mul(l,((l+r)>>1)),mul(((l+r)>>1)+1,r));
}
int main()
{
    long long x;
    scanf("%lld %lld %lld",&n,&m,&k);
    ps[1]=1;
    for(long long i=2;i<1e7;i++) {
        ps[i]=ps[i-1];
        if(i>ps[i]) ps[i]=2*ps[i];
        //cout<<i<<" "<<ps[i]<<endl;
    }
    for(long long i=1;i<=m;i++) a[i].push_back(1);
    for(long long i=0;i<n;i++) {
        scanf("%lld",&x);
        a[x].push_back(1);
    }
    printf("%lld",mul(1,m)[k]);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
struct comp
{
    double x,y;
    comp(double xi,double yi) {
        x=xi;
        y=yi;
    }
    comp(double xi) {
        x=xi;
        y=0.0;
    }
    comp() {
        x=0.0;
        y=0.0;
    }
};
comp operator + (comp a,comp b) {
    return comp(a.x+b.x,a.y+b.y);
}
comp operator - (comp a,comp b) {
    return comp(a.x-b.x,a.y-b.y);
}
comp operator * (comp a,comp b) {
    return comp(a.x*b.x-a.y*b.y,a.x*b.y+b.x*a.y);
}
comp polarcomp (double r,double arg){
    return comp(r*cos(arg),r*sin(arg));
}
int n,m,k;
vector<int> a[2000005];
int ps[10000000];
vector<int> z;
int f;
vector<comp> pm[3];
int inverse(int i)
{
    int j=1;
    int rt=0;
    int l=f>>1;
    while(j<l) {
        if((i&j)) rt+=l;
        if((i&l)) rt+=j;
        j=(j<<1);
        l=(l>>1);
    }
    if(j==l && (i&j)==l) rt+=l;
    return rt;
}
void dft(int ind,bool inv) {
    for(int i=0;i<pm[ind].size();i++) {
        if(i<inverse(i)) swap(pm[ind][i],pm[ind][inverse(i)]);
    }
    comp d,w,x,y;
    for(int l=2;l<=f;l=(l<<1)) {
        if(!inv) w=polarcomp(1.0,2.00*acos(-1.0)/double(l));
        else w=polarcomp(1.0,-2.00*acos(-1.0)/double(l));
        //cout<<w.x<<" "<<w.y<<endl;
        for(int i=0;i<f;i=i+l) {
            d=comp(1.0,0.0);
            for(int j=i;j<i+(l>>1);j++) {
                x=pm[ind][j];
                y=pm[ind][j+(l>>1)]*d;
                pm[ind][j]=x+y;
                pm[ind][j+(l>>1)]=x-y;
                d=d*w;
            }
        }
        /*for(int i=0;i<pm[ind].size();i++) cout<<"("<<pm[ind][i].x<<","<<pm[ind][i].y<<") ";
        cout<<endl;*/
    }
}
vector<int> fft(vector<int> x,vector<int> y) {
    pm[0].clear();
    f=ps[x.size()+y.size()];
    while(pm[0].size()<f) pm[0].push_back(0.00);
    pm[1].clear();
    while(pm[1].size()<f) pm[1].push_back(0.00);
    pm[2].clear();
    while(pm[2].size()<f) pm[2].push_back(0.00);
    for(int i=0;i<x.size();i++) pm[0][i]=x[i];
    for(int i=0;i<y.size();i++) pm[1][i]=y[i];
    dft(0,false);
    dft(1,false);
    for(int i=0;i<pm[2].size();i++) pm[2][i]=pm[0][i]*pm[1][i];
    //for(int i=0;i<pm[0].size();i++) cout<<"("<<pm[0][i].x<<","<<pm[0][i].y<<") ("<<pm[1][i].x<<","<<pm[1][i].y<<") ("<<pm[2][i].x<<","<<pm[2][i].y<<")"<<endl;
    dft(2,true);
    for(int i=0;i<pm[2].size();i++) pm[2][i]=comp(pm[2][i].x/((double)(f)),pm[2][i].y/((double)(f)));
    //f=(f>>1);
    z.resize(pm[2].size());
    //cout<<f<<" "<<x.size()<<" "<<y.size()<<endl;
    for(int i=0;i<z.size();i++) {
        z[i]=((int)round(pm[2][i].x))%1009;
        //cout<<"("<<pm[2][i].x<<","<<pm[2][i].y<<")"<<endl;
    }
    while(z[z.size()-1]==0) z.pop_back();
    return z;

}
vector<int> mul(int l,int r){
    //cout<<l<<" "<<r<<endl;
    if(l==r) return a[l];
    return fft(mul(l,((l+r)>>1)),mul(((l+r)>>1)+1,r));
}
int main()
{
    int x;
    scanf("%d %d %d",&n,&m,&k);
    ps[1]=1;
    for(int i=2;i<1e7;i++) {
        ps[i]=ps[i-1];
        if(i>ps[i]) ps[i]=2*ps[i];
        //cout<<i<<" "<<ps[i]<<endl;
    }
    for(int i=1;i<=m;i++) a[i].push_back(1);
    for(int i=0;i<n;i++) {
        scanf("%d",&x);
        a[x].push_back(1);
    }
    printf("%d",mul(1,m)[k]);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
struct comp
{
    double x,y;
    comp(double xi,double yi) {
        x=xi;
        y=yi;
    }
    comp(double xi) {
        x=xi;
        y=0.0;
    }
    comp() {
        x=0.0;
        y=0.0;
    }
};
comp operator + (comp a,comp b) {
    return comp(a.x+b.x,a.y+b.y);
}
comp operator - (comp a,comp b) {
    return comp(a.x-b.x,a.y-b.y);
}
comp operator * (comp a,comp b) {
    return comp(a.x*b.x-a.y*b.y,a.x*b.y+b.x*a.y);
}
comp polarcomp (double r,double arg){
    return comp(r*cos(arg),r*sin(arg));
}
int n,m,k;
vector<int> a[2000005];
int ps[10000000];
vector<int> z;
int f;
vector<comp> pm[3];
int inverse(int i)
{
    int j=1;
    int rt=0;
    int l=f>>1;
    while(j<l) {
        if((i&j)) rt+=l;
        if((i&l)) rt+=j;
        j=(j<<1);
        l=(l>>1);
    }
    if(j==l && (i&j)==l) rt+=l;
    return rt;
}
void dft(int ind,bool inv) {
    for(int i=0;i<pm[ind].size();i++) {
        if(i<inverse(i)) swap(pm[ind][i],pm[ind][inverse(i)]);
    }
    comp d,w,x,y;
    for(int l=2;l<=f;l=(l<<1)) {
        if(!inv) w=polarcomp(1.0,2.00*acos(-1.0)/double(l));
        else w=polarcomp(1.0,-2.00*acos(-1.0)/double(l));
        //cout<<w.x<<" "<<w.y<<endl;
        for(int i=0;i<f;i=i+l) {
            d=comp(1.0,0.0);
            for(int j=i;j<i+(l>>1);j++) {
                x=pm[ind][j];
                y=pm[ind][j+(l>>1)]*d;
                pm[ind][j]=x+y;
                pm[ind][j+(l>>1)]=x-y;
                d=d*w;
            }
        }
        /*for(int i=0;i<pm[ind].size();i++) cout<<"("<<pm[ind][i].x<<","<<pm[ind][i].y<<") ";
        cout<<endl;*/
    }
}
vector<int> fft(vector<int> x,vector<int> y) {
    pm[0].clear();
    f=ps[x.size()+y.size()];
    while(pm[0].size()<f) pm[0].push_back(0.00);
    pm[1].clear();
    while(pm[1].size()<f) pm[1].push_back(0.00);
    pm[2].clear();
    while(pm[2].size()<f) pm[2].push_back(0.00);
    for(int i=0;i<x.size();i++) pm[0][i]=x[i];
    for(int i=0;i<y.size();i++) pm[1][i]=y[i];
    dft(0,false);
    dft(1,false);
    for(int i=0;i<pm[2].size();i++) pm[2][i]=pm[0][i]*pm[1][i];
    //for(int i=0;i<pm[0].size();i++) cout<<"("<<pm[0][i].x<<","<<pm[0][i].y<<") ("<<pm[1][i].x<<","<<pm[1][i].y<<") ("<<pm[2][i].x<<","<<pm[2][i].y<<")"<<endl;
    dft(2,true);
    for(int i=0;i<pm[2].size();i++) pm[2][i]=comp(pm[2][i].x/((double)(f)),pm[2][i].y/((double)(f)));
    //f=(f>>1);
    z.resize(pm[2].size());
    //cout<<f<<" "<<x.size()<<" "<<y.size()<<endl;
    for(int i=0;i<z.size();i++) {
        z[i]=((int)round(pm[2][i].x))%1009;
        //cout<<"("<<pm[2][i].x<<","<<pm[2][i].y<<")"<<endl;
    }
    return z;

}
vector<int> mul(int l,int r){
    //cout<<l<<" "<<r<<endl;
    if(l==r) return a[l];
    return fft(mul(l,((l+r)>>1)),mul(((l+r)>>1)+1,r));
}
int main()
{
    int x;
    scanf("%d %d %d",&n,&m,&k);
    ps[1]=1;
    for(int i=2;i<1e7;i++) {
        ps[i]=ps[i-1];
        if(i>ps[i]) ps[i]=2*ps[i];
        //cout<<i<<" "<<ps[i]<<endl;
    }
    for(int i=1;i<=m;i++) a[i].push_back(1);
    for(int i=0;i<n;i++) {
        scanf("%d",&x);
        a[x].push_back(1);
    }
    printf("%d",mul(1,m)[k]);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
struct comp
{
    double x,y;
    comp(double xi,double yi) {
        x=xi;
        y=yi;
    }
    comp(double xi) {
        x=xi;
        y=0.0;
    }
    comp() {
        x=0.0;
        y=0.0;
    }
};
comp operator + (comp a,comp b) {
    return comp(a.x+b.x,a.y+b.y);
}
comp operator - (comp a,comp b) {
    return comp(a.x-b.x,a.y-b.y);
}
comp operator * (comp a,comp b) {
    return comp(a.x*b.x-a.y*b.y,a.x*b.y+b.x*a.y);
}
comp polarcomp (double r,double arg){
    return comp(r*cos(arg),r*sin(arg));
}
int n,m,k;
vector<int> a[200005];
int ps[1000000];
vector<int> z;
int f;
vector<comp> pm[3];
int inverse(int i)
{
    int j=1;
    int rt=0;
    int l=f>>1;
    while(j<l) {
        if((i&j)) rt+=l;
        if((i&l)) rt+=j;
        j=(j<<1);
        l=(l>>1);
    }
    if(j==l && (i&j)==l) rt+=l;
    return rt;
}
void dft(int ind,bool inv) {
    for(int i=0;i<pm[ind].size();i++) {
        if(i<inverse(i)) swap(pm[ind][i],pm[ind][inverse(i)]);
    }
    comp d,w,x,y;
    for(int l=2;l<=f;l=(l<<1)) {
        if(!inv) w=polarcomp(1.0,2.00*acos(-1.0)/double(l));
        else w=polarcomp(1.0,-2.00*acos(-1.0)/double(l));
        //cout<<w.x<<" "<<w.y<<endl;
        for(int i=0;i<f;i=i+l) {
            d=comp(1.0,0.0);
            for(int j=i;j<i+(l>>1);j++) {
                x=pm[ind][j];
                y=pm[ind][j+(l>>1)]*d;
                pm[ind][j]=x+y;
                pm[ind][j+(l>>1)]=x-y;
                d=d*w;
            }
        }
        /*for(int i=0;i<pm[ind].size();i++) cout<<"("<<pm[ind][i].x<<","<<pm[ind][i].y<<") ";
        cout<<endl;*/
    }
}
vector<int> fft(vector<int> x,vector<int> y) {
    pm[0].clear();
    f=ps[x.size()+y.size()];
    while(pm[0].size()<f) pm[0].push_back(0.00);
    pm[1].clear();
    while(pm[1].size()<f) pm[1].push_back(0.00);
    pm[2].clear();
    while(pm[2].size()<f) pm[2].push_back(0.00);
    for(int i=0;i<x.size();i++) pm[0][i]=x[i];
    for(int i=0;i<y.size();i++) pm[1][i]=y[i];
    dft(0,false);
    dft(1,false);
    for(int i=0;i<pm[2].size();i++) pm[2][i]=pm[0][i]*pm[1][i];
    //for(int i=0;i<pm[0].size();i++) cout<<"("<<pm[0][i].x<<","<<pm[0][i].y<<") ("<<pm[1][i].x<<","<<pm[1][i].y<<") ("<<pm[2][i].x<<","<<pm[2][i].y<<")"<<endl;
    dft(2,true);
    for(int i=0;i<pm[2].size();i++) pm[2][i]=comp(pm[2][i].x/((double)(f)),pm[2][i].y/((double)(f)));
    //f=(f>>1);
    z.resize(pm[2].size());
    //cout<<f<<" "<<x.size()<<" "<<y.size()<<endl;
    for(int i=0;i<z.size();i++) {
        z[i]=round(pm[2][i].x);
        //cout<<"("<<pm[2][i].x<<","<<pm[2][i].y<<")"<<endl;
    }
    return z;

}
vector<int> mul(int l,int r){
    //cout<<l<<" "<<r<<endl;
    if(l==r) return a[l];
    return fft(mul(l,((l+r)>>1)),mul(((l+r)>>1)+1,r));
}
int main()
{
    int x;
    scanf("%d %d %d",&n,&m,&k);
    ps[1]=1;
    for(int i=2;i<1e6;i++) {
        ps[i]=ps[i-1];
        if(i>ps[i]) ps[i]=2*ps[i];
        //cout<<i<<" "<<ps[i]<<endl;
    }
    for(int i=1;i<=m;i++) a[i].push_back(1);
    for(int i=0;i<n;i++) {
        scanf("%d",&x);
        a[x].push_back(1);
    }
    printf("%d",mul(1,m)[k]);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
struct comp
{
    double x,y;
    comp(double xi,double yi) {
        x=xi;
        y=yi;
    }
    comp(double xi) {
        x=xi;
    }
    comp() {
        x=0.0;
        y=0.0;
    }
};
comp operator + (comp a,comp b) {
    return comp(a.x+b.x,a.y+b.y);
}
comp operator - (comp a,comp b) {
    return comp(a.x-b.x,a.y-b.y);
}
comp operator * (comp a,comp b) {
    return comp(a.x*b.x-a.y*b.y,2*a.x*b.y);
}
comp polarcomp (double r,double arg){
    return comp(r*cos(arg),r*sin(arg));
}
int n,m,k;
vector<int> a[200005];
int ps[1000000];
vector<int> z;
int f;
vector<comp> pm[3];
int inverse(int i)
{
    int j=1;
    int rt=0;
    int l=f>>1;
    while(j<l) {
        if((i&j)) rt+=l;
        if((i&l)) rt+=j;
        j=(j<<1);
        l=(l>>1);
    }
    if(j==l && (i&j)==l) rt+=l;
    return rt;
}
void dft(int ind,bool inv) {
    for(int i=0;i<pm[ind].size();i++) {
        if(i<inverse(i)) swap(pm[ind][i],pm[ind][inverse(i)]);
    }
    comp d,w,x,y;
    for(int l=2;l<=f;l=(l<<1)) {
        if(!inv) w=polarcomp(1.0,2.00*acos(-1.0)/double(l));
        else w=polarcomp(1.0,-2.00*acos(-1.0)/l);
        for(int i=0;i<f;i=i+l) {
            d=comp(1.0,0.0);
            for(int j=i;j<i+(l>>1);j++) {
                x=pm[ind][j];
                y=pm[ind][j+(l>>1)];
                pm[ind][j]=x+y*d;
                pm[ind][j+(l>>1)]=x-y*d;
                d=d*w;
            }
        }
    }
}
vector<int> fft(vector<int> x,vector<int> y) {
    pm[0].clear();
    f=ps[x.size()+y.size()];
    while(pm[0].size()<f) pm[0].push_back(0.00);
    pm[1].clear();
    while(pm[1].size()<f) pm[1].push_back(0.00);
    pm[2].clear();
    while(pm[2].size()<f) pm[2].push_back(0.00);
    for(int i=0;i<x.size();i++) pm[0][i]=x[i];
    for(int i=0;i<y.size();i++) pm[1][i]=y[i];
    dft(0,false);
    dft(1,false);
    for(int i=0;i<pm[2].size();i++) pm[2][i]=pm[0][i]*pm[1][i];
    dft(2,true);
    //f=(f>>1);
    for(int i=0;i<pm[2].size();i++) pm[2][i]=comp(pm[2][i].x/((double)(f)),pm[2][i].y/((double)(f)));
    z.resize(pm[2].size());
    cout<<f<<" "<<x.size()<<" "<<y.size()<<endl;
    for(int i=0;i<z.size();i++) {
        z[i]=round(pm[2][i].x);
        cout<<"("<<pm[2][i].x<<","<<pm[2][i].y<<")"<<endl;
    }
    return z;

}
vector<int> mul(int l,int r){
    cout<<l<<" "<<r<<endl;
    if(l==r) return a[l];
    return fft(mul(l,((l+r)>>1)),mul(((l+r)>>1)+1,r));
}
int main()
{
    int x;
    scanf("%d %d %d",&n,&m,&k);
    ps[1]=1;
    for(int i=2;i<1e6;i++) {
        ps[i]=ps[i-1];
        if(i>ps[i]) ps[i]=2*ps[i];
        //cout<<i<<" "<<ps[i]<<endl;
    }
    for(int i=1;i<=m;i++) a[i].push_back(1);
    for(int i=0;i<n;i++) {
        scanf("%d",&x);
        a[x].push_back(1);
    }
    printf("%d",mul(1,m)[k]);
    return 0;
}


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

constexpr float pi = std::acos(-1.0);

using data_type = std::complex<float>;

std::vector<data_type> fft(std::vector<data_type> v, bool inv = false) {
    int const n = v.size();
    double theta = 2 * pi / n * (inv ? -1 : 1);
    for(int m = n; m >= 2; m >>= 1) {
        int mh = m >> 1;
        data_type theta_i(0, theta);
        for(int i = 0; i < mh; ++i) {
            data_type w = std::exp((data_type)i * theta_i);
            for(int j = i; j < n; j += m) {
                data_type x = v[j] - v[j + mh]; // (a_k - a_{k + N/2})
                v[j] = v[j] + v[j + mh];   // (a_k + a_{k + N/2})
                v[j + mh] = w * x;         // (a_k - a_{k + N/2}) * W_N^j
            }
        }
        theta *= 2;
    }
    int i = 0;
    for(int j = 1; j < n - 1; ++j) {
        for(int k = n >> 1; k > (i ^= k); k >>= 1);
        if(j < i) {
            swap(v[i], v[j]);
        }
    }
    if(inv) {
        for(auto& x : v) x /= n;
    }
    return v;
}

std::vector<data_type> convolution(std::vector<data_type> x, std::vector<data_type> y) {
    int sz = 1;
    int t = x.size() + y.size() - 1;
    while(sz < t) {
        sz <<= 1;
    }
    x.resize(sz); y.resize(sz);
    x = fft(std::move(x)); y = fft(std::move(y));
    for(int i = 0; i < sz; ++i) {
        x[i] *= y[i];
    }
    x = fft(std::move(x), true);
    return x;
}

int n, m, k;

vector<int> solve(int l, int r, const vector<int>& cnt) {
    if(l + 1 == r) {
        return vector<int>(cnt[l] + 1, 1);
    }
    if(l >= r) {
        return vector<int>(1, 1);
    }

    auto v1 = solve(l, (l + r) / 2, cnt);
    auto v2 = solve((l + r) / 2, r, cnt);
    vector<data_type> w1(v1.size()), w2(v2.size());
    for(int i = 0; i < (int)v1.size(); ++i) {
        w1[i] = data_type(v1[i], 0);
    }
    for(int i = 0; i < (int)v2.size(); ++i) {
        w2[i] = data_type(v2[i], 0);
    }
    auto t = convolution(move(w1), move(w2));

    vector<int> res(min(k + 1, (int)t.size()));
    for(int i = 0; i < (int)res.size(); ++i) {
        res[i] = static_cast<int>(real(t[i]) + 0.1) % 1009;
    }
    return res;
}

int main() {
    cin >> n >> m >> k;
    vector<int> cnt(m);
    for(int i = 0; i < n; ++i) {
        int x; cin >> x;
        cnt[x - 1]++;
    }
    vector<int> cnt2;
    for(int i = 0; i < m; ++i) {
        if(cnt[i] > 0) cnt2.push_back(cnt[i]);
    }
    sort(begin(cnt2), end(cnt2));

    cout << solve(0, n, cnt2)[k] << endl;
}


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

constexpr double pi = std::acos(-1.0);

using data_type = std::complex<double>;

std::vector<data_type> fft(std::vector<data_type> v, bool inv = false) {
    int const n = v.size();
    double theta = 2 * pi / n * (inv ? -1 : 1);
    for(int m = n; m >= 2; m >>= 1) {
        int mh = m >> 1;
        data_type theta_i(0, theta);
        for(int i = 0; i < mh; ++i) {
            data_type w = std::exp((data_type)i * theta_i);
            for(int j = i; j < n; j += m) {
                data_type x = v[j] - v[j + mh]; // (a_k - a_{k + N/2})
                v[j] = v[j] + v[j + mh];   // (a_k + a_{k + N/2})
                v[j + mh] = w * x;         // (a_k - a_{k + N/2}) * W_N^j
            }
        }
        theta *= 2;
    }
    int i = 0;
    for(int j = 1; j < n - 1; ++j) {
        for(int k = n >> 1; k > (i ^= k); k >>= 1);
        if(j < i) {
            swap(v[i], v[j]);
        }
    }
    if(inv) {
        for(auto& x : v) x /= n;
    }
    return v;
}

std::vector<data_type> convolution(std::vector<data_type> x, std::vector<data_type> y) {
    int sz = 1;
    int t = x.size() + y.size() - 1;
    while(sz < t) {
        sz <<= 1;
    }
    x.resize(sz); y.resize(sz);
    x = fft(std::move(x)); y = fft(std::move(y));
    for(int i = 0; i < sz; ++i) {
        x[i] *= y[i];
    }
    x = fft(std::move(x), true);
    return x;
}

int n, m, k;

vector<int> solve(int l, int r, const vector<int>& cnt) {
    if(l + 1 == r) {
        return vector<int>(cnt[l] + 1, 1);
    }
    if(l >= r) {
        return vector<int>(1, 1);
    }

    auto v1 = solve(l, (l + r) / 2, cnt);
    auto v2 = solve((l + r) / 2, r, cnt);
    const int sz1 = v1.size();
    const int sz2 = v2.size();
    vector<data_type> w1(sz1), w2(sz2);
    for(int i = 0; i < sz1; ++i) {
        w1[i] = data_type(v1[i], 0);
    }
    for(int i = 0; i < sz2; ++i) {
        w2[i] = data_type(v2[i], 0);
    }
    auto t = convolution(move(w1), move(w2));

    vector<int> res(min(k + 1, (int)t.size()));
    for(int i = 0; i < (int)res.size(); ++i) {
        res[i] = static_cast<int>(real(t[i]) + 0.1) % 1009;
    }
    return res;
}

int main() {
    cin >> n >> m >> k;
    vector<int> cnt(m);
    for(int i = 0; i < n; ++i) {
        int x; cin >> x;
        cnt[x - 1]++;
    }

    cout << solve(0, m, cnt)[k] << endl;
}


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

//constexpr float pi = std::acos(-1.0);
//
//using data_type = std::complex<float>;
//
//std::vector<data_type> fft(std::vector<data_type> v, bool inv = false) {
//    int const n = v.size();
//    double theta = 2 * pi / n * (inv ? -1 : 1);
//    for(int m = n; m >= 2; m >>= 1) {
//        int mh = m >> 1;
//        data_type theta_i(0, theta);
//        for(int i = 0; i < mh; ++i) {
//            data_type w = std::exp((data_type)i * theta_i);
//            for(int j = i; j < n; j += m) {
//                data_type x = v[j] - v[j + mh]; // (a_k - a_{k + N/2})
//                v[j] = v[j] + v[j + mh];   // (a_k + a_{k + N/2})
//                v[j + mh] = w * x;         // (a_k - a_{k + N/2}) * W_N^j
//            }
//        }
//        theta *= 2;
//    }
//    int i = 0;
//    for(int j = 1; j < n - 1; ++j) {
//        for(int k = n >> 1; k > (i ^= k); k >>= 1);
//        if(j < i) {
//            swap(v[i], v[j]);
//        }
//    }
//    if(inv) {
//        for(auto& x : v) x /= n;
//    }
//    return v;
//}
//
//std::vector<data_type> convolution(std::vector<data_type> x, std::vector<data_type> y) {
//    int sz = 1;
//    int t = x.size() + y.size() - 1;
//    while(sz < t) {
//        sz <<= 1;
//    }
//    x.resize(sz); y.resize(sz);
//    x = fft(std::move(x)); y = fft(std::move(y));
//    for(int i = 0; i < sz; ++i) {
//        x[i] *= y[i];
//    }
//    x = fft(std::move(x), true);
//    return x;
//}

#include <cstdio>
#include <cassert>
#include <vector>

using namespace std;

typedef long long ll;
typedef pair<int, int> Pii;

#define FOR(i,n) for(int i = 0; i < (n); i++)
#define sz(c) ((int)(c).size())
#define ten(x) ((int)1e##x)

template<class T> T extgcd(T a, T b, T& x, T& y) { for (T u = y = 1, v = x = 0; a;) { T q = b / a; swap(x -= q * u, u); swap(y -= q * v, v); swap(b -= q * a, a); } return b; }
template<class T> T mod_inv(T a, T m) { T x, y; extgcd(a, m, x, y); return (m + x % m) % m; }
ll mod_pow(ll a, ll n, ll mod) { ll ret = 1; ll p = a % mod; while (n) { if (n & 1) ret = ret * p % mod; p = p * p % mod; n >>= 1; } return ret; }

template<int mod, int primitive_root>
class NTT {
public:
	int get_mod() const { return mod; }
	void _ntt(vector<ll>& a, int sign) {
		const int n = sz(a);
		assert((n ^ (n&-n)) == 0); //n = 2^k

		const int g = 3; //g is primitive root of mod
		int h = (int)mod_pow(g, (mod - 1) / n, mod); // h^n = 1
		if (sign == -1) h = (int)mod_inv(h, mod); //h = h^-1 % mod

		//bit reverse
		int i = 0;
		for (int j = 1; j < n - 1; ++j) {
			for (int k = n >> 1; k >(i ^= k); k >>= 1);
			if (j < i) swap(a[i], a[j]);
		}

		for (int m = 1; m < n; m *= 2) {
			const int m2 = 2 * m;
			const ll base = mod_pow(h, n / m2, mod);
			ll w = 1;
			FOR(x, m) {
				for (int s = x; s < n; s += m2) {
					ll u = a[s];
					ll d = a[s + m] * w % mod;
					a[s] = u + d;
					if (a[s] >= mod) a[s] -= mod;
					a[s + m] = u - d;
					if (a[s + m] < 0) a[s + m] += mod;
				}
				w = w * base % mod;
			}
		}

		for (auto& x : a) if (x < 0) x += mod;
	}
	void ntt(vector<ll>& input) {
		_ntt(input, 1);
	}
	void intt(vector<ll>& input) {
		_ntt(input, -1);
		const int n_inv = mod_inv(sz(input), mod);
		for (auto& x : input) x = x * n_inv % mod;
	}

	// 畳み込み演算を行う
	vector<ll> convolution(const vector<ll>& a, const vector<ll>& b){
		int ntt_size = 1;
		while (ntt_size < sz(a) + sz(b)) ntt_size *= 2;

		vector<ll> _a = a, _b = b;
		_a.resize(ntt_size); _b.resize(ntt_size);

		ntt(_a);
		ntt(_b);

		FOR(i, ntt_size){
			(_a[i] *= _b[i]) %= mod;
		}

		intt(_a);
		return _a;
	}
};

ll garner(vector<Pii> mr, int mod){
	mr.emplace_back(mod, 0);

	vector<ll> coffs(sz(mr), 1);
	vector<ll> constants(sz(mr), 0);
	FOR(i, sz(mr) - 1){
		// coffs[i] * v + constants[i] == mr[i].second (mod mr[i].first) を解く
		ll v = (mr[i].second - constants[i]) * mod_inv<ll>(coffs[i], mr[i].first) % mr[i].first;
		if (v < 0) v += mr[i].first;

		for (int j = i + 1; j < sz(mr); j++) {
			(constants[j] += coffs[j] * v) %= mr[j].first;
			(coffs[j] *= mr[i].first) %= mr[j].first;
		}
	}

	return constants[sz(mr) - 1];
}

typedef NTT<167772161, 3> NTT_1;
typedef NTT<469762049, 3> NTT_2;
typedef NTT<1224736769, 3> NTT_3;

//任意のmodで畳み込み演算 O(n log n)
vector<ll> int32mod_convolution(vector<ll> a, vector<ll> b,int mod){
	for (auto& x : a) x %= mod;
	for (auto& x : b) x %= mod;
	NTT_1 ntt1; NTT_2 ntt2; NTT_3 ntt3;
	auto x = ntt1.convolution(a, b);
	auto y = ntt2.convolution(a, b);
	auto z = ntt3.convolution(a, b);

	vector<ll> ret(sz(x));
	vector<Pii> mr(3);
	FOR(i, sz(x)){
		mr[0].first = ntt1.get_mod(), mr[0].second = (int)x[i];
		mr[1].first = ntt2.get_mod(), mr[1].second = (int)y[i];
		mr[2].first = ntt3.get_mod(), mr[2].second = (int)z[i];
		ret[i] = garner(mr, mod);
	}

	return ret;
}

// garnerのアルゴリズムを直書きしたversion，速い
vector<ll> fast_int32mod_convolution(vector<ll> a, vector<ll> b,int mod){
	for (auto& x : a) x %= mod;
	for (auto& x : b) x %= mod;

	NTT_1 ntt1; NTT_2 ntt2; NTT_3 ntt3;
	assert(ntt1.get_mod() < ntt2.get_mod() && ntt2.get_mod() < ntt3.get_mod());
	auto x = ntt1.convolution(a, b);
	auto y = ntt2.convolution(a, b);
	auto z = ntt3.convolution(a, b);

	// garnerのアルゴリズムを極力高速化した
	const ll m1 = ntt1.get_mod(), m2 = ntt2.get_mod(), m3 = ntt3.get_mod();
	const ll m1_inv_m2 = mod_inv<ll>(m1, m2);
	const ll m12_inv_m3 = mod_inv<ll>(m1 * m2, m3);
	const ll m12_mod = m1 * m2 % mod;
	vector<ll> ret(sz(x));
	FOR(i, sz(x)){
		ll v1 = (y[i] - x[i]) *  m1_inv_m2 % m2;
		if (v1 < 0) v1 += m2;
		ll v2 = (z[i] - (x[i] + m1 * v1) % m3) * m12_inv_m3 % m3;
		if (v2 < 0) v2 += m3;
		ll constants3 = (x[i] + m1 * v1 + m12_mod * v2) % mod;
		if (constants3 < 0) constants3 += mod;
		ret[i] = constants3;
	}

	return ret;
}

void int32mod_convolution_test(){
	vector<ll> x , y;
	FOR(i, 10) x.push_back(ten(8) + i);
	y = x;

	auto z = int32mod_convolution(x, y, ten(9) + 7);
	z.resize(sz(x) + sz(y) - 1);
	vector<ll> z2 = {
		930000007, 60000000, 390000001, 920000004,
		650000003, 580000006, 710000014, 40000021,
		570000042, 300000064, 370000109, 240000144,
		910000175, 380000187, 650000193, 720000185,
		590000162, 260000123, 730000074 };
	assert(z == z2);
}

int n, m, k;

vector<ll> solve(int l, int r, const vector<int>& cnt) {
    if(l + 1 == r) {
        return vector<ll>(cnt[l] + 1, 1);
    }
    if(l >= r) {
        return vector<ll>(1, 1);
    }

    auto v1 = solve(l, (l + r) / 2, cnt);
    auto v2 = solve((l + r) / 2, r, cnt);
    auto res = int32mod_convolution(move(v1), move(v2), 1009);
    res.resize(k + 1);
    return res;
}

int main() {
    cin >> n >> m >> k;
    vector<int> cnt(m);
    for(int i = 0; i < n; ++i) {
        int x; cin >> x;
        cnt[x - 1]++;
    }

    cout << solve(0, n, cnt)[k] << endl;
}


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

constexpr double pi = std::acos(-1.0);

using data_type = std::complex<double>;
using ll = long long;

std::vector<data_type> fft(std::vector<data_type> v, bool inv = false) {
    int const n = v.size();
    double theta = 2 * pi / n * (inv ? -1 : 1);
    for(int m = n; m >= 2; m >>= 1) {
        int mh = m >> 1;
        data_type theta_i(0, theta);
        for(int i = 0; i < mh; ++i) {
            data_type w = std::exp((data_type)i * theta_i);
            for(int j = i; j < n; j += m) {
                data_type x = v[j] - v[j + mh]; // (a_k - a_{k + N/2})
                v[j] = v[j] + v[j + mh];   // (a_k + a_{k + N/2})
                v[j + mh] = w * x;         // (a_k - a_{k + N/2}) * W_N^j
            }
        }
        theta *= 2;
    }
    int i = 0;
    for(int j = 1; j < n - 1; ++j) {
        for(int k = n >> 1; k > (i ^= k); k >>= 1);
        if(j < i) {
            swap(v[i], v[j]);
        }
    }
    if(inv) {
        for(auto& x : v) x /= n;
    }
    return v;
}

std::vector<data_type> convolution(std::vector<data_type> x, std::vector<data_type> y) {
    int sz = 1;
    int t = x.size() + y.size() - 1;
    while(sz < t) {
        sz <<= 1;
    }
    x.resize(sz); y.resize(sz);
    x = fft(std::move(x)); y = fft(std::move(y));
    for(int i = 0; i < sz; ++i) {
        x[i] *= y[i];
    }
    x = fft(std::move(x), true);
    return x;
}

int n, m, k;

vector<ll> solve(int l, int r, const vector<ll>& sum) {
    if(l + 1 == r) {
        return vector<ll>(sum[r] - sum[l] + 1, 1);
    }
    if(l >= r) {
        return vector<ll>(1, 1);
    }

    auto v1 = solve(l, (l + r) / 2, sum);
    auto v2 = solve((l + r) / 2, r, sum);
    v1.resize(min(sum[(l + r) / 2] - sum[l] + 1, (ll)v1.size()));
    v2.resize(min(sum[r] - sum[(l + r) / 2] + 1, (ll)v2.size()));
    const int sz1 = v1.size();
    const int sz2 = v2.size();
    vector<data_type> w1(sz1), w2(sz2);
    for(int i = 0; i < sz1; ++i) {
        w1[i] = data_type(v1[i], 0);
    }
    for(int i = 0; i < sz2; ++i) {
        w2[i] = data_type(v2[i], 0);
    }
    auto t = convolution(move(w1), move(w2));

    vector<ll> res(min(sum[r] - sum[l] + 1, (ll)t.size()));
    for(int i = 0; i < (int)res.size(); ++i) {
        res[i] = static_cast<ll>(real(t[i]) + 0.1) % 1009;
    }
    return res;
}

int main() {
    cin >> n >> m >> k;
    vector<ll> cnt(m);
    for(int i = 0; i < n; ++i) {
        int x; cin >> x;
        cnt[x - 1]++;
    }
    vector<ll> sum(m + 1);
    for(int i = 0; i < m; ++i) {
        sum[i + 1] = sum[i] + cnt[i];
    }

    cout << solve(0, m, sum)[k] << endl;
}


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

constexpr float pi = std::acos(-1.0);

using data_type = std::complex<float>;

std::vector<data_type> fft(std::vector<data_type> v, bool inv = false) {
    int const n = v.size();
    double theta = 2 * pi / n * (inv ? -1 : 1);
    for(int m = n; m >= 2; m >>= 1) {
        int mh = m >> 1;
        data_type theta_i(0, theta);
        for(int i = 0; i < mh; ++i) {
            data_type w = std::exp((data_type)i * theta_i);
            for(int j = i; j < n; j += m) {
                data_type x = v[j] - v[j + mh]; // (a_k - a_{k + N/2})
                v[j] = v[j] + v[j + mh];   // (a_k + a_{k + N/2})
                v[j + mh] = w * x;         // (a_k - a_{k + N/2}) * W_N^j
            }
        }
        theta *= 2;
    }
    int i = 0;
    for(int j = 1; j < n - 1; ++j) {
        for(int k = n >> 1; k > (i ^= k); k >>= 1);
        if(j < i) {
            swap(v[i], v[j]);
        }
    }
    if(inv) {
        for(auto& x : v) x /= n;
    }
    return v;
}

std::vector<data_type> convolution(std::vector<data_type> x, std::vector<data_type> y) {
    int sz = 1;
    int t = x.size() + y.size() - 1;
    while(sz < t) {
        sz <<= 1;
    }
    x.resize(sz); y.resize(sz);
    x = fft(std::move(x)); y = fft(std::move(y));
    for(int i = 0; i < sz; ++i) {
        x[i] *= y[i];
    }
    x = fft(std::move(x), true);
    return x;
}

int n, m, k;

vector<int> solve(int l, int r, const vector<int>& cnt) {
    if(l + 1 == r) {
        return vector<int>(cnt[l] + 1, 1);
    }
    if(l >= r) {
        return vector<int>(1, 1);
    }

    auto v1 = solve(l, (l + r) / 2, cnt);
    auto v2 = solve((l + r) / 2, r, cnt);
    const int sz1 = v1.size();
    const int sz2 = v2.size();
    vector<data_type> w1(sz1), w2(sz2);
    for(int i = 0; i < sz1; ++i) {
        w1[i] = data_type(v1[i], 0);
    }
    for(int i = 0; i < sz2; ++i) {
        w2[i] = data_type(v2[i], 0);
    }
    auto t = convolution(move(w1), move(w2));

    vector<int> res(min({k + 1, (int)t.size(), r - l + 1}));
    for(int i = 0; i < (int)res.size(); ++i) {
        res[i] = static_cast<int>(real(t[i]) + 0.1) % 1009;
    }
    return res;
}

int main() {
    cin >> n >> m >> k;
    vector<int> cnt(m);
    for(int i = 0; i < n; ++i) {
        int x; cin >> x;
        cnt[x - 1]++;
    }

    cout << solve(0, n, cnt)[k] << endl;
}


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

constexpr float pi = std::acos(-1.0);

using data_type = std::complex<float>;

std::vector<data_type> fft(std::vector<data_type> v, bool inv = false) {
    int const n = v.size();
    double theta = 2 * pi / n * (inv ? -1 : 1);
    for(int m = n; m >= 2; m >>= 1) {
        int mh = m >> 1;
        data_type theta_i(0, theta);
        for(int i = 0; i < mh; ++i) {
            data_type w = std::exp((data_type)i * theta_i);
            for(int j = i; j < n; j += m) {
                data_type x = v[j] - v[j + mh]; // (a_k - a_{k + N/2})
                v[j] = v[j] + v[j + mh];   // (a_k + a_{k + N/2})
                v[j + mh] = w * x;         // (a_k - a_{k + N/2}) * W_N^j
            }
        }
        theta *= 2;
    }
    int i = 0;
    for(int j = 1; j < n - 1; ++j) {
        for(int k = n >> 1; k > (i ^= k); k >>= 1);
        if(j < i) {
            swap(v[i], v[j]);
        }
    }
    if(inv) {
        for(auto& x : v) x /= n;
    }
    return v;
}

std::vector<data_type> convolution(std::vector<data_type> x, std::vector<data_type> y) {
    int sz = 1;
    int t = x.size() + y.size() - 1;
    while(sz < t) {
        sz <<= 1;
    }
    x.resize(sz); y.resize(sz);
    x = fft(std::move(x)); y = fft(std::move(y));
    for(int i = 0; i < sz; ++i) {
        x[i] *= y[i];
    }
    x = fft(std::move(x), true);
    return x;
}

int n, m, k;

vector<int> solve(int l, int r, const vector<int>& cnt) {
    if(l + 1 == r) {
        return vector<int>(cnt[l] + 1, 1);
    }
    if(l >= r) {
        return vector<int>(1, 1);
    }

    auto v1 = solve(l, (l + r) / 2, cnt);
    auto v2 = solve((l + r) / 2, r, cnt);
    const int sz1 = v1.size();
    const int sz2 = v2.size();
    vector<data_type> w1(sz1), w2(sz2);
    for(int i = 0; i < sz1; ++i) {
        w1[i] = data_type(v1[i], 0);
    }
    for(int i = 0; i < sz2; ++i) {
        w2[i] = data_type(v2[i], 0);
    }
    auto t = convolution(move(w1), move(w2));

    vector<int> res(min({k + 1, (int)t.size(), r - l + 1}));
    for(int i = 0; i < (int)res.size(); ++i) {
        res[i] = static_cast<int>(real(t[i]) + 0.1) % 1009;
    }
    return res;
}

int main() {
    cin >> n >> m >> k;
    vector<int> cnt(m);
    for(int i = 0; i < n; ++i) {
        int x; cin >> x;
        cnt[x - 1]++;
    }

    cout << solve(0, n, cnt)[0] << endl;
}


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

constexpr float pi = std::acos(-1.0);

using data_type = std::complex<float>;

std::vector<data_type> fft(std::vector<data_type> v, bool inv = false) {
    int const n = v.size();
    double theta = 2 * pi / n * (inv ? -1 : 1);
    for(int m = n; m >= 2; m >>= 1) {
        int mh = m >> 1;
        data_type theta_i(0, theta);
        for(int i = 0; i < mh; ++i) {
            data_type w = std::exp((data_type)i * theta_i);
            for(int j = i; j < n; j += m) {
                data_type x = v[j] - v[j + mh]; // (a_k - a_{k + N/2})
                v[j] = v[j] + v[j + mh];   // (a_k + a_{k + N/2})
                v[j + mh] = w * x;         // (a_k - a_{k + N/2}) * W_N^j
            }
        }
        theta *= 2;
    }
    int i = 0;
    for(int j = 1; j < n - 1; ++j) {
        for(int k = n >> 1; k > (i ^= k); k >>= 1);
        if(j < i) {
            swap(v[i], v[j]);
        }
    }
    if(inv) {
        for(auto& x : v) x /= n;
    }
    return v;
}

std::vector<data_type> convolution(std::vector<data_type> x, std::vector<data_type> y) {
    int sz = 1;
    int t = x.size() + y.size() - 1;
    while(sz < t) {
        sz <<= 1;
    }
    x.resize(sz); y.resize(sz);
    x = fft(std::move(x)); y = fft(std::move(y));
    for(int i = 0; i < sz; ++i) {
        x[i] *= y[i];
    }
    x = fft(std::move(x), true);
    return x;
}

int n, m, k;

vector<short> solve(int l, int r, const vector<int>& cnt) {
    if(l + 1 == r) {
        return vector<short>(cnt[l] + 1, 1);
    }
    if(l >= r) {
        return vector<short>(1, 1);
    }

    auto v1 = solve(l, (l + r) / 2, cnt);
    auto v2 = solve((l + r) / 2, r, cnt);
    vector<data_type> w1(v1.size()), w2(v2.size());
    for(int i = 0; i < (int)v1.size(); ++i) {
        w1[i] = data_type(v1[i], 0);
    }
    for(int i = 0; i < (int)v2.size(); ++i) {
        w2[i] = data_type(v2[i], 0);
    }
    auto t = convolution(move(w1), move(w2));

    vector<short> res(min(k + 1, (int)t.size()));
    for(int i = 0; i < (int)res.size(); ++i) {
        res[i] = static_cast<short>(real(t[i]) + 0.1) % 1009;
    }
    return res;
}

int main() {
    cin >> n >> m >> k;
    vector<int> cnt(m);
    for(int i = 0; i < n; ++i) {
        int x; cin >> x;
        cnt[x - 1]++;
    }
    vector<int> cnt2;
    for(int i = 0; i < m; ++i) {
        if(cnt[i] > 0) cnt2.push_back(cnt[i]);
    }
    sort(begin(cnt2), end(cnt2));

    cout << solve(0, n, cnt2)[k] << endl;
}


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

constexpr float pi = std::acos(-1.0);

using data_type = std::complex<float>;

std::vector<data_type> fft(std::vector<data_type> v, bool inv = false) {
    int const n = v.size();
    double theta = 2 * pi / n * (inv ? -1 : 1);
    for(int m = n; m >= 2; m >>= 1) {
        int mh = m >> 1;
        data_type theta_i(0, theta);
        for(int i = 0; i < mh; ++i) {
            data_type w = std::exp((data_type)i * theta_i);
            for(int j = i; j < n; j += m) {
                data_type x = v[j] - v[j + mh]; // (a_k - a_{k + N/2})
                v[j] = v[j] + v[j + mh];   // (a_k + a_{k + N/2})
                v[j + mh] = w * x;         // (a_k - a_{k + N/2}) * W_N^j
            }
        }
        theta *= 2;
    }
    int i = 0;
    for(int j = 1; j < n - 1; ++j) {
        for(int k = n >> 1; k > (i ^= k); k >>= 1);
        if(j < i) {
            swap(v[i], v[j]);
        }
    }
    if(inv) {
        for(auto& x : v) x /= n;
    }
    return v;
}

std::vector<data_type> convolution(std::vector<data_type> x, std::vector<data_type> y) {
    int sz = 1;
    int t = x.size() + y.size() - 1;
    while(sz < t) {
        sz <<= 1;
    }
    x.resize(sz); y.resize(sz);
    x = fft(std::move(x)); y = fft(std::move(y));
    for(int i = 0; i < sz; ++i) {
        x[i] *= y[i];
    }
    x = fft(std::move(x), true);
    return x;
}

int n, m, k;

vector<int> solve(int l, int r, const vector<int>& cnt) {
    if(l + 1 == r) {
        return vector<int>(cnt[l] + 1, 1);
    }
    if(l >= r) {
        return vector<int>(1, 1);
    }

    auto v1 = solve(l, (l + r) / 2, cnt);
    auto v2 = solve((l + r) / 2, r, cnt);
    const int sz1 = v1.size();
    const int sz2 = v2.size();
    vector<data_type> w1(sz1), w2(sz2);
    for(int i = 0; i < sz1; ++i) {
        w1[i] = data_type(v1[i], 0);
    }
    for(int i = 0; i < sz2; ++i) {
        w2[i] = data_type(v2[i], 0);
    }
    auto t = convolution(move(w1), move(w2));

    vector<int> res(min(k + 1, (int)t.size()));
    for(int i = 0; i < (int)res.size(); ++i) {
        res[i] = static_cast<int>(real(t[i]) + 0.1) % 1009;
    }
    return res;
}

int main() {
    cin >> n >> m >> k;
    vector<int> cnt(m);
    for(int i = 0; i < n; ++i) {
        int x; cin >> x;
        cnt[x - 1]++;
    }

    cout << solve(0, m, cnt)[k] << endl;
}


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

constexpr double pi = std::acos(-1.0);

using data_type = std::complex<double>;
using ll = long long;

std::vector<data_type> fft(std::vector<data_type> v, bool inv = false) {
    int const n = v.size();
    double theta = 2 * pi / n * (inv ? -1 : 1);
    for(int m = n; m >= 2; m >>= 1) {
        int mh = m >> 1;
        data_type theta_i(0, theta);
        for(int i = 0; i < mh; ++i) {
            data_type w = std::exp((data_type)i * theta_i);
            for(int j = i; j < n; j += m) {
                data_type x = v[j] - v[j + mh]; // (a_k - a_{k + N/2})
                v[j] = v[j] + v[j + mh];   // (a_k + a_{k + N/2})
                v[j + mh] = w * x;         // (a_k - a_{k + N/2}) * W_N^j
            }
        }
        theta *= 2;
    }
    int i = 0;
    for(int j = 1; j < n - 1; ++j) {
        for(int k = n >> 1; k > (i ^= k); k >>= 1);
        if(j < i) {
            swap(v[i], v[j]);
        }
    }
    if(inv) {
        for(auto& x : v) x /= n;
    }
    return v;
}

std::vector<data_type> convolution(std::vector<data_type> x, std::vector<data_type> y) {
    int sz = 1;
    int t = x.size() + y.size() - 1;
    while(sz < t) {
        sz <<= 1;
    }
    x.resize(sz); y.resize(sz);
    x = fft(std::move(x)); y = fft(std::move(y));
    for(int i = 0; i < sz; ++i) {
        x[i] *= y[i];
    }
    x = fft(std::move(x), true);
    return x;
}

int n, m, k;

vector<ll> solve(int l, int r, const vector<ll>& cnt) {
    if(l + 1 == r) {
        return vector<ll>(cnt[l] + 1, 1);
    }
    if(l >= r) {
        return vector<ll>(1, 1);
    }

    auto v1 = solve(l, (l + r) / 2, cnt);
    auto v2 = solve((l + r) / 2, r, cnt);
    const int sz1 = v1.size();
    const int sz2 = v2.size();
    vector<data_type> w1(sz1), w2(sz2);
    for(int i = 0; i < sz1; ++i) {
        w1[i] = data_type(v1[i], 0);
    }
    for(int i = 0; i < sz2; ++i) {
        w2[i] = data_type(v2[i], 0);
    }
    auto t = convolution(move(w1), move(w2));

    vector<ll> res(min(k + 1, (int)t.size()));
    for(int i = 0; i < (int)res.size(); ++i) {
        res[i] = static_cast<ll>(real(t[i]) + 0.1) % 1009;
    }
    return res;
}

int main() {
    cin >> n >> m >> k;
    vector<ll> cnt(m);
    for(int i = 0; i < n; ++i) {
        int x; cin >> x;
        cnt[x - 1]++;
    }

    cout << solve(0, m, cnt)[k] << endl;
}


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

constexpr double pi = std::acos(-1.0);

using data_type = std::complex<double>;

std::vector<data_type> fft(std::vector<data_type> v, bool inv = false) {
    int const n = v.size();
    double theta = 2 * pi / n * (inv ? -1 : 1);
    for(int m = n; m >= 2; m >>= 1) {
        int mh = m >> 1;
        data_type theta_i(0, theta);
        for(int i = 0; i < mh; ++i) {
            data_type w = std::exp((data_type)i * theta_i);
            for(int j = i; j < n; j += m) {
                data_type x = v[j] - v[j + mh]; // (a_k - a_{k + N/2})
                v[j] = v[j] + v[j + mh];   // (a_k + a_{k + N/2})
                v[j + mh] = w * x;         // (a_k - a_{k + N/2}) * W_N^j
            }
        }
        theta *= 2;
    }
    int i = 0;
    for(int j = 1; j < n - 1; ++j) {
        for(int k = n >> 1; k > (i ^= k); k >>= 1);
        if(j < i) {
            swap(v[i], v[j]);
        }
    }
    if(inv) {
        for(auto& x : v) x /= n;
    }
    return v;
}

std::vector<data_type> convolution(std::vector<data_type> x, std::vector<data_type> y) {
    int sz = 1;
    int t = x.size() + y.size() - 1;
    while(sz < t) {
        sz <<= 1;
    }
    x.resize(sz); y.resize(sz);
    x = fft(std::move(x)); y = fft(std::move(y));
    for(int i = 0; i < sz; ++i) {
        x[i] *= y[i];
    }
    x = fft(std::move(x), true);
    return x;
}

int n, m, k;

vector<int> solve(int l, int r, const vector<int>& cnt) {
    if(l + 1 == r) {
        return vector<int>(cnt[l] + 1, 1);
    }
    if(l >= r) {
        return vector<int>(1, 1);
    }

    auto v1 = solve(l, (l + r) / 2, cnt);
    auto v2 = solve((l + r) / 2, r, cnt);
    vector<data_type> w1(v1.size()), w2(v2.size());
    for(int i = 0; i < (int)v1.size(); ++i) {
        w1[i] = data_type(round(v1[i]), 0);
    }
    for(int i = 0; i < (int)v2.size(); ++i) {
        w2[i] = data_type(round(v2[i]), 0);
    }
    auto t = convolution(move(w1), move(w2));

    vector<int> res(min(k + 1, (int)t.size()));
    for(int i = 0; i < (int)res.size(); ++i) {
        res[i] = round(real(t[i]));
        res[i] %= 1009;
    }
    return res;
}

int main() {
    cin >> n >> m >> k;
    vector<int> cnt(m);
    for(int i = 0; i < n; ++i) {
        int x; cin >> x;
        cnt[x - 1]++;
    }

    cout << solve(0, n, cnt)[k] << endl;
}


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

constexpr float pi = std::acos(-1.0);

using data_type = std::complex<float>;

std::vector<data_type> fft(std::vector<data_type> v, bool inv = false) {
    int const n = v.size();
    double theta = 2 * pi / n * (inv ? -1 : 1);
    for(int m = n; m >= 2; m >>= 1) {
        int mh = m >> 1;
        data_type theta_i(0, theta);
        for(int i = 0; i < mh; ++i) {
            data_type w = std::exp((data_type)i * theta_i);
            for(int j = i; j < n; j += m) {
                data_type x = v[j] - v[j + mh]; // (a_k - a_{k + N/2})
                v[j] = v[j] + v[j + mh];   // (a_k + a_{k + N/2})
                v[j + mh] = w * x;         // (a_k - a_{k + N/2}) * W_N^j
            }
        }
        theta *= 2;
    }
    int i = 0;
    for(int j = 1; j < n - 1; ++j) {
        for(int k = n >> 1; k > (i ^= k); k >>= 1);
        if(j < i) {
            swap(v[i], v[j]);
        }
    }
    if(inv) {
        for(auto& x : v) x /= n;
    }
    return v;
}

std::vector<data_type> convolution(std::vector<data_type> x, std::vector<data_type> y) {
    int sz = 1;
    int t = x.size() + y.size() - 1;
    while(sz < t) {
        sz <<= 1;
    }
    x.resize(sz); y.resize(sz);
    x = fft(std::move(x)); y = fft(std::move(y));
    for(int i = 0; i < sz; ++i) {
        x[i] *= y[i];
    }
    x = fft(std::move(x), true);
    return x;
}

int n, m, k;

vector<int> solve(int l, int r, const vector<int>& cnt) {
    if(l + 1 == r) {
        return vector<int>(cnt[l] + 1, 1);
    }
    if(l >= r) {
        return vector<int>(1, 1);
    }

    auto v1 = solve(l, (l + r) / 2, cnt);
    auto v2 = solve((l + r) / 2, r, cnt);
    const int sz1 = v1.size();
    const int sz2 = v2.size();
    static vector<data_type> w1(sz1), w2(sz2);
    for(int i = 0; i < sz1; ++i) {
        w1[i] = data_type(v1[i], 0);
    }
    for(int i = 0; i < sz2; ++i) {
        w2[i] = data_type(v2[i], 0);
    }
    auto t = convolution(move(w1), move(w2));

    vector<int> res(min({k + 1, (int)t.size(), r - l + 1}));
    for(int i = 0; i < (int)res.size(); ++i) {
        res[i] = static_cast<int>(real(t[i]) + 0.1) % 1009;
    }
    return res;
}

int main() {
    cin >> n >> m >> k;
    vector<int> cnt(m);
    for(int i = 0; i < n; ++i) {
        int x; cin >> x;
        cnt[x - 1]++;
    }
    vector<int> cnt2;
    for(int i = 0; i < m; ++i) {
        if(cnt[i] > 0) cnt2.push_back(cnt[i]);
    }
    sort(begin(cnt2), end(cnt2));

    cout << solve(0, n, cnt2)[k] << endl;
}


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

constexpr float pi = std::acos(-1.0);

using data_type = std::complex<float>;

std::vector<data_type> fft(std::vector<data_type> v, bool inv = false) {
    int const n = v.size();
    double theta = 2 * pi / n * (inv ? -1 : 1);
    for(int m = n; m >= 2; m >>= 1) {
        int mh = m >> 1;
        data_type theta_i(0, theta);
        for(int i = 0; i < mh; ++i) {
            data_type w = std::exp((data_type)i * theta_i);
            for(int j = i; j < n; j += m) {
                data_type x = v[j] - v[j + mh]; // (a_k - a_{k + N/2})
                v[j] = v[j] + v[j + mh];   // (a_k + a_{k + N/2})
                v[j + mh] = w * x;         // (a_k - a_{k + N/2}) * W_N^j
            }
        }
        theta *= 2;
    }
    int i = 0;
    for(int j = 1; j < n - 1; ++j) {
        for(int k = n >> 1; k > (i ^= k); k >>= 1);
        if(j < i) {
            swap(v[i], v[j]);
        }
    }
    if(inv) {
        for(auto& x : v) x /= n;
    }
    return v;
}

std::vector<data_type> convolution(std::vector<data_type> x, std::vector<data_type> y) {
    int sz = 1;
    int t = x.size() + y.size() - 1;
    while(sz < t) {
        sz <<= 1;
    }
    x.resize(sz); y.resize(sz);
    x = fft(std::move(x)); y = fft(std::move(y));
    for(int i = 0; i < sz; ++i) {
        x[i] *= y[i];
    }
    x = fft(std::move(x), true);
    return x;
}

int n, m, k;

vector<int> solve(int l, int r, const vector<int>& cnt) {
    if(l + 1 == r) {
        return vector<int>(cnt[l] + 1, 1);
    }
    if(l >= r) {
        return vector<int>(1, 1);
    }

    auto v1 = solve(l, (l + r) / 2, cnt);
    auto v2 = solve((l + r) / 2, r, cnt);
    const int sz1 = v1.size();
    const int sz2 = v2.size();
    vector<data_type> w1(sz1), w2(sz2);
    for(int i = 0; i < sz1; ++i) {
        w1[i] = data_type(v1[i], 0);
    }
    for(int i = 0; i < sz2; ++i) {
        w2[i] = data_type(v2[i], 0);
    }
    auto t = convolution(move(w1), move(w2));

    vector<int> res(min({k + 1, (int)t.size(), r - l + 1}));
    for(int i = 0; i < (int)res.size(); ++i) {
        res[i] = static_cast<int>(real(t[i]) + 0.1) % 1009;
    }
    return res;
}

int main() {
    cin >> n >> m >> k;
    vector<int> cnt(m);
    for(int i = 0; i < n; ++i) {
        int x; cin >> x;
        cnt[x - 1]++;
    }

    cout << solve(0, m, cnt)[k] << endl;
}


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

constexpr float pi = std::acos(-1.0);

using data_type = std::complex<float>;

std::vector<data_type> fft(std::vector<data_type> v, bool inv = false) {
    int const n = v.size();
    double theta = 2 * pi / n * (inv ? -1 : 1);
    for(int m = n; m >= 2; m >>= 1) {
        int mh = m >> 1;
        data_type theta_i(0, theta);
        for(int i = 0; i < mh; ++i) {
            data_type w = std::exp((data_type)i * theta_i);
            for(int j = i; j < n; j += m) {
                data_type x = v[j] - v[j + mh]; // (a_k - a_{k + N/2})
                v[j] = v[j] + v[j + mh];   // (a_k + a_{k + N/2})
                v[j + mh] = w * x;         // (a_k - a_{k + N/2}) * W_N^j
            }
        }
        theta *= 2;
    }
    int i = 0;
    for(int j = 1; j < n - 1; ++j) {
        for(int k = n >> 1; k > (i ^= k); k >>= 1);
        if(j < i) {
            swap(v[i], v[j]);
        }
    }
    if(inv) {
        for(auto& x : v) x /= n;
    }
    return v;
}

std::vector<data_type> convolution(std::vector<data_type> x, std::vector<data_type> y) {
    int sz = 1;
    int t = x.size() + y.size() - 1;
    while(sz < t) {
        sz <<= 1;
    }
    x.resize(sz); y.resize(sz);
    x = fft(std::move(x)); y = fft(std::move(y));
    for(int i = 0; i < sz; ++i) {
        x[i] *= y[i];
    }
    x = fft(std::move(x), true);
    return x;
}

int n, m, k;

vector<int> solve(int l, int r, const vector<int>& cnt) {
    if(l + 1 == r) {
        return vector<int>(cnt[l] + 1, 1);
    }
    if(l >= r) {
        return vector<int>(1, 1);
    }

    auto v1 = solve(l, (l + r) / 2, cnt);
    auto v2 = solve((l + r) / 2, r, cnt);
    vector<data_type> w1(v1.size()), w2(v2.size());
    for(int i = 0; i < (int)v1.size(); ++i) {
        w1[i] = data_type(round(v1[i]), 0);
    }
    for(int i = 0; i < (int)v2.size(); ++i) {
        w2[i] = data_type(round(v2[i]), 0);
    }
    auto t = convolution(move(w1), move(w2));

    vector<int> res(min(k + 1, (int)t.size()));
    for(int i = 0; i < (int)res.size(); ++i) {
        res[i] = round(real(t[i]));
        res[i] %= 1009;
    }
    return res;
}

int main() {
    cin >> n >> m >> k;
    vector<int> cnt(m);
    for(int i = 0; i < n; ++i) {
        int x; cin >> x;
        cnt[x - 1]++;
    }

    cout << solve(0, n, cnt)[k] << endl;
}


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

constexpr double pi = std::acos(-1.0);

using data_type = std::complex<double>;

std::vector<data_type> fft(std::vector<data_type> v, bool inv = false) {
    int const n = v.size();
    double theta = 2 * pi / n * (inv ? -1 : 1);
    for(int m = n; m >= 2; m >>= 1) {
        int mh = m >> 1;
        data_type theta_i(0, theta);
        for(int i = 0; i < mh; ++i) {
            data_type w = std::exp((data_type)i * theta_i);
            for(int j = i; j < n; j += m) {
                data_type x = v[j] - v[j + mh]; // (a_k - a_{k + N/2})
                v[j] = v[j] + v[j + mh];   // (a_k + a_{k + N/2})
                v[j + mh] = w * x;         // (a_k - a_{k + N/2}) * W_N^j
            }
        }
        theta *= 2;
    }
    int i = 0;
    for(int j = 1; j < n - 1; ++j) {
        for(int k = n >> 1; k > (i ^= k); k >>= 1);
        if(j < i) {
            swap(v[i], v[j]);
        }
    }
    if(inv) {
        for(auto& x : v) x /= n;
    }
    return v;
}

std::vector<data_type> convolution(std::vector<data_type> x, std::vector<data_type> y) {
    int sz = 1;
    int t = x.size() + y.size() - 1;
    while(sz < t) {
        sz <<= 1;
    }
    x.resize(sz); y.resize(sz);
    x = fft(std::move(x)); y = fft(std::move(y));
    for(int i = 0; i < sz; ++i) {
        x[i] *= y[i];
    }
    x = fft(std::move(x), true);
    return x;
}

int n, m, k;

vector<int> solve(int l, int r, const vector<int>& cnt) {
    if(l + 1 == r) {
        return vector<int>(cnt[l] + 1, 1);
    }
    if(l >= r) {
        return vector<int>(1, 1);
    }

    auto v1 = solve(l, (l + r) / 2, cnt);
    auto v2 = solve((l + r) / 2, r, cnt);
    vector<data_type> w1(v1.size()), w2(v2.size());
    for(int i = 0; i < (int)v1.size(); ++i) {
        w1[i] = data_type(round(v1[i]), 0);
    }
    for(int i = 0; i < (int)v2.size(); ++i) {
        w2[i] = data_type(round(v2[i]), 0);
    }
    auto t = convolution(move(w1), move(w2));

    vector<int> res(min(k + 1, (int)t.size()));
    for(int i = 0; i < (int)res.size(); ++i) {
        res[i] = round(real(t[i]));
        res[i] %= 1009;
    }
    return res;
}

int main() {
    cin >> n >> m >> k;
    vector<int> cnt(m);
    for(int i = 0; i < n; ++i) {
        int x; cin >> x;
        cnt[x - 1]++;
    }
    vector<int> cnt2;
    for(int i = 0; i < m; ++i) {
        if(cnt[i] > 0) cnt2.push_back(cnt[i]);
    }
    sort(begin(cnt2), end(cnt2));

    cout << solve(0, n, cnt2)[k] << endl;
}