//#pragma GCC optimize("Ofast")
//#pragma GCC target("avx")
//#undef LOCAL

#include <cassert>
#include <numeric>
#include <type_traits>

#ifdef _MSC_VER
#include <intrin.h>
#endif

#include <utility>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

constexpr long long safe_mod(long long x, long long m) {
    x %= m;
    if (x < 0) x += m;
    return x;
}

struct barrett {
    unsigned int _m;
    unsigned long long im;

    barrett(unsigned int m) : _m(m), im((unsigned long long)(-1) / m + 1) {}

    unsigned int umod() const { return _m; }

    unsigned int mul(unsigned int a, unsigned int b) const {

        unsigned long long z = a;
        z *= b;
#ifdef _MSC_VER
        unsigned long long x;
        _umul128(z, im, &x);
#else
        unsigned long long x =
            (unsigned long long)(((unsigned __int128)(z)*im) >> 64);
#endif
        unsigned int v = (unsigned int)(z - x * _m);
        if (_m <= v) v += _m;
        return v;
    }
};

constexpr long long pow_mod_constexpr(long long x, long long n, int m) {
    if (m == 1) return 0;
    unsigned int _m = (unsigned int)(m);
    unsigned long long r = 1;
    unsigned long long y = safe_mod(x, m);
    while (n) {
        if (n & 1) r = (r * y) % _m;
        y = (y * y) % _m;
        n >>= 1;
    }
    return r;
}

constexpr bool is_prime_constexpr(int n) {
    if (n <= 1) return false;
    if (n == 2 || n == 7 || n == 61) return true;
    if (n % 2 == 0) return false;
    long long d = n - 1;
    while (d % 2 == 0) d /= 2;
    constexpr long long bases[3] = {2, 7, 61};
    for (long long a : bases) {
        long long t = d;
        long long y = pow_mod_constexpr(a, t, n);
        while (t != n - 1 && y != 1 && y != n - 1) {
            y = y * y % n;
            t <<= 1;
        }
        if (y != n - 1 && t % 2 == 0) {
            return false;
        }
    }
    return true;
}
template <int n> constexpr bool is_prime = is_prime_constexpr(n);

constexpr std::pair<long long, long long> inv_gcd(long long a, long long b) {
    a = safe_mod(a, b);
    if (a == 0) return {b, 0};

    long long s = b, t = a;
    long long m0 = 0, m1 = 1;

    while (t) {
        long long u = s / t;
        s -= t * u;
        m0 -= m1 * u;  // |m1 * u| <= |m1| * s <= b

        auto tmp = s;
        s = t;
        t = tmp;
        tmp = m0;
        m0 = m1;
        m1 = tmp;
    }
    if (m0 < 0) m0 += b / s;
    return {s, m0};
}

constexpr int primitive_root_constexpr(int m) {
    if (m == 2) return 1;
    if (m == 167772161) return 3;
    if (m == 469762049) return 3;
    if (m == 754974721) return 11;
    if (m == 998244353) return 3;
    int divs[20] = {};
    divs[0] = 2;
    int cnt = 1;
    int x = (m - 1) / 2;
    while (x % 2 == 0) x /= 2;
    for (int i = 3; (long long)(i)*i <= x; i += 2) {
        if (x % i == 0) {
            divs[cnt++] = i;
            while (x % i == 0) {
                x /= i;
            }
        }
    }
    if (x > 1) {
        divs[cnt++] = x;
    }
    for (int g = 2;; g++) {
        bool ok = true;
        for (int i = 0; i < cnt; i++) {
            if (pow_mod_constexpr(g, (m - 1) / divs[i], m) == 1) {
                ok = false;
                break;
            }
        }
        if (ok) return g;
    }
}
template <int m> constexpr int primitive_root = primitive_root_constexpr(m);

}  // namespace internal

}  // namespace atcoder

#include <cassert>
#include <numeric>
#include <type_traits>

namespace atcoder {

namespace internal {

#ifndef _MSC_VER
template <class T>
using is_signed_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value ||
                                  std::is_same<T, __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int128 =
    typename std::conditional<std::is_same<T, __uint128_t>::value ||
                                  std::is_same<T, unsigned __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using make_unsigned_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value,
                              __uint128_t,
                              unsigned __int128>;

template <class T>
using is_integral = typename std::conditional<std::is_integral<T>::value ||
                                                  is_signed_int128<T>::value ||
                                                  is_unsigned_int128<T>::value,
                                              std::true_type,
                                              std::false_type>::type;

template <class T>
using is_signed_int = typename std::conditional<(is_integral<T>::value &&
                                                 std::is_signed<T>::value) ||
                                                    is_signed_int128<T>::value,
                                                std::true_type,
                                                std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<(is_integral<T>::value &&
                               std::is_unsigned<T>::value) ||
                                  is_unsigned_int128<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<
    is_signed_int128<T>::value,
    make_unsigned_int128<T>,
    typename std::conditional<std::is_signed<T>::value,
                              std::make_unsigned<T>,
                              std::common_type<T>>::type>::type;

#else

template <class T> using is_integral = typename std::is_integral<T>;

template <class T>
using is_signed_int =
    typename std::conditional<is_integral<T>::value && std::is_signed<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<is_integral<T>::value &&
                                  std::is_unsigned<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<is_signed_int<T>::value,
                                              std::make_unsigned<T>,
                                              std::common_type<T>>::type;

#endif

template <class T>
using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;

template <class T>
using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;

template <class T> using to_unsigned_t = typename to_unsigned<T>::type;

}  // namespace internal

}  // namespace atcoder

namespace atcoder {

namespace internal {

struct modint_base {};
struct static_modint_base : modint_base {};

template <class T> using is_modint = std::is_base_of<modint_base, T>;
template <class T> using is_modint_t = std::enable_if_t<is_modint<T>::value>;

}  // namespace internal

template <int m, std::enable_if_t<(1 <= m)>* = nullptr>
struct static_modint : internal::static_modint_base {
    using mint = static_modint;

  public:
    static constexpr int mod() { return m; }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    static_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    static_modint(T v) {
        long long x = (long long)(v % (long long)(umod()));
        if (x < 0) x += umod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    static_modint(T v) {
        _v = (unsigned int)(v % umod());
    }
    static_modint(bool v) { _v = ((unsigned int)(v) % umod()); }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v -= rhs._v;
        if (_v >= umod()) _v += umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        unsigned long long z = _v;
        z *= rhs._v;
        _v = (unsigned int)(z % umod());
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        if (prime) {
            assert(_v);
            return pow(umod() - 2);
        } else {
            auto eg = internal::inv_gcd(_v, m);
            assert(eg.first == 1);
            return eg.second;
        }
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static constexpr unsigned int umod() { return m; }
    static constexpr bool prime = internal::is_prime<m>;
};

template <int id> struct dynamic_modint : internal::modint_base {
    using mint = dynamic_modint;

  public:
    static int mod() { return (int)(bt.umod()); }
    static void set_mod(int m) {
        assert(1 <= m);
        bt = internal::barrett(m);
    }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    dynamic_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        long long x = (long long)(v % (long long)(mod()));
        if (x < 0) x += mod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        _v = (unsigned int)(v % mod());
    }
    dynamic_modint(bool v) { _v = ((unsigned int)(v) % mod()); }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v += mod() - rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        _v = bt.mul(_v, rhs._v);
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        auto eg = internal::inv_gcd(_v, mod());
        assert(eg.first == 1);
        return eg.second;
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static internal::barrett bt;
    static unsigned int umod() { return bt.umod(); }
};
template <int id> internal::barrett dynamic_modint<id>::bt = 998244353;

using modint998244353 = static_modint<998244353>;
using modint1000000007 = static_modint<1000000007>;
using modint = dynamic_modint<-1>;

namespace internal {

template <class T>
using is_static_modint = std::is_base_of<internal::static_modint_base, T>;

template <class T>
using is_static_modint_t = std::enable_if_t<is_static_modint<T>::value>;

template <class> struct is_dynamic_modint : public std::false_type {};
template <int id>
struct is_dynamic_modint<dynamic_modint<id>> : public std::true_type {};

template <class T>
using is_dynamic_modint_t = std::enable_if_t<is_dynamic_modint<T>::value>;

}  // namespace internal

}  // namespace atcoder

#include <unistd.h>
#include <algorithm>
#include <array>
#include <cctype>
#include <cstring>
#include <string>
#include <type_traits>
#include <vector>

namespace yosupo {

namespace internal {

int ceil_pow2(int n) {
    int x = 0;
    while ((1U << x) < (unsigned int)(n)) x++;
    return x;
}

}  // namespace internal

int bsf(unsigned int n) { return __builtin_ctz(n); }
int bsf(unsigned long n) { return __builtin_ctzl(n); }
int bsf(unsigned long long n) { return __builtin_ctzll(n); }

int bsr(unsigned int n) {
    return 8 * (int)sizeof(unsigned int) - 1 - __builtin_clz(n);
}
int bsr(unsigned long n) {
    return 8 * (int)sizeof(unsigned long) - 1 - __builtin_clzl(n);
}
int bsr(unsigned long long n) {
    return 8 * (int)sizeof(unsigned long long) - 1 - __builtin_clzll(n);
}

}  // namespace yosupo

#include <cassert>
#include <numeric>
#include <type_traits>

namespace yosupo {

namespace internal {

template <class T>
using is_signed_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value ||
                                  std::is_same<T, __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int128 =
    typename std::conditional<std::is_same<T, __uint128_t>::value ||
                                  std::is_same<T, unsigned __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using make_unsigned_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value,
                              __uint128_t,
                              unsigned __int128>;

template <class T>
using is_integral =
    typename std::conditional<std::is_integral<T>::value ||
                                  internal::is_signed_int128<T>::value ||
                                  internal::is_unsigned_int128<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_signed_int = typename std::conditional<(is_integral<T>::value &&
                                                 std::is_signed<T>::value) ||
                                                    is_signed_int128<T>::value,
                                                std::true_type,
                                                std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<(is_integral<T>::value &&
                               std::is_unsigned<T>::value) ||
                                  is_unsigned_int128<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<
    is_signed_int128<T>::value,
    make_unsigned_int128<T>,
    typename std::conditional<std::is_signed<T>::value,
                              std::make_unsigned<T>,
                              std::common_type<T>>::type>::type;

template <class T>
using is_integral_t = std::enable_if_t<is_integral<T>::value>;

template <class T>
using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;

template <class T>
using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;

template <class T> using to_unsigned_t = typename to_unsigned<T>::type;

}  // namespace internal

}  // namespace yosupo

namespace yosupo {

struct Scanner {
  public:
    Scanner(FILE* fp) : fd(fileno(fp)) {}

    void read() {}
    template <class H, class... T> void read(H& h, T&... t) {
        bool f = read_single(h);
        assert(f);
        read(t...);
    }

    int read_unsafe() { return 0; }
    template <class H, class... T> int read_unsafe(H& h, T&... t) {
        bool f = read_single(h);
        if (!f) return 0;
        return 1 + read_unsafe(t...);
    }

  private:
    static constexpr size_t SIZE = 1 << 15;

    bool read_single(std::string& ref) {
        if (!skip_space()) return false;
        ref = "";
        while (true) {
            char c = top();
            if (c <= ' ') break;
            ref += c;
            st++;
        }
        return true;
    }
    bool read_single(double& ref) {
        std::string s;
        if (!read_single(s)) return false;
        ref = std::stod(s);
        return true;
    }

    template <class T, internal::is_signed_int_t<T>* = nullptr>
    bool read_single(T& sref) {
        using U = internal::to_unsigned_t<T>;
        if (!skip_space(50)) return false;
        bool neg = false;
        if (line[st] == '-') {
            neg = true;
            st++;
        }
        U ref = 0;
        do {
            ref = 10 * ref + (line[st++] & 0x0f);
        } while (line[st] >= '0');
        sref = neg ? -ref : ref;
        return true;
    }
    template <class U, internal::is_unsigned_int_t<U>* = nullptr>
    bool read_single(U& ref) {
        if (!skip_space(50)) return false;
        ref = 0;
        do {
            ref = 10 * ref + (line[st++] & 0x0f);
        } while (line[st] >= '0');
        return true;
    }

    int fd = -1;
    char line[SIZE];
    size_t st = 0, ed = 0;
    bool eof = false;
    bool reread() {
        if (ed - st >= 50) return true;
        if (st > SIZE / 2) {
            std::memmove(line, line + st, ed - st);
            ed -= st;
            st = 0;
        }
        if (eof) return false;
        auto u = ::read(fd, line + ed, SIZE - ed);
        if (u == 0) {
            eof = true;
            line[ed] = '\0';
            u = 1;
        }
        ed += u;
        return true;
    }

    char top() {
        if (st == ed) {
            bool f = reread();
            assert(f);
        }
        return line[st];
    }

    bool skip_space(int token_len = 0) {
        while (true) {
            while (st != ed && line[st] <= ' ') st++;
            if (ed - st > token_len) return true;
            for (int i = st; i < ed; i++) {
                if (line[i] <= ' ') return true;
            }
            if (!reread()) return false;
        }
    }
};

struct Printer {
  public:
    template <bool F = false> void write() {}
    template <bool F = false, class H, class... T>
    void write(const H& h, const T&... t) {
        if (F) write_single(' ');
        write_single(h);
        write<true>(t...);
    }
    template <class... T> void writeln(const T&... t) {
        write(t...);
        write_single('\n');
    }

    Printer(FILE* _fp) : fd(fileno(_fp)) {}
    ~Printer() { flush(); }

    void flush() {
        ::write(fd, line, pos);
        pos = 0;
    }

  private:
    static std::array<std::array<char, 2>, 100> small;
    static std::array<unsigned long long, 20> tens;

    static int calc_len(unsigned long long x) {
        int i = (bsr(x) * 3 + 3) / 10;
        if (x < tens[i])
            return i;
        else
            return i + 1;
    }

    static constexpr size_t SIZE = 1 << 15;
    int fd;
    char line[SIZE];
    size_t pos = 0;
    void write_single(const char& val) {
        if (pos == SIZE) flush();
        line[pos++] = val;
    }

    template <class T, internal::is_signed_int_t<T>* = nullptr>
    void write_single(const T& val) {
        using U = internal::to_unsigned_t<T>;
        if (val == 0) {
            write_single('0');
            return;
        }
        if (pos > SIZE - 50) flush();
        U uval = val;
        if (val < 0) {
            write_single('-');
            uval = -uval;
        }
        write_unsigned(uval);
    }

    template <class U, internal::is_unsigned_int_t<U>* = nullptr>
    void write_single(U uval) {
        if (uval == 0) {
            write_single('0');
            return;
        }
        if (pos > SIZE - 50) flush();

        write_unsigned(uval);
    }

    template <class U,
              internal::is_unsigned_int_t<U>* = nullptr,
              std::enable_if_t<sizeof(U) == 4>* = nullptr>
    void write_unsigned(U uval) {
        write_unsigned(uint64_t(uval));
    }

    template <class U,
              internal::is_unsigned_int_t<U>* = nullptr,
              std::enable_if_t<sizeof(U) == 8>* = nullptr>
    void write_unsigned(U uval) {
        size_t len = calc_len(uval);
        pos += len;

        char* ptr = line + pos;
        while (uval >= 100) {
            ptr -= 2;
            memcpy(ptr, small[uval % 100].data(), 2);
            uval /= 100;
        }
        if (uval >= 10) {
            memcpy(ptr - 2, small[uval].data(), 2);
        } else {
            *(ptr - 1) = char('0' + uval);
        }
    }

    void write_single(const std::string& s) {
        for (char c : s) write_single(c);
    }
    void write_single(const char* s) {
        size_t len = strlen(s);
        for (size_t i = 0; i < len; i++) write_single(s[i]);
    }
    template <class T> void write_single(const std::vector<T>& val) {
        auto n = val.size();
        for (size_t i = 0; i < n; i++) {
            if (i) write_single(' ');
            write_single(val[i]);
        }
    }
};

std::array<std::array<char, 2>, 100> Printer::small = [] {
    std::array<std::array<char, 2>, 100> table;
    for (int i = 0; i <= 99; i++) {
        table[i][1] = char('0' + (i % 10));
        table[i][0] = char('0' + (i / 10 % 10));
    }
    return table;
}();
std::array<unsigned long long, 20> Printer::tens = [] {
    std::array<unsigned long long, 20> table;
    for (int i = 0; i < 20; i++) {
        table[i] = 1;
        for (int j = 0; j < i; j++) {
            table[i] *= 10;
        }
    }
    return table;
}();

}  // namespace yosupo
using namespace yosupo;
using mint = atcoder::modint;

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n - 1); }
template <class T> using V = vector<T>;
template <class T> using VV = V<V<T>>;

#ifdef LOCAL

ostream& operator<<(ostream& os, __int128_t x) {
    if (x < 0) {
        os << "-";
        x *= -1;
    }
    if (x == 0) {
        return os << "0";
    }
    string s;
    while (x) {
        s += char(x % 10 + '0');
        x /= 10;
    }
    reverse(s.begin(), s.end());
    return os << s;
}
ostream& operator<<(ostream& os, __uint128_t x) {
    if (x == 0) {
        return os << "0";
    }
    string s;
    while (x) {
        s += char(x % 10 + '0');
        x /= 10;
    }
    reverse(s.begin(), s.end());
    return os << s;
}

template <class T, class U>
ostream& operator<<(ostream& os, const pair<T, U>& p);
template <class T> ostream& operator<<(ostream& os, const V<T>& v);
template <class T> ostream& operator<<(ostream& os, const deque<T>& v);
template <class T, size_t N>
ostream& operator<<(ostream& os, const array<T, N>& a);
template <class T> ostream& operator<<(ostream& os, const set<T>& s);
template <class T, class U>
ostream& operator<<(ostream& os, const map<T, U>& m);

template <class T, class U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
    return os << "P(" << p.first << ", " << p.second << ")";
}

template <class T> ostream& operator<<(ostream& os, const V<T>& v) {
    os << "[";
    bool f = false;
    for (auto d : v) {
        if (f) os << ", ";
        f = true;
        os << d;
    }
    return os << "]";
}

template <class T> ostream& operator<<(ostream& os, const deque<T>& v) {
    os << "[";
    bool f = false;
    for (auto d : v) {
        if (f) os << ", ";
        f = true;
        os << d;
    }
    return os << "]";
}
template <class T, size_t N>
ostream& operator<<(ostream& os, const array<T, N>& a) {
    os << "[";
    bool f = false;
    for (auto d : a) {
        if (f) os << ", ";
        f = true;
        os << d;
    }
    return os << "]";
}

template <class T> ostream& operator<<(ostream& os, const set<T>& s) {
    os << "{";
    bool f = false;
    for (auto d : s) {
        if (f) os << ", ";
        f = true;
        os << d;
    }
    return os << "}";
}

template <class T, class U>
ostream& operator<<(ostream& os, const map<T, U>& s) {
    os << "{";
    bool f = false;
    for (auto p : s) {
        if (f) os << ", ";
        f = true;
        os << p.first << ": " << p.second;
    }
    return os << "}";
}

struct PrettyOS {
    ostream& os;
    bool first;

    template <class T> auto operator<<(T&& x) {
        if (!first) os << ", ";
        first = false;
        os << x;
        return *this;
    }
};
template <class... T> void dbg0(T&&... t) {
    (PrettyOS{cerr, true} << ... << t);
}
#define dbg(...)                                            \
    do {                                                    \
        cerr << __LINE__ << " : " << #__VA_ARGS__ << " = "; \
        dbg0(__VA_ARGS__);                                  \
        cerr << endl;                                       \
    } while (false);
#else
#define dbg(...)
#endif

Scanner sc = Scanner(stdin);
Printer pr = Printer(stdout);

int main() {
    int n, m, mod;
    sc.read(n, m, mod);
    mint::set_mod(mod);

    VV<mint> C(n + 1, V<mint>(n + 1));
    C[0][0] = 1;
    for (int i = 1; i <= n; i++) {
        C[i][0] = 1;
        for (int j = 1; j <= n; j++) {
            C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
        }
    }

    V<mint> g(n + 1);
    for (int i = 0; i <= n; i++) {
        g[i] = i * (i + 1) / 2;
    }

    using P = pair<mint, mint>;
    V<P> f(n + 1); // (pattern, sum of maddness of all pattern)
    f[0] = {1, 0};

    for (int i = 1; i <= n; i++) {
        for (int j = 0; j < i; j++) {
            // j, (i - 1 - j)
            mint z = f[j].first * f[i - 1 - j].first * C[i - 1][j];
            f[i].first += z * mint(i + 1);
            f[i].second += z * (g[j] + g[i - 1 - j]);
            f[i].second += (f[i - 1 - j].first * f[j].second + f[j].first * f[i - 1 - j].second) * C[i - 1][j] * mint(i + 1);
        }
    }

    for (int i = 0; i <= n; i++) {
        dbg(i, f[i].first.val(), f[i].second.val(), g[i].val());
    }

    // 0  : empty
    // 1~n: ???
    // n+1: empty

    VV<P> dp(n + 2, V<P>(m + 1));
    dp[0][0] = {1, 0};
    for (int l = 0; l <= n; l++) {
        for (int r = l + 1; r <= n + 1; r++) {
            int di = r - l - 1;
            for (int i = 0; i + di <= m; i++) {
                // dp[l][i] -> dp[r][i + di]
                mint z = dp[l][i].first * f[di].first;
                dp[r][i + di].first += z * C[i + di][di];
                dp[r][i + di].second += (dp[l][i].second * f[di].first + dp[l][i].first * f[di].second) * C[i + di][di];
            }
        }
    }

    dbg(dp[n + 1][m].first.val(), dp[n + 1][m].second.val());

    pr.writeln(dp[n + 1][m].second.val());
    return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#define rep(i,l,r) for(int i=(l);i<=(r);++i)
#define per(i,r,l) for(int i=(r);i>=(l);--i)
using namespace std;
const int N=510;
int n,m,P,f[N],g[N],C[N][N],p[N][N],q[N][N];
inline void upd(int &x,int y){((x+=y)>=P)&&(x-=P);}
int main(){
	scanf("%d%d%d",&n,&m,&P);
	f[0]=1;
	rep(i,0,m){C[i][0]=1;rep(j,1,i) C[i][j]=(C[i-1][j]+C[i-1][j-1])%P;}
	rep(i,1,m) rep(j,1,i){
		upd(f[i],1ll*f[j-1]*f[i-j]%P*(i+1)%P*C[i-1][j-1]%P);
		upd(g[i],(1ll*f[j-1]*g[i-j]+1ll*f[i-j]*g[j-1])%P*(i+1)%P*C[i-1][j-1]%P);
		upd(g[i],1ll*(C[j][2]+C[i-j+1][2])*f[j-1]%P*f[i-j]%P*C[i-1][j-1]%P);
	}
	p[0][0]=1;
	rep(i,1,n){
		rep(j,0,min(i-1,m)) rep(k,0,j){
			upd(p[i][j],1ll*p[i-k-1][j-k]*f[k]%P*C[j][k]%P);
			upd(q[i][j],(1ll*p[i-k-1][j-k]*g[k]+1ll*q[i-k-1][j-k]*f[k])%P*C[j][k]%P);
		}
		if(i<=m) p[i][i]=f[i],q[i][i]=g[i];
	}
	printf("%d\n",q[n][m]);
	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=(b)-1;i>=(a);--i)
#define ll long long
#define lb(x) ((x)&-(x))
#define pii pair<int,int>
#define vi vector<int>
#define pb push_back
#define fi first
#define se second
#define de(x) cout<<#x<<" x"<<endl
#define LCAFA rep(i,1,20)rep(j,1,n+1)fa[j][i]=fa[fa[j][i-1]][i-1]
#define all(x) x.begin(),x.end()
#define ls(x) x<<1
#define rs(x) x<<1|1
#define pr(x) {for(auto v:x)cout<<v<<' ';cout<<#x<<endl;}
using namespace std;
const int N=500+9;
int mod=998244353;
inline int add(int a,const int &b){
	a+=b;
	if(a>=mod)a-=mod;
	return a;
}
inline int mul(const int &a,const int &b){
	return 1ll*a*b%mod;
}
int dp[N][N],dp2[N][N],C[N][N],f[N],g[N];
int main(){
	int n,m;
	scanf("%d%d%d",&n,&m,&mod);
	rep(i,0,n+1){
		C[i][0]=1;
		rep(j,0,i)C[i][j+1]=add(C[i-1][j+1],C[i-1][j]);
	}
	f[0]=1,g[0]=0;
	rep(i,1,m+1){
		rep(j,1,i+1){
			f[i]=add(f[i],mul(mul(C[i-1][j-1],i+1),mul(f[j-1],f[i-j])));
			g[i]=add(g[i],mul(mul(C[i-1][j-1],i+1),add(mul(f[j-1],g[i-j]),mul(g[j-1],f[i-j]))));
			g[i]=add(g[i],mul(mul(C[i-1][j-1],(j-1)*j/2+(i-j+1)*(i-j)/2),mul(f[j-1],f[i-j])));
		}
	}
	++n;
	dp[0][0]=1,dp2[0][0]=0;
	rep(i,0,n){
		rep(j,0,m+1){
			for(int k=0;j+k<=m&&i+k+1<=n;++k){
				dp[i+k+1][j+k]=add(dp[i+k+1][j+k],mul(mul(dp[i][j],f[k]),C[j+k][j]));
				dp2[i+k+1][j+k]=add(dp2[i+k+1][j+k],mul(C[j+k][j],add(mul(dp2[i][j],f[k]),mul(dp[i][j],g[k]))));
			}
		}
	}
	cout<<dp2[n][m];
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;

template<typename T> ostream& operator<<(ostream &os, const vector<T> &v) { os << '['; string sep = ""; for (const auto &x : v) os << sep << x, sep = ", "; return os << ']'; }
template<typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) { return os << '(' << p.first << ", " << p.second << ')'; }
template<typename A> ostream& operator<<(ostream &os, const set<A> &s) { os << '{'; string sep = ""; for (const auto &x : s) os << sep << x, sep = ", "; return os << '}'; }
template<typename A, typename B> ostream& operator<<(ostream &os, const map<A, B> &m) { os << '{'; string sep = ""; for (const auto &x : m) os << sep << x.first << " -> " << x.second, sep = ", "; return os << '}'; }

#ifdef MY_DEBUG_FLAG
void debug() { cerr << endl; }
template<typename Ini, typename... Fim> void debug(Ini I, Fim... F) { cerr << I; if(sizeof...(F)) cerr << ", "; debug(F...);}
#define db(...) cerr << "DEBUG (" << #__VA_ARGS__ << ") == ", debug(__VA_ARGS__)
#else
#define db(...)
#endif

#define pb push_back
#define eb emplace_back
#define ff first
#define ss second
#define fast ios_base::sync_with_stdio(false), cout.tie(nullptr), cin.tie(nullptr)
#define sz(a) ((int)(a).size())
#define rep(i,a,b) for(int i=(a); i<(b); i++)
#define dec(i,n,a) for(int i=(n); i>=(a); i--)
#define clr(a,v) memset(a, v, sizeof(a))
#define all(a) (a).begin(),(a).end()

constexpr int inf = 0x3f3f3f3f;
constexpr int maxn = 510;
int mod;

// m mod i = m - i*floor(m/i)
// m mod i === - i*floor(m/i) mod m
// i^-1 === m - floor(m/i)*(m mod i)^-1 mod m

int fat[maxn], inv[maxn], inv_fat[maxn];

void calc() {
	fat[0] = fat[1] = inv[1] = inv_fat[0] = inv_fat[1] = 1;
	for(int i = 2; i < maxn; i++) {
		fat[i] = (int)(1ll * fat[i-1] * i % mod);
		inv[i] = mod - (int)(1ll * (mod/i) * inv[mod%i] % mod);
		inv_fat[i] = (int)(1ll * inv_fat[i-1] * inv[i] % mod);
	}
}

inline int choose(int a, int b) {
	return (int)(1ll * fat[a] * (1ll * inv_fat[b] * inv_fat[a-b] % mod) % mod);
}

inline ll p(int x) { return 1ll * x * (x+1) / 2; }

int f[maxn], c[maxn], dp1[maxn][maxn], dp2[maxn][maxn];

int main() {
	int n, m; scanf("%d %d %d", &n, &m, &mod);
	calc();
	f[0] = 1;
	for(int i = 1; i <= m; i++) {
		for(int j = 0; j < i; j++) {
			f[i] += (int)((1ll * choose(i-1, j) * f[j] % mod) * f[i-1-j] % mod);
			if(f[i] >= mod) f[i] -= mod;
			c[i] += (int)((1ll * (i+1) * choose(i-1, j) % mod) *
				((1ll * f[j] * c[i-1-j] % mod) + (1ll * f[i-1-j] * c[j] % mod) % mod) % mod);
			if(c[i] >= mod) c[i] -= mod;
			c[i] += (int)((1ll * choose(i-1, j) * (p(j) + p(i-1-j)) % mod) *
				(1ll * f[j] * f[i-1-j] % mod) % mod);
			if(c[i] >= mod) c[i] -= mod;
		}
		f[i] = (int)(1ll * f[i] * (i+1) % mod);
	}
	dp1[0][0] = 1;
	for(int k = 1; k <= n; k++) {
		dp1[k][0] = 1;
		for(int i = 1; i <= min(m, k); i++) {
			dp1[k][i] = dp1[k-1][i];
			dp2[k][i] = dp2[k-1][i];
			for(int j = 1; j <= i; j++) {
				dp1[k][i] += (int)((1ll * f[j] * dp1[max(k-j-1, 0)][i-j] % mod) * choose(i, j) % mod);
				if(dp1[k][i] >= mod) dp1[k][i] -= mod;

				dp2[k][i] += (int)((1ll * c[j] * dp1[max(k-j-1, 0)][i-j] % mod) * choose(i, j) % mod);
				if(dp2[k][i] >= mod) dp2[k][i] -= mod;
				dp2[k][i] += (int)((1ll * f[j] * dp2[max(k-j-1, 0)][i-j] % mod) * choose(i, j) % mod);
				if(dp2[k][i] >= mod) dp2[k][i] -= mod;
			}
		}
	}
	printf("%d\n", dp2[n][m]);
}


#pragma GCC optimize(2)
#pragma GCC optimize(3)
#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--)
using namespace std;

typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef long long ll;

template <typename _T>
inline void read(_T &f) {
    f = 0; _T fu = 1; char c = getchar();
    while (c < '0' || c > '9') { if (c == '-') { fu = -1; } c = getchar(); }
    while (c >= '0' && c <= '9') { f = (f << 3) + (f << 1) + (c & 15); c = getchar(); }
    f *= fu;
}

template <typename T>
void print(T x) {
    if (x < 0) putchar('-'), x = -x;
    if (x < 10) putchar(x + 48);
    else print(x / 10), putchar(x % 10 + 48);
}

template <typename T>
void print(T x, char t) {
    print(x); putchar(t);
}

const int N = 505;

int n, m, md;

inline int add(int x, int y) {
    x += y;
    if (x >= md) x -= md;
    return x;
}

inline int sub(int x, int y) {
    x -= y;
    if (x < 0) x += md;
    return x;
}

inline int mul(int x, int y) { return 1ll * x * y % md; }

inline int fpow(int x, int y) {
    int ans = 1;
    while (y) {
        if (y & 1) ans = mul(ans, x);
        y >>= 1; x = mul(x, x);
    }
    return ans;
}

int fac[N], inv[N], f[N], g[N], dp[N][N][2], dp2[N][N][2];

inline int C(int n, int m) {
    return mul(fac[n], mul(inv[m], inv[n - m]));
}

int main() {
    read(n); read(m); read(md);
    fac[0] = 1;
    for (int i = 1; i <= n; i++) fac[i] = mul(fac[i - 1], i);
    inv[n] = fpow(fac[n], md - 2);
    for (int i = n; i >= 1; i--) inv[i - 1] = mul(inv[i], i);
    f[0] = 0; g[0] = 1;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= i; j++) {
            int now = mul(C(i - 1, j - 1), i + 1);
            g[i] = add(g[i], mul(mul(g[j - 1], g[i - j]), now));
            f[i] = add(f[i], mul(mul(f[j - 1], g[i - j]), now));
            f[i] = add(f[i], mul(mul(g[j - 1], f[i - j]), now));
            f[i] = add(f[i], mul(mul(C(i - 1, j - 1), mul(g[j - 1], g[i - j])), (j - 1) * j / 2 + (i - j) * (i - j + 1) / 2));
        }
        // fprintf(stderr, "f[%d] = %d, g[%d] = %d\n", i, f[i], i, g[i]);
    }
    dp[0][0][1] = 0; dp2[0][0][1] = 1;
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j <= i; j++) {
            dp[i][j][1] = add(dp[i - 1][j][0], dp[i - 1][j][1]);
            dp2[i][j][1] = add(dp2[i - 1][j][0], dp2[i - 1][j][1]);
            for (int k = 1; k <= j; k++) {
                dp[i][j][0] = add(dp[i][j][0], mul(C(j, k), mul(dp2[i - k][j - k][1], f[k])));
                dp[i][j][0] = add(dp[i][j][0], mul(C(j, k), mul(dp[i - k][j - k][1], g[k])));
                dp2[i][j][0] = add(dp2[i][j][0], mul(C(j, k), mul(dp2[i - k][j - k][1], g[k])));
            }
        }
    }
    print(add(dp[n][m][0], dp[n][m][1]), '\n');
    return 0;
}


// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <chrono>
#include <random>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <iomanip>
#define dibs reserve
#define OVER9000 1234567890
#define tisic 47
#define soclose 1e-8
#define patkan 9
#define ff first
#define ss second
using uint = unsigned int;
using cat = long long;
using dbl = long double;
constexpr dbl pi = 3.14159265358979323846;
using namespace std;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

template <typename T>
T abs(T x) { return (x < 0) ? (-x) : x; }

cat pw(cat a, cat e, cat mod) {
	if(e <= 0) return 1;
	cat x = pw(a, e/2, mod);
	x = x * x % mod;
	return (e&1) ? x * a % mod : x;
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cout << fixed << setprecision(10);
	int N, M;
	cat mod;
	cin >> N >> M >> mod;
	vector<cat> fac(N+1, 1), inv(N+1, 1);
	for(int i = 1; i <= N; i++) {
		fac[i] = fac[i-1] * i % mod;
		inv[i] = inv[i-1] * pw(i, mod-2, mod) % mod;
	}
	vector<cat> cnt(M+1, 0);
	vector<cat> sum(M+1, 0);
	cnt[0] = 1;
	for(int m = 1; m <= M; m++) {
		for(int k = 0; k < m; k++) {
			cat cl = cnt[k] * inv[k] % mod, cr = cnt[m-1-k] * inv[m-1-k] % mod;
			cat sl = sum[k] * inv[k] % mod, sr = sum[m-1-k] * inv[m-1-k] % mod;
			cnt[m] += cl * cr % mod * (m+1);
			sum[m] += (cl * sr + sl * cr) % mod * (m+1);
			sum[m] += cl * cr % mod * (k*(k+1)+(m-k)*(m-k-1))/2 % mod;
		}
		cnt[m] = cnt[m] % mod * fac[m-1] % mod;
		sum[m] = sum[m] % mod * fac[m-1] % mod;
	}
	vector< vector<cat> > cnt_ans(N+1, vector<cat>(M+1, 0));
	vector< vector<cat> > sum_ans(N+1, vector<cat>(M+1, 0));
	cnt_ans[0][0] = 1;
	for(int i = 1; i <= N; i++) for(int j = 0; j <= min(i, M); j++) {
		cnt_ans[i][j] = cnt_ans[i-1][j];
		sum_ans[i][j] = sum_ans[i-1][j];
		if(j == i) {
			cnt_ans[i][j] += cnt[i] * inv[i] % mod;
			sum_ans[i][j] += sum[i] * inv[i] % mod;
		}
		for(int k = 1; k <= min(j, i-1); k++) {
			cat c = cnt[k] * inv[k] % mod;
			cat s = sum[k] * inv[k] % mod;
			cnt_ans[i][j] += cnt_ans[i-1-k][j-k] * c % mod;
			sum_ans[i][j] += (sum_ans[i-1-k][j-k] * c + cnt_ans[i-1-k][j-k] * s) % mod;
		}
		cnt_ans[i][j] %= mod;
		sum_ans[i][j] %= mod;
	}
	cat ans = sum_ans[N][M] * fac[M] % mod;
	cout << ans << "\n";
}

// look at my code
// my code is amazing


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;

template<typename T> ostream& operator<<(ostream &os, const vector<T> &v) { os << '['; string sep = ""; for (const auto &x : v) os << sep << x, sep = ", "; return os << ']'; }
template<typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) { return os << '(' << p.first << ", " << p.second << ')'; }
template<typename A> ostream& operator<<(ostream &os, const set<A> &s) { os << '{'; string sep = ""; for (const auto &x : s) os << sep << x, sep = ", "; return os << '}'; }
template<typename A, typename B> ostream& operator<<(ostream &os, const map<A, B> &m) { os << '{'; string sep = ""; for (const auto &x : m) os << sep << x.first << " -> " << x.second, sep = ", "; return os << '}'; }

#ifdef MY_DEBUG_FLAG
void debug() { cerr << endl; }
template<typename Ini, typename... Fim> void debug(Ini I, Fim... F) { cerr << I; if(sizeof...(F)) cerr << ", "; debug(F...);}
#define db(...) cerr << "DEBUG (" << #__VA_ARGS__ << ") == ", debug(__VA_ARGS__)
#else
#define db(...)
#endif

#define pb push_back
#define eb emplace_back
#define ff first
#define ss second
#define fast ios_base::sync_with_stdio(false), cout.tie(nullptr), cin.tie(nullptr)
#define sz(a) ((int)(a).size())
#define rep(i,a,b) for(int i=(a); i<(b); i++)
#define dec(i,n,a) for(int i=(n); i>=(a); i--)
#define clr(a,v) memset(a, v, sizeof(a))
#define all(a) (a).begin(),(a).end()

constexpr int inf = 0x3f3f3f3f;
constexpr int maxn = 510;
int mod;

// m mod i = m - i*floor(m/i)
// m mod i === - i*floor(m/i) mod m
// i^-1 === m - floor(m/i)*(m mod i)^-1 mod m

int fat[maxn], inv[maxn], inv_fat[maxn];

void calc() {
	fat[0] = fat[1] = inv[1] = inv_fat[0] = inv_fat[1] = 1;
	for(int i = 2; i < maxn; i++) {
		fat[i] = (int)(1ll * fat[i-1] * i % mod);
		inv[i] = mod - (int)(1ll * (mod/i) * inv[mod%i] % mod);
		inv_fat[i] = (int)(1ll * inv_fat[i-1] * inv[i] % mod);
	}
}

inline int choose(int a, int b) {
	return (int)(1ll * fat[a] * (1ll * inv_fat[b] * inv_fat[a-b] % mod) % mod);
}

inline ll p(int x) { return 1ll * x * (x+1) / 2; }

int f[maxn], c[maxn], dp1[maxn][maxn], dp2[maxn][maxn];

int main() {
	int n, m; scanf("%d %d %d", &n, &m, &mod);
	calc();
	f[0] = 1;
	for(int i = 1; i <= m; i++) {
		for(int j = 0; j < i; j++) {
			f[i] += (int)((1ll * choose(i-1, j) * f[j] % mod) * f[i-1-j] % mod);
			if(f[i] >= mod) f[i] -= mod;
			c[i] += (int)((1ll * (i+1) * choose(i-1, j) % mod) *
				((1ll * f[j] * c[i-1-j] % mod) + (1ll * f[i-1-j] * c[j] % mod) % mod) % mod);
			if(c[i] >= mod) c[i] -= mod;
			c[i] += (int)((1ll * choose(i-1, j) * (p(j) + p(i-1-j)) % mod) *
				(1ll * f[j] * f[i-1-j] % mod) % mod);
			if(c[i] >= mod) c[i] -= mod;
		}
		f[i] = (int)(1ll * f[i] * (i+1) % mod);
	}
	dp1[0][0] = 1;
	for(int k = 1; k <= n; k++) {
		dp1[k][0] = 1;
		for(int i = 1; i <= min(m, k); i++) {
			dp1[k][i] = dp1[k-1][i];
			for(int j = 1; j <= i; j++) {
				dp1[k][i] += (int)((1ll * f[j] * dp1[max(k-j-1, 0)][i-j] % mod) * choose(i, j) % mod);
				if(dp1[k][i] >= mod) dp1[k][i] -= mod;
			}

			dp2[k][i] = dp2[k-1][i];
			for(int j = 1; j <= i; j++) {
				dp2[k][i] += (int)((1ll * c[j] * dp1[max(k-j-1, 0)][i-j] % mod) * choose(i, j) % mod);
				if(dp2[k][i] >= mod) dp2[k][i] -= mod;
				dp2[k][i] += (int)((1ll * f[j] * dp2[max(k-j-1, 0)][i-j] % mod) * choose(i, j) % mod);
				if(dp2[k][i] >= mod) dp2[k][i] -= mod;
			}
		}
	}
	printf("%d\n", dp2[n][m]);
}


//#define DEBUG
//#define USEPB_DS
#define USETR1
#define CPPELEVEN
#define GPP

/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#if __cplusplus < 201500L
#include <bits/stdc++.h>
#else
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <list>
#include <iomanip>
#include <cmath>
#include <deque>
#include <utility>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <sstream>
#include <tuple>
#endif

using namespace std;

#ifndef CPPELEVEN
#ifdef USETR1
#include <tr1/unordered_map>
#include <tr1/unordered_set>
using namespace tr1;
#endif
#else
#include <unordered_map>
#include <unordered_set>
#endif

#ifdef USEPB_DS
#include <ext/pb_ds/priority_queue.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
// binomial_heap_tag, rc_binomial_heap_tag, thin_heap_tag, binary_heap_tag
typedef __gnu_pbds::priority_queue<int, greater<int>, pairing_heap_tag> pq_type;
// splay_tree_tag, ov_tree_tag
typedef tree <int, null_type, less <int>, rb_tree_tag, tree_order_statistics_node_update> tree_type;
#endif

#define mpr make_pair
typedef unsigned int ui;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<double> vd;
typedef vector<string> vs;
typedef map<string, int> mpsi;
typedef map<double, int> mpdi;
typedef map<int, int> mpii;

const double pi = acos(0.0) * 2.0;
const long double eps = 1e-10;
const int step[8][2] = { { -1, 0 }, { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 1 }, {
		1, 1 }, { 1, -1 }, { -1, -1 } };

template<class T> inline T abs1(T a) {
	return a < 0 ? -a : a;
}

#ifndef CPPELEVEN
template <class T> inline T max1(T a, T b) { return b < a ? a : b; }
template <class T> inline T max1(T a, T b, T c) { return max1(max1(a, b), c); }
template <class T> inline T max1(T a, T b, T c, T d) { return max1(max1(a, b, c), d); }
template <class T> inline T max1(T a, T b, T c, T d, T e) { return max1(max1(a, b, c, d), e); }
template <class T> inline T min1(T a, T b) { return a < b ? a : b; }
template <class T> inline T min1(T a, T b, T c) { return min1(min1(a, b), c); }
template <class T> inline T min1(T a, T b, T c, T d) { return min1(min1(a, b, c), d); }
template <class T> inline T min1(T a, T b, T c, T d, T e) { return min1(min1(a, b, c, d), e); }
#else
template<typename t, typename t1>
t min1(t a, t1 b) {
	return a < b ? a : b;
}
template<typename t, typename ... arg>
t min1(t a, arg ... arr) {
	return min1(a, min1(arr...));
}
template<typename t, typename t1>
t max1(t a, t1 b) {
	return a > b ? a : b;
}
template<typename t, typename ... arg>
t max1(t a, arg ... arr) {
	return max1(a, max1(arr...));
}
#endif

inline int jud(double a, double b) {
	if (abs(a) < eps && abs(b) < eps)
		return 0;
	else if (abs1(a - b) / max(abs1(a), abs1(b)) < eps) return 0;
	if (a < b) return -1;
	return 1;
}
template<typename t> inline int jud(t a, t b) {
	if (a < b) return -1;
	if (a == b) return 0;
	return 1;
}

// f_lb == 1代表返回相同的一串的左边界，f_small == 1代表返回如果没有寻找的值返回小的数
template<typename it, typename t1>
inline int RangeFind(t1 val, it a, int na, bool f_small = 1, bool f_lb = 1) {
	if (na == 0) return 0;
	int be = 0, en = na - 1;
	if (*a <= *(a + na - 1)) {
		if (f_lb == 0)
			while (be < en) {
				int mid = (be + en + 1) / 2;
				if (jud(*(a + mid), val) != 1)
					be = mid;
				else
					en = mid - 1;
			}
		else
			while (be < en) {
				int mid = (be + en) / 2;
				if (jud(*(a + mid), val) != -1)
					en = mid;
				else
					be = mid + 1;
			}
		if (f_small && jud(*(a + be), val) == 1) be--;
		if (!f_small && jud(*(a + be), val) == -1) be++;
	} else {
		if (f_lb)
			while (be < en) {
				int mid = (be + en + 1) / 2;
				if (jud(*(a + mid), val) != -1)
					be = mid;
				else
					en = mid - 1;
			}
		else
			while (be < en) {
				int mid = (be + en) / 2;
				if (jud(*(a + mid), val) != 1)
					en = mid;
				else
					be = mid + 1;
			}
		if (!f_small && jud(*(a + be), val) == -1) be--;
		if (f_small && jud(*(a + be), val) == 1) be++;
	}
	return be;
}

template<class T> inline T lowb(T num) {
	return num & (-num);
}
#ifdef GPP
inline int bitnum(ui nValue) {
	return __builtin_popcount(nValue);
}
inline int bitnum(int nValue) {
	return __builtin_popcount(nValue);
}
inline int bitnum(ull nValue) {
	return __builtin_popcountll(nValue);
}
inline int bitnum(ll nValue) {
	return __builtin_popcountll(nValue);
}
inline int bitmaxl(ui a) {
	if (a == 0) return 0;
	return 32 - __builtin_clz(a);
}
inline int bitmaxl(int a) {
	if (a == 0) return 0;
	return 32 - __builtin_clz(a);
}
inline int bitmaxl(ull a) {
	if (a == 0) return 0;
	return 64 - __builtin_clzll(a);
}
inline int bitmaxl(ll a) {
	if (a == 0) return 0;
	return 64 - __builtin_clzll(a);
}
#else
#endif

long long pow(long long n, long long m, long long mod = 0) {
	if (m < 0) return 0;
	long long ans = 1;
	long long k = n;
	while (m) {
		if (m & 1) {
			ans *= k;
			if (mod) ans %= mod;
		}
		k *= k;
		if (mod) k %= mod;
		m >>= 1;
	}
	return ans;
}

#define  MOD 1000000007
template<class t1, class t2>
inline void add(t1 &a, t2 b, int mod = -1) {
	if (mod == -1) mod = MOD;
	a += b;
	while (a >= mod)
		a -= mod;
	while (a < 0)
		a += mod;
}
template<class t>
void output1(t arr) {
	for (int i = 0; i < (int) arr.size(); i++)
		cerr << arr[i] << ' ';
	cerr << endl;
}
template<class t>
void output2(t arr) {
	for (int i = 0; i < (int) arr.size(); i++)
		output1(arr[i]);
}

//....................密..........封..........线..........下..........禁..........止..........hack...............................................

const int maxn = 510;
ll dp_con[maxn], sum_con[maxn], dp[maxn][maxn], sum[maxn][maxn];
int c[maxn][maxn];
int n, m, mod;

inline ll Arth(ll n) {
	return n * (n + 1) / 2 % mod;
}

int main() {

//............................不要再忘了检查maxn大小了！！！！BSBandme你个SB！！！！...................................................

	ios_base::sync_with_stdio(0);
#ifdef DEBUG //......................................................................................................
	freopen("input.txt", "r", stdin);
#endif //...........................................................................................................

	scanf("%d%d%d", &n, &m, &mod);
	for (int i = 0; i < maxn; i++) {
		c[i][0] = 1;
		for (int j = 1; j <= i; j++) {
			c[i][j] = c[i - 1][j] + c[i - 1][j - 1];
			c[i][j] %= mod;
		}
	}

	dp_con[1] = 2;
	dp_con[0] = 1;
	sum_con[1] = sum_con[0] = 0;
	for (int i = 2; i <= m; i++) {
		dp_con[i] = 0;
		sum_con[i] = 0;
		for (int j = 0; j < i; j++) {
			ll rcon = dp_con[j] * dp_con[i - j - 1] % mod * c[i - 1][j] % mod;
			dp_con[i] += rcon * (i + 1) % mod;
			sum_con[i] += (dp_con[j] * sum_con[i - j - 1] + sum_con[j] * dp_con[i - j - 1]) % mod * c[i - 1][j] % mod * (i + 1) % mod;
			sum_con[i] += rcon * (Arth(j) + Arth(i - 1 - j)) % mod;
		}
		dp_con[i] %= mod;
		sum_con[i] %= mod;
	}

	dp[0][0] = 1;
	for (int i = 0; i < m; i++) for (int j = 0; j <= i; j++) if (dp[i][j]) {
		for (int k = 1; k + i <= m; k++) {
			dp[i + k][j + 1] += dp[i][j] * dp_con[k] % mod * c[i + k][k];
			dp[i + k][j + 1] %= mod;
			sum[i + k][j + 1] += (dp[i][j] * sum_con[k] + sum[i][j] * dp_con[k]) % mod * c[i + k][k];
			sum[i + k][j + 1] %= mod;
		}
	}

	ll ans = 0;
	for (int j = 1; j <= m; j++) {
		if (n - (m - 1 + j) < 0) break;
		ans += sum[m][j] * c[n - (m - 1 + j) + j][j] % mod;
		ans %= mod;
	}

	printf("%I64d\n", ans);

	return 0;
}


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

using ll=long long;
#define int ll

#define rng(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,b) rng(i,0,b)
#define gnr(i,a,b) for(int i=int(b)-1;i>=int(a);i--)
#define per(i,b) gnr(i,0,b)
#define pb push_back
#define eb emplace_back
#define a first
#define b second
#define bg begin()
#define ed end()
#define all(x) x.bg,x.ed
#define si(x) int(x.size())
#ifdef LOCAL
#define dmp(x) cerr<<__LINE__<<" "<<#x<<" "<<x<<endl
#else
#define dmp(x) void(0)
#endif

template<class t,class u> void chmax(t&a,u b){if(a<b)a=b;}
template<class t,class u> void chmin(t&a,u b){if(b<a)a=b;}

template<class t> using vc=vector<t>;
template<class t> using vvc=vc<vc<t>>;

using pi=pair<int,int>;
using vi=vc<int>;

template<class t,class u>
ostream& operator<<(ostream& os,const pair<t,u>& p){
	return os<<"{"<<p.a<<","<<p.b<<"}";
}

template<class t> ostream& operator<<(ostream& os,const vc<t>& v){
	os<<"{";
	for(auto e:v)os<<e<<",";
	return os<<"}";
}

#define mp make_pair
#define mt make_tuple
#define one(x) memset(x,-1,sizeof(x))
#define zero(x) memset(x,0,sizeof(x))
#ifdef LOCAL
void dmpr(ostream&os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
	os<<t<<" ";
	dmpr(os,args...);
}
#define dmp2(...) dmpr(cerr,__LINE__,##__VA_ARGS__)
#else
#define dmp2(...) void(0)
#endif

using uint=unsigned;
using ull=unsigned long long;

template<class t,size_t n>
ostream& operator<<(ostream&os,const array<t,n>&a){
	return os<<vc<t>(all(a));
}

template<int i,class T>
void print_tuple(ostream&,const T&){
}

template<int i,class T,class H,class ...Args>
void print_tuple(ostream&os,const T&t){
	if(i)os<<",";
	os<<get<i>(t);
	print_tuple<i+1,T,Args...>(os,t);
}

template<class ...Args>
ostream& operator<<(ostream&os,const tuple<Args...>&t){
	os<<"{";
	print_tuple<0,tuple<Args...>,Args...>(os,t);
	return os<<"}";
}

template<class t>
void print(t x,int suc=1){
	cout<<x;
	if(suc==1)
		cout<<"\n";
	if(suc==2)
		cout<<" ";
}

ll read(){
	ll i;
	cin>>i;
	return i;
}

vi readvi(int n,int off=0){
	vi v(n);
	rep(i,n)v[i]=read()+off;
	return v;
}

pi readpi(int off=0){
	int a,b;cin>>a>>b;
	return pi(a+off,b+off);
}

template<class T>
void print(const vector<T>&v,int suc=1){
	rep(i,v.size())
		print(v[i],i==int(v.size())-1?suc:2);
}

string readString(){
	string s;
	cin>>s;
	return s;
}

template<class T>
T sq(const T& t){
	return t*t;
}

//#define CAPITAL
void yes(bool ex=true){
	#ifdef CAPITAL
	cout<<"YES"<<"\n";
	#else
	cout<<"Yes"<<"\n";
	#endif
	if(ex)exit(0);
	#ifdef LOCAL
	cout.flush();
	#endif
}
void no(bool ex=true){
	#ifdef CAPITAL
	cout<<"NO"<<"\n";
	#else
	cout<<"No"<<"\n";
	#endif
	if(ex)exit(0);
	#ifdef LOCAL
	cout.flush();
	#endif
}
void possible(bool ex=true){
	#ifdef CAPITAL
	cout<<"POSSIBLE"<<"\n";
	#else
	cout<<"Possible"<<"\n";
	#endif
	if(ex)exit(0);
	#ifdef LOCAL
	cout.flush();
	#endif
}
void impossible(bool ex=true){
	#ifdef CAPITAL
	cout<<"IMPOSSIBLE"<<"\n";
	#else
	cout<<"Impossible"<<"\n";
	#endif
	if(ex)exit(0);
	#ifdef LOCAL
	cout.flush();
	#endif
}

constexpr ll ten(int n){
	return n==0?1:ten(n-1)*10;
}

const ll infLL=LLONG_MAX/3;

#ifdef int
const int inf=infLL;
#else
const int inf=INT_MAX/2-100;
#endif

int topbit(signed t){
	return t==0?-1:31-__builtin_clz(t);
}
int topbit(ll t){
	return t==0?-1:63-__builtin_clzll(t);
}
int botbit(signed a){
	return a==0?32:__builtin_ctz(a);
}
int botbit(ll a){
	return a==0?64:__builtin_ctzll(a);
}
int popcount(signed t){
	return __builtin_popcount(t);
}
int popcount(ll t){
	return __builtin_popcountll(t);
}
bool ispow2(int i){
	return i&&(i&-i)==i;
}
ll mask(int i){
	return (ll(1)<<i)-1;
}

bool inc(int a,int b,int c){
	return a<=b&&b<=c;
}

template<class t> void mkuni(vc<t>&v){
	sort(all(v));
	v.erase(unique(all(v)),v.ed);
}

ll rand_int(ll l, ll r) { //[l, r]
	#ifdef LOCAL
	static mt19937_64 gen;
	#else
	static mt19937_64 gen(chrono::steady_clock::now().time_since_epoch().count());
	#endif
	return uniform_int_distribution<ll>(l, r)(gen);
}

template<class t>
void myshuffle(vc<t>&a){
	rep(i,si(a))swap(a[i],a[rand_int(0,i)]);
}

template<class t>
int lwb(const vc<t>&v,const t&a){
	return lower_bound(all(v),a)-v.bg;
}

vvc<int> readGraph(int n,int m){
	vvc<int> g(n);
	rep(i,m){
		int a,b;
		cin>>a>>b;
		//sc.read(a,b);
		a--;b--;
		g[a].pb(b);
		g[b].pb(a);
	}
	return g;
}

vvc<int> readTree(int n){
	return readGraph(n,n-1);
}

struct modinfo{uint mod,root;};
template<modinfo const&ref>
struct modular{
	static constexpr uint const &mod=ref.mod;
	static modular root(){return modular(ref.root);}
	uint v;
	//modular(initializer_list<uint>ls):v(*ls.bg){}
	modular(ll vv=0){s(vv%mod+mod);}
	modular& s(uint vv){
		v=vv<mod?vv:vv-mod;
		return *this;
	}
	modular operator-()const{return modular()-*this;}
	modular& operator+=(const modular&rhs){return s(v+rhs.v);}
	modular&operator-=(const modular&rhs){return s(v+mod-rhs.v);}
	modular&operator*=(const modular&rhs){
		v=ull(v)*rhs.v%mod;
		return *this;
	}
	modular&operator/=(const modular&rhs){return *this*=rhs.inv();}
	modular operator+(const modular&rhs)const{return modular(*this)+=rhs;}
	modular operator-(const modular&rhs)const{return modular(*this)-=rhs;}
	modular operator*(const modular&rhs)const{return modular(*this)*=rhs;}
	modular operator/(const modular&rhs)const{return modular(*this)/=rhs;}
	modular pow(int n)const{
		modular res(1),x(*this);
		while(n){
			if(n&1)res*=x;
			x*=x;
			n>>=1;
		}
		return res;
	}
	modular inv()const{return pow(mod-2);}
	/*modular inv()const{
		int x,y;
		int g=extgcd<ll>(v,mod,x,y);
		assert(g==1);
		if(x<0)x+=mod;
		return modular(x);
	}*/
	friend modular operator+(int x,const modular&y){
		return modular(x)+y;
	}
	friend modular operator-(int x,const modular&y){
		return modular(x)-y;
	}
	friend modular operator*(int x,const modular&y){
		return modular(x)*y;
	}
	friend modular operator/(int x,const modular&y){
		return modular(x)/y;
	}
	friend ostream& operator<<(ostream&os,const modular&m){
		return os<<m.v;
	}
	friend istream& operator>>(istream&is,modular&m){
		ll x;is>>x;
		m=modular(x);
		return is;
	}
	bool operator<(const modular&r)const{return v<r.v;}
	bool operator==(const modular&r)const{return v==r.v;}
	bool operator!=(const modular&r)const{return v!=r.v;}
	explicit operator bool()const{
		return v;
	}
};

//extern constexpr modinfo base{998244353,3};
//extern constexpr modinfo base{1000000007,0};
modinfo base{1,0};
using mint=modular<base>;

const int vmax=10010;
mint fact[vmax],finv[vmax],invs[vmax];
void initfact(){
	fact[0]=1;
	rng(i,1,vmax){
		fact[i]=fact[i-1]*i;
	}
	finv[vmax-1]=fact[vmax-1].inv();
	for(int i=vmax-2;i>=0;i--){
		finv[i]=finv[i+1]*(i+1);
	}
	for(int i=vmax-1;i>=1;i--){
		invs[i]=finv[i]*fact[i-1];
	}
}
mint choose(int n,int k){
	return fact[n]*finv[n-k]*finv[k];
}
mint binom(int a,int b){
	return fact[a+b]*finv[a]*finv[b];
}
mint catalan(int n){
	return binom(n,n)-(n-1>=0?binom(n-1,n+1):0);
}

/*
const int vmax=110;
mint binbuf[vmax][vmax];
mint choose(int n,int k){
	return binbuf[n-k][k];
}
mint binom(int a,int b){
	return binbuf[a][b];
}
void initfact(){
	binbuf[0][0]=1;
	rep(i,vmax)rep(j,vmax){
		if(i)binbuf[i][j]+=binbuf[i-1][j];
		if(j)binbuf[i][j]+=binbuf[i][j-1];
	}
}
*/

void slv(){
	int n,m;cin>>n>>m>>base.mod;
	initfact();

	mint ans;
	rng(len,1,m){
		mint f=mint(len+1).pow(len)*len/(n-len)*finv[len];
		rep(i,m-len){
			int j=i+len;
			mint g=mint(n-len).pow(i)*finv[i];
			mint h=(n-j)*mint(n+1).pow(m-1-j)*fact[j];
			ans+=f*g*h;
		}
	}
	ans*=mint(2).pow(m-1)*(n+1-m);
	print(ans);
}

signed main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	cout<<fixed<<setprecision(20);

	//int t;cin>>t;rep(_,t)
	slv();
}


#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
const int N=507;
int n,m,p,fac[N],ifac[N],f[N][N],g[N][N],ans[N][N],sum[N][N],C[N][N];
inline int pows(long long u,int v){
	long long ans=1;
	while(v>0){
		if(v&1) ans=ans*u%p; u=u*u%p,v=v>>1;
	}
	return ans;
}
inline long long binomx(int a,int b){
//	if(a>b) return 0;
//	return C[a][b];
	return 1ll*fac[a]*ifac[b]%p*ifac[a-b]%p;
}
inline long long binom(int a,int b){
	return C[a][b];
}
inline long long getsum(int u){
	return 1ll*u*(u+1)/2;
}
signed main(){
	cin>>n>>m>>p,fac[0]=ifac[0]=1;
	for(int i=1;i<=500;i++) fac[i]=1ll*fac[i-1]*i%p,ifac[i]=pows(fac[i],p-2);
	for(int i=0;i<=500;i++)
		for(int j=0;j<=500;j++) C[i][j]=binomx(i,j);
	for(int len=1;len<=n;len++)
		for(int l=1;l<=n;l++){
			int r=l+len-1; if(r>n) continue;
//			if(r-l+1!=len) continue;
			if(l==r){
				f[l][r]=0,g[l][r]=2;
			}
			else{
				g[l][r]=(g[l][r]+1ll*(g[l+1][r]+g[l][r-1])*(r-l+2))%p;
				f[l][r]=(f[l][r]+1ll*(g[l+1][r]+g[l][r-1])*getsum(r-l))%p;
				f[l][r]=(f[l][r]+1ll*(f[l+1][r]+f[l][r-1])*(r-l+2))%p; int S=0,T=0;
				for(int x=l+1;x<=r-1;x++){
					int A=1ll*(r-l+2)*binom(r-l,x-l)%p;
					S=(S+(1ll*f[l][x-1]*g[x+1][r]+1ll*f[x+1][r]*g[l][x-1])%p*A+(getsum(x-l)+getsum(r-x))*g[x+1][r]%p*g[l][x-1]%p*binom(r-l,x-l))%p;
					T=(T+1ll*g[x+1][r]*g[l][x-1]%p*A)%p;
				}
				f[l][r]=(f[l][r]+S)%p;
				g[l][r]=(g[l][r]+T)%p;
			}
		}
	ans[0][0]=0,sum[0][0]=1;
	for(int i=1;i<=n;i++){
		for(int j=i;j<=n;j++)
			for(int k=0;k<=i;k++){
				int t=k+j-i+1; if(t>m) break;
				ans[j+1][t]=(ans[j+1][t]+1ll*ans[i-1][k]*g[i][j]%p*binom(t,j-i+1))%p;
				ans[j+1][t]=(ans[j+1][t]+1ll*f[i][j]*sum[i-1][k]%p*binom(t,j-i+1))%p;
				sum[j+1][t]=(sum[j+1][t]+1ll*g[i][j]*sum[i-1][k]%p*binom(t,j-i+1))%p;
			}
		for(int j=0;j<=i;j++){
			ans[i][j]=(ans[i][j]+ans[i-1][j])%p;
			sum[i][j]=(sum[i][j]+sum[i-1][j])%p;
		}
	}
	cout<<(ans[n+1][m]+ans[n][m])%p<<endl;
}
//500 500 998244353


#include<bits/stdc++.h>
using namespace std;
const int N=510;
typedef pair<int,int> pii;
#define mp make_pair
#define fi first
#define se second

int n,m,mod,C[N][N];
pii dp[N][N];

int add(int a,int b) {
	return a+b>=mod?a+b-mod:a+b;
}

pii operator+(const pii &a,const pii &b) {
	return mp(add(a.fi,b.fi),add(a.se,b.se));
}

pii operator*(const pii &a,const pii &b) {
	return mp(1ll*a.fi*b.fi%mod,(1ll*a.fi*b.se+1ll*a.se*b.fi)%mod);
}

int s1(int l,int r) {
	return (l+r)*(r-l+1)/2;
}

int main() {
#ifdef LOCAL
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
#endif
	ios::sync_with_stdio(0);cin.tie(0);
	cin>>n>>m>>mod;
	for(int i=0;i<N;i++) {
		C[i][0]=1;
		for(int j=1;j<=i;j++) C[i][j]=add(C[i-1][j],C[i-1][j-1]);
	}
	for(int i=0;i<=n;i++) {
		dp[i][0]=mp(1,0);
		for(int j=1;j<=i&&j<=m;j++) {
			if(i!=j) {
				for(int k=1;k<=i;k++)
					dp[i][j]=dp[i][j]+dp[k-1][k-1]*dp[i-k][j-k+1]*mp(C[j][k-1],0);
			}
			else {
				for(int k=1;k<=i;k++) {
					dp[i][j]=dp[i][j]+dp[k-1][k-1]*dp[i-k][i-k]*mp(C[i-1][k-1],0)*mp(i+1,k*k-s1(1,k)+s1(k+1,i)-k*(i-k));
					//if(i==2&&j==2) cerr<<dp[i][j].fi<<' '<<dp[i][j].se<<'\n';
				}
			}
			//cerr<<i<<' '<<j<<' '<<dp[i][j].fi<<' '<<dp[i][j].se<<'\n';
		}
	}
	cout<<dp[n][m].se;
	return 0;
}


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

#ifdef SG
	#include <debug.h>
#else
	template<typename T> struct outputer;
	struct outputable {};
	#define PRINT(...)
	#define OUTPUT(...)
	#define show(...)
	#define debug(...)
	#define deepen(...)
	#define timer(...)
	#define fbegin(...)
	#define fend
	#define pbegin(...)
	#define pend
#endif

#define ARG4(_1,_2,_3,_4,...) _4

#define forn3(i,l,r) for (int i = int(l); i < int(r); ++i)
#define forn2(i,n) forn3 (i, 0, n)
#define forn(...) ARG4(__VA_ARGS__, forn3, forn2) (__VA_ARGS__)

#define ford3(i,l,r) for (int i = int(r) - 1; i >= int(l); --i)
#define ford2(i,n) ford3 (i, 0, n)
#define ford(...) ARG4(__VA_ARGS__, ford3, ford2) (__VA_ARGS__)

#define ve vector
#define pa pair
#define tu tuple
#define mp make_pair
#define mt make_tuple
#define pb emplace_back
#define fs first
#define sc second
#define all(a) (a).begin(), (a).end()
#define sz(a) ((int)(a).size())

typedef long double ld;
typedef int64_t ll;
typedef uint64_t ull;
typedef uint32_t ui;
typedef uint16_t us;
typedef uint8_t uc;
typedef pa<int, int> pii;
typedef pa<int, ll> pil;
typedef pa<ll, int> pli;
typedef pa<ll, ll> pll;
typedef ve<int> vi;

template<typename T> inline auto sqr (T x) -> decltype(x * x) {return x * x;}
template<typename T1, typename T2> inline bool umx (T1& a, T2 b) {if (a < b) {a = b; return 1;} return 0;}
template<typename T1, typename T2> inline bool umn (T1& a, T2 b) {if (b < a) {a = b; return 1;} return 0;}

const int N = 500;

struct Input {
	ll mod;
	int n, m;

	bool read() {
		return !!(cin >> n >> m >> mod);
	}

	void init(const Input &input) {
		*this = input;
	}
};

struct Data: Input {
	ll ans;

	void write() {
		cout << ans << endl;
	}
};

namespace Main {

	struct Solution: Data {

		ll pw(ll x, ll y) {
			ll res = 1;
			while (y) {
				if (y & 1) {
					res = res * x % mod;
				}
				x = x * x % mod;
				y >>= 1;
			}
			return res;
		}

		ll inv(ll x) {
			return pw(x, mod - 2);
		}

		ll ss(int x) {
			return x * (x + 1) / 2;
		}

		ll c[N + 1][N + 1];

		// cnt, sum
		pll a[N + 1];
		pll d[N + 2][N + 1];

		void solve() {
			forn (i, n + 1) {
				forn (j, n + 1) {
					if (!i || !j) {
						c[i][j] = 1;
						continue;
					}
					c[i][j] = (c[i - 1][j] + c[i][j - 1]) % mod;
				}
			}

			memset(a, 0, sizeof a);
			a[0] = pll(1, 0);
			forn (i, 1, m + 1) {
				forn (j, i) {
					pll cur;
					cur.fs = a[j].fs * a[i - 1 - j].fs % mod;
					cur.sc = (a[j].sc * a[i - 1 - j].fs + a[j].fs * a[i - 1 - j].sc) % mod;
					cur.sc = (cur.sc * (i + 1) + (ss(j) + ss(i - 1 - j)) * cur.fs) % mod;
					cur.fs = cur.fs * (i + 1) % mod;
					cur.fs = cur.fs * c[j][i - 1 - j] % mod;
					cur.sc = cur.sc * c[j][i - 1 - j] % mod;
					a[i].fs = (a[i].fs + cur.fs) % mod;
					a[i].sc = (a[i].sc + cur.sc) % mod;
				}
			}

			debug(a, a + m + 1);

			memset(d, 0, sizeof d);
			d[0][0] = pll(1, 0);
			forn (i, n + 2) {
				forn (j, m + 1) {
					forn (k, min(n - i, m - j) + 1) {
						pll cur;
						cur.fs = a[k].fs * d[i][j].fs % mod;
						cur.sc = (a[k].sc * d[i][j].fs + a[k].fs * d[i][j].sc) % mod;
						cur.fs = cur.fs * c[j][k] % mod;
						cur.sc = cur.sc * c[j][k] % mod;
						d[i + k + 1][j + k].fs = (d[i + k + 1][j + k].fs + cur.fs) % mod;
						d[i + k + 1][j + k].sc = (d[i + k + 1][j + k].sc + cur.sc) % mod;
					}
				}
				debug(d[i], d[i] + m + 1);
			}
			ans = d[n + 1][m].sc;
		}

		void clear() {
			*this = Solution();
		}
	};
}

Main::Solution sol;

int main() {
	cout.setf(ios::showpoint | ios::fixed);
	cout.precision(20);

	#ifdef SG
		freopen((problemname + ".in").c_str(), "r", stdin);
//		freopen((problemname + ".out").c_str(), "w", stdout);
		while (sol.read()) {
			sol.solve();
			sol.write();
			sol.clear();
		}
	#else
		sol.read();
		sol.solve();
		sol.write();
	#endif

	/*
	int t;
	cin >> t;
	forn (i, t) {
		sol.read();
		sol.solve();
		sol.write();
		sol.clear();
	}
	*/

	return 0;
}


// Author -- xyr2005

#include<bits/stdc++.h>

#define lowbit(x) ((x)&(-(x)))
#define DEBUG fprintf(stderr,"Running on Line %d in Function %s\n",__LINE__,__FUNCTION__)
#define SZ(x) ((int)x.size())
#define mkpr std::make_pair
#define pb push_back

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef std::pair<int,int> pi;
typedef std::pair<ll,ll> pl;
using std::min;
using std::max;

const int inf=0x3f3f3f3f,Inf=0x7fffffff;
const ll INF=0x3f3f3f3f3f3f3f3f;

std::mt19937 rnd(std::chrono::steady_clock::now().time_since_epoch().count());
template <typename _Tp>_Tp gcd(const _Tp &a,const _Tp &b){return (!b)?a:gcd(b,a%b);}
template <typename _Tp>inline _Tp abs(const _Tp &a){return a>=0?a:-a;}
template <typename _Tp>inline void chmax(_Tp &a,const _Tp &b){(a<b)&&(a=b);}
template <typename _Tp>inline void chmin(_Tp &a,const _Tp &b){(b<a)&&(a=b);}
template <typename _Tp>inline void read(_Tp &x)
{
	char ch(getchar());bool f(false);while(!isdigit(ch)) f|=ch==45,ch=getchar();
	x=ch&15,ch=getchar();while(isdigit(ch)) x=(((x<<2)+x)<<1)+(ch&15),ch=getchar();
	f&&(x=-x);
}
template <typename _Tp,typename... Args>inline void read(_Tp &t,Args &...args){read(t);read(args...);}
inline int read_str(char *s)
{
	char ch(getchar());while(ch==' '||ch=='\r'||ch=='\n') ch=getchar();
	char *tar=s;*tar=ch,ch=getchar();while(ch!=' '&&ch!='\r'&&ch!='\n'&&ch!=EOF) *(++tar)=ch,ch=getchar();
	return tar-s+1;
}

const int N=505;
int mod;
struct FastMod{
	typedef __uint128_t LLL;
	ull b,m;
	void init(ull b){this->b=b,m=ull((LLL(1)<<64)/b);}
	inline ull operator()(ull a){
		ull r=a-(ull)((LLL(m)*a)>>64)*b;
		return r>=b?r-b:r;
	}
}M;
template<typename _Tp1,typename _Tp2>inline void add(_Tp1 &a,_Tp2 b){(a+=b)>=mod&&(a-=mod);}
template<typename _Tp1,typename _Tp2>inline void sub(_Tp1 &a,_Tp2 b){(a-=b)<0&&(a+=mod);}
int f[N],g[N],dp1[N][N],dp2[N][N],C[N][N];
inline ll s(int x){return x*(x+1)/2;}
int main()
{
	int n,m;read(n,m,mod),M.init(mod);
	for(int i=0;i<N;++i) for(int j=C[i][0]=1;j<=i;++j) C[i][j]=C[i-1][j-1],add(C[i][j],C[i-1][j]);
	g[0]=1;
	for(int i=1;i<=m;++i)
	{
		for(int j=1;j<=i;++j)
		{
			int tmp=C[i-1][j-1],coef=M(M(1LL*g[j-1]*g[i-j])*tmp);
			add(f[i],M(M(M(1LL*f[j-1]*g[i-j]+1LL*g[j-1]*f[i-j])*(i+1))*tmp));
			add(f[i],M((s(j-1)+s(i-j))*coef));
			add(g[i],M(1LL*coef*(i+1)));
		}
	}
	dp2[0][0]=1;
	for(int i=0;i<=n;++i)
	{
		for(int j=0;j<=m;++j)
		{
			add(dp1[i+1][j],dp1[i][j]),add(dp2[i+1][j],dp2[i][j]);
			for(int k=1;i+k<=n&&j+k<=m;++k)
			{
				int tmp=C[j+k][j];
				add(dp1[i+k+1][j+k],M(M(1LL*tmp*dp1[i][j])*g[k]));
				add(dp1[i+k+1][j+k],M(M(1LL*tmp*dp2[i][j])*f[k]));
				add(dp2[i+k+1][j+k],M(M(1LL*tmp*dp2[i][j])*g[k]));
			}
		}
	}
	printf("%d\n",dp1[n+1][m]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std ;
#define Next( i, x ) for( register int i = head[x]; i; i = e[i].next )
#define rep( i, s, t ) for( register int i = (s); i <= (t); ++ i )
#define drep( i, s, t ) for( register int i = (t); i >= (s); -- i )
#define re register
#define int long long
int gi() {
	char cc = getchar() ; int cn = 0, flus = 1 ;
	while( cc < '0' || cc > '9' ) {  if( cc == '-' ) flus = - flus ; cc = getchar() ; }
	while( cc >= '0' && cc <= '9' )  cn = cn * 10 + cc - '0', cc = getchar() ;
	return cn * flus ;
}
const int N = 500 + 5 ;
int n, m, P, maxn, fac[N], inv[N], F[N][N], G[N][N], f[N], g[N] ;
int fpow(int x, int k) {
	int ans = 1, base = x ;
	while(k) {
		if(k & 1) ans = 1ll * ans * base % P ;
		base = 1ll * base * base % P, k >>= 1 ;
	} return ans ;
}
int C(int x, int y) {
	if( x < y ) return 0 ;
	return fac[x] * inv[y] % P * inv[x - y] % P ;
}
int S(int x) {
	return x * (x + 1) / 2 ;
}
signed main()
{
	n = gi(), m = gi(), P = gi() ;
	maxn = n + 1, fac[0] = inv[0] = 1 ;
	rep( i, 1, maxn ) fac[i] = fac[i - 1] * i % P ;
	rep( i, 1, maxn ) inv[i] = fpow( fac[i], P - 2 ) ;
	f[0] = 1 ;
	rep( i, 1, m ) {
		for(re int j = 0; j < i; ++ j)
			f[i] = (f[i] + f[j] * f[i - 1 - j] % P * C(i - 1, j) % P) % P,
			g[i] = (g[i] +
				( (g[j] * f[i - 1 - j] % P + f[j] * g[i - 1 - j] % P ) * (i + 1) % P
				+ f[j] * f[i - 1 - j] % P * (S(j) + S(i - 1 - j)) % P) * C(i - 1, j) % P) % P ;
		f[i] = f[i] * (i + 1) % P ;
	}
	F[0][0] = 1 ;
	rep( j, 0, n ) F[0][j] = 1 ;
	rep( i, 1, m ) {
		F[i][i] = f[i], G[i][i] = g[i] ;
		for(re int j = i + 1; j <= n; ++ j) {
			F[i][j] = F[i][j - 1], G[i][j] = G[i][j - 1] ;
			for(re int l = 1; l <= i; ++ l) {
				F[i][j] = (F[i][j] + F[i - l][j - 1 - l] * f[l] % P * C(i, l) % P) % P,
				G[i][j] = (G[i][j] + (G[i - l][j - 1 - l] * f[l] % P + F[i - l][j - 1 - l] * g[l] % P) * C(i, l) % P) % P ;
			}
		//	printf("QAQ (%lld %lld) %lld %lld\n", i, j, F[i][j], G[i][j] ) ;
		}
	}
	cout << G[m][n] << endl ;
	return 0 ;
}


#include <bits/stdc++.h>
using namespace std;
typedef signed long long ll;

#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<(to);x++)
#define FORR(x,arr) for(auto& x:arr)
#define FORR2(x,y,arr) for(auto& [x,y]:arr)
#define ALL(a) (a.begin()),(a.end())
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
template<class T> bool chmax(T &a, const T &b) { if(a<b){a=b;return 1;}return 0;}
template<class T> bool chmin(T &a, const T &b) { if(a>b){a=b;return 1;}return 0;}
//-------------------------------------------------------

ll mo;
struct modint {
	ll v;
	modint(const ll a=0) { v=a; if(mo&&(v>=mo||v<0)) v=(v%mo+mo)%mo;}
	static modint pow(const modint& a,ll n=mo-2) {
		ll b=a.v,r=1;
		while(n) r=r*((n%2)?b:1)%mo,b=b*b%mo,n>>=1;
		return modint(r);
	}
	modint& operator+=(const modint& a) { v+=a.v; if(v>=mo) v-=mo; return *this;}
	modint& operator-=(const modint& a) { v+=mo-a.v; if(v>=mo) v-=mo; return *this;}
	modint& operator*=(const modint& a) { v=v*a.v%mo; return *this;}
	modint& operator/=(const modint& a) { assert(a.v!=0); *this*=pow(a); return *this;}
	modint operator+(const modint& a) const { modint res(*this); return res+=a;}
	modint operator-(const modint& a) const { modint res(*this); return res-=a;}
	modint operator*(const modint& a) const { modint res(*this); return res*=a;}
	modint operator/(const modint& a) const { modint res(*this); return res/=a;}
	friend ostream& operator<<(ostream& os, const modint& a){ os<<a.v; return os;}
};

int N,M;
modint dp1[505];
modint dp2[505];
modint dp3[505][505];
modint dp4[505][505];

ll comb(ll N_, ll C_) {
	const int NUM_=400001;
	static ll fact[NUM_+1],factr[NUM_+1],inv[NUM_+1];
	if (fact[0]==0) {
		inv[1]=fact[0]=factr[0]=1;
		for (int i=2;i<=NUM_;++i) inv[i] = inv[mo % i] * (mo - mo / i) % mo;
		for (int i=1;i<=NUM_;++i) fact[i]=fact[i-1]*i%mo, factr[i]=factr[i-1]*inv[i]%mo;
	}
	if(C_<0 || C_>N_) return 0;
	return factr[C_]*fact[N_]%mo*factr[N_-C_]%mo;
}

void solve() {
	int i,j,k,l,r,x,y; string s;

	cin>>N>>M>>mo;
	dp1[0]=1;
	for(i=1;i<=N;i++) {
		for(j=1;j<=i;j++) {
			dp1[i]+=modint(i+1)*dp1[j-1]*dp1[i-j]*comb(i-1,j-1);
			dp2[i]+=modint(i+1)*(dp2[i-j]*dp1[j-1]+dp1[i-j]*dp2[j-1])*comb(i-1,j-1);
			dp2[i]+=dp1[j-1]*dp1[i-j]*comb(i-1,j-1)*(comb(j-1+1,2)+comb(i-j+1,2));
		}
	}
	dp3[0][0]=1;
	for(i=1;i<=N;i++) {
		FOR(j,i) {
			dp3[i][j]=dp3[i-1][j];
			dp4[i][j]=dp4[i-1][j];
			for(l=1;l<=j;l++) {
				dp3[i][j]+=dp1[l]*dp3[i-l-1][j-l]*comb(j,l);
				dp4[i][j]+=(dp1[l]*dp4[i-l-1][j-l]+dp2[l]*dp3[i-l-1][j-l])*comb(j,l);
			}
		}
		dp3[i][i]=dp1[i];
		dp4[i][i]=dp2[i];
	}

	cout<<dp4[N][M]<<endl;

}

int main(int argc,char** argv){
	string s;int i;
	if(argc==1) ios::sync_with_stdio(false), cin.tie(0);
	FOR(i,argc-1) s+=argv[i+1],s+='\n'; FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin);
	cout.tie(0); solve(); return 0;
}


#include<bits/stdc++.h>
#define cs const
#define pb push_back
using namespace std;
int Mod;
int add(int a, int b){ return a + b >= Mod ? a + b - Mod : a + b; }
int dec(int a, int b){ return a - b < 0 ? a - b + Mod : a - b; }
int mul(int a, int b){ return 1ll * a * b % Mod; }
void Add(int &a, int b){ a = add(a, b); }
void Dec(int &a, int b){ a = dec(a, b); }
void Mul(int &a, int b){ a = mul(a, b); }
cs int N = 1e3 + 50;
int n, m, f[N], g[N];
int C[N][N];
void fc_init(int n){
	for(int i = 0; i <= n; i++) C[i][0] = 1;
	for(int i = 1; i <= n; i++)
	for(int j = 1; j <= i; j++)
	C[i][j] = add(C[i - 1][j - 1], C[i - 1][j]);
}
int main(){
	#ifdef FSYo
	freopen("1.in", "r", stdin);
	#endif
	cin >> n >> m >> Mod;
	f[1] = 2, g[1] = 0;
	fc_init(max(m, n - m + 1));
	for(int i = 2; i <= m; i++){
		f[i] = mul(f[i - 1], 2 * (i + 1));
		g[i] = mul(g[i - 1], 2 * (i + 1));
		Add(g[i], mul(f[i - 1], i * (i - 1)));
		for(int j = 1; j < i; j++){
			int k = i - j - 1;
			int c = mul(C[j + k][j], j + k + 2);
			Add(f[i], mul(c, mul(f[j], f[k])));
			Add(g[i], mul(c, mul(f[j], g[k])));
			Add(g[i], mul(c, mul(g[j], f[k])));
			int w = j * (j + 1) / 2 + k * (k + 1) / 2;
			Add(g[i], mul(mul(C[j + k][j], w), mul(f[j], f[k])));
		}
	}
	static int dp[N][N][2];
	dp[0][0][0] = 1;
	for(int i = 0; i <= m; i++)
	for(int j = 0; j <= m; j++)
	for(int o = 0, c; o < 2; o++)
	if(c = dp[i][j][o]){
		if(!o)
		for(int k = 1; k + j <= m; k++)
		Add(dp[i + 1][j + k][0], mul(mul(c, C[j + k][k]), f[k])),
		Add(dp[i + 1][j + k][1], mul(mul(c, C[j + k][k]), g[k]));
		else
		for(int k = 1; k + j <= m; k++)
		Add(dp[i + 1][j + k][1], mul(mul(c, C[j + k][k]), f[k]));
	}
	int ans = 0;
	for(int i = 1; i <= m; i++)
	Add(ans, mul(dp[i][m][1], C[n - m + 1][i]));
	cout << ans;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 505;
int n, m, mod;
inline int add(int x, int y) {
	x += y;
	return x >= mod ? x - mod : x;
}
inline int mul(int x, int y) { return 1ll * x * y % mod; }
int C[maxn][maxn];
int f[maxn], g[maxn];
int F[maxn][maxn], G[maxn][maxn];
int main() {
	scanf("%d%d%d", &n, &m, &mod);
	for(int i = 0; i <= n; i++) {
		C[i][0] = 1;
		for(int j = 1; j <= i; j++) C[i][j] = add(C[i - 1][j - 1], C[i - 1][j]);
	}
	f[0] = 1;
	for(int i = 1; i <= n; i++) {
		for(int j = 1; j <= i; j++) {
			f[i] = add(f[i], mul(mul(f[j - 1], f[i - j]), mul(i + 1,  C[i - 1][j - 1])));
			g[i] = add(g[i], mul(mul(f[j - 1], g[i - j]), mul(i + 1,  C[i - 1][j - 1])));
			g[i] = add(g[i], mul(mul(g[j - 1], f[i - j]), mul(i + 1,  C[i - 1][j - 1])));
			g[i] = add(g[i], mul(mul(f[j - 1], f[i - j]), mul(add(C[j][2], C[i - j + 1][2]),  C[i - 1][j - 1])));
		}
	}
	F[0][0] = 1;
	for(int i = 1; i <= n; i++)
		for(int j = 0; j <= min(i, m); j++) {
			for(int l = 0; l < j; l++) {
				F[i][j] = add(F[i][j], mul(mul(f[l], F[i - l - 1][j - l]), C[j][l]));
				G[i][j] = add(G[i][j], mul(mul(g[l], F[i - l - 1][j - l]), C[j][l]));
				G[i][j] = add(G[i][j], mul(mul(f[l], G[i - l - 1][j - l]), C[j][l]));
			}
			F[i][j] = add(F[i][j], f[j]);
			G[i][j] = add(G[i][j], g[j]);
		}
	cout << G[n][m] << endl;
	return 0;
}


//In the Name of God
//Ya Ali

#include <bits/stdc++.h>

#define err(A) cout << #A << " = " << (A) << endl

#define int long long

using namespace std;

const int maxn = 512;

int n, m, M;

int c[maxn][maxn];
int p[maxn][maxn];

int me, you;

int g(int a, int b)
{
  if (!b)
    return 1;
  return p[a + 1][b - 1] * p[2][b] %M * (a + 1 - b) %M;
}

int32_t main()
{
  ios::sync_with_stdio(0); cin.tie(0);

  cin >> n >> m >> M;

  for (int i = 0; i < maxn; i ++)
    for (int j = 0; j <= i; j ++)
      if (j)
	c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % M;
      else
	c[i][j] = 1;

  for (int i = 0; i < maxn; i ++)
    for (int j = 0; j < maxn; j ++)
      if (j)
	p[i][j] = p[i][j - 1] * i % M;
      else
	p[i][j] = 1;

  for (int i = 2; i <= m; i ++)
    for (int d = 1; d < i; d ++)
      {
	me = d * (d + 1) / 2 * c[i - 1][d] %M * p[d + 1][d - 1] %M * g(n + 1 - (d + 1) - 1, i - (d + 1)) %M * p[2][d] %M * p[n + 1][m - i] %M * p[2][m - i] %M;
	you = (you + me + me) % M;
      }

  cout << you * (n + 1 - m) % M << endl;

  return 0;
}


#include<bits/stdc++.h>
using namespace std;
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/detail/standard_policies.hpp>
// using namespace __gnu_pbds;

#pragma GCC optimize("O3")
#ifdef LOCAL
#include "/Users/lbjlc/Desktop/coding/debug_utils.h"
#else
#define print(...) ;
#define printn(...) ;
#define printg(...) ;
#define fprint(...) ;
#define fprintn(...) ;
#endif

#define rep(i, a, b) for(auto i = (a); i < (b); i++)
#define rrep(i, a, b) for(auto i = (a); i > (b); i--)
#define all(v) (v).begin(), (v).end()
#define pb push_back
// #define mp make_pair
#define fi first
#define se second
#define maxi(x, y) x = max(x, y)
#define mini(x, y) x = min(x, y)
// long long fact(long long n) { if(!n) return 1; return n*fact(n-1); }
// #define endl '\n'
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int get_random() {
    static uniform_int_distribution<int> dist(0, 1e9 + 6);
    return dist(rng);
}
#define solve_testcase int T;cin>>T;for(int t=1;t<=T;t++){solve(t);}

typedef unsigned long long ull;
typedef long long ll;

typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<pdd> vpdd;
typedef vector<long long> vll;
#define bd(type,op,val) bind(op<type>(), std::placeholders::_1, val)

template<class T>
void make_unique(T & v) {
    sort(v.begin(), v.end()); v.erase(unique(v.begin(), v.end()), v.end());
}
int geti() { int x; cin >> x; return x; }
long long getll() { long long x; cin >> x; return x; }
double getd() { double x; cin >> x; return x; }
// pair<int, int> a(geti(), geti()) does not work
// pair<int, int> a({geti(), geti()}) works, since it uses initializer.

const int MAXN = 500 + 100;

void solve(int tt) {
    // cout<<"Case #"<<tt<<": ";
}

ll mod;
struct mint{
    long long x;

    mint(): x(0) {}
    mint(long long _x) { x = _x >= 0 ? _x % mod : _x % mod + mod; }
    //operator long long() { return x; }

    template<class T>
    mint operator^(T b) const {
        if(!b) return 1;
        mint tmp = (*this) ^ (b / 2);
        return b % 2 ? tmp * tmp * (*this) : tmp * tmp;
    }

    mint inv() const {
        static unordered_map<long long, long long> inv_dp;
        if(inv_dp.count(x))
            return inv_dp[x];
        else if(inv_dp.size() < 100000)
            return mint(inv_dp[x] = ((*this) ^ (mod - 2)).x);
        else return (*this) ^ (mod - 2);
    }

    mint operator+(const mint & b) const { return (x + b.x) % mod; }
    mint operator-(const mint & b) const { return (x - b.x + mod) % mod; }
    mint operator*(const mint & b) const { return (x * b.x) % mod; }
    mint operator/(const mint & b) const { return (*this) * b.inv(); }

    mint & operator+=(const mint & b) { x = (x + b.x) % mod; return *this; }
    mint & operator-=(const mint & b) { x = (x - b.x + mod) % mod; return *this; }
    mint & operator*=(const mint & b) { x = (x * b.x) % mod; return *this; }
    mint & operator/=(const mint & b) { x = (x * b.inv().x) % mod; return *this; }

    bool operator==(const mint & b) const { return x == b.x; }
    bool operator!=(const mint & b) const { return x != b.x; }
};
mint comb[MAXN][MAXN];
void gen_comb(int n) {
    for(int i = 0; i <= n; i++) {
        comb[i][0] = comb[i][i] = 1;
        for(int j = 1; j < i; j++)
            comb[i][j] = comb[i - 1][j - 1] + comb[i - 1][j];
    }
}
string to_string(const mint & x) { return to_string(x.x); }

mint a[MAXN],c[MAXN];

mint dp[MAXN][MAXN][2];
mint dpc[MAXN][MAXN][2];

ll s1(ll l, ll r) {
	if(l>r)return 0;
	return (l+r)*(r-l+1)/2;
}

int main(int argc, char * argv[]) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    // solve_testcase;

    ll n,m;
    cin>>n>>m>>mod;

    gen_comb(MAXN-1);

    a[0]=0;
    c[0]=1;
    a[1]=0;
    c[1]=2;
    rep(i,2,m+1) {
    	mint tmp=0;
    	mint tmpc=0;
    	// tmp+=c[i-1]*s1(1,i-1)*2+a[i-1]*(i+1)*2;
    	// tmpc+=c[i-1]*2*(i+1);
    	rep(l,0,i) {
    		ll r=i-1-l;
    		tmp+=c[l]*c[r]*(s1(1,l)+s1(1,r))*comb[i-1][l]+(a[l]*c[r]+a[r]*c[l])*comb[i-1][l]*(i+1);
    		tmpc+=c[l]*c[r]*(i+1)*comb[i-1][l];
    	}
    	a[i]=tmp;
    	c[i]=tmpc;
    }
    printn(a,m+1);
    printn(c,m+1);

    dpc[0][0][0]=1;
    rep(i,1,n+1) {
    	rep(j,0,m+1) {
    		if(j>i) continue;

    		dpc[i][j][0]=dpc[i-1][j][0]+dpc[i-1][j][1];
    		rep(k,1,j+1) {
    			dpc[i][j][1]+=c[k]*comb[j][k]*dpc[i-k][j-k][0];
    		}
    	}
    }

    // dp[0][0][0]=0;
    rep(i,1,n+1) {
    	rep(j,0,m+1) {
    		if(j>i) continue;

    		dp[i][j][0]=dp[i-1][j][0]+dp[i-1][j][1];
    		rep(k,1,j+1) {
    			dp[i][j][1]+=a[k]*comb[j][k]*dpc[i-k][j-k][0] + dp[i-k][j-k][0]*c[k]*comb[j][k];
    		}
    	}
    }

    cout<<(dp[n][m][0]+dp[n][m][1]).x<<endl;

    // mint res=0;
    // rep(i,1,n+1)res+=dp[i][m][1];
    // cout<<res.x<<endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define f(i, x, n) for(int i = x; i < (int)n; ++i)

int const N = 500;
int md, ch[N + 1][N + 1];
pair<int, int> dp1[N + 1], dp2[2][N + 1][N + 1];

void ad(int &x, int y) { if ((x += y) >= md)x -= md; }

int sm(int n) { return n * (n + 1) >> 1; }

int main(){
	int n, m;
	scanf("%d%d%d", &n, &m, &md);

	f(i, 0, m + 1){
		ch[i][0] = 1;
		f(j, 1, i + 1)ad(ch[i][j] = ch[i - 1][j], ch[i - 1][j - 1]);
	}

	dp1[0].first = 1;
	f(i, 1, m + 1)f(j, 1, i + 1){
		int w = (ll)dp1[j - 1].first * dp1[i - j].first % md * ch[i - 1][j - 1] % md;
		ad(dp1[i].second, (sm(j - 1) + sm(i - j)) * (ll)w % md);
		ad(dp1[i].second, (ll)dp1[j - 1].second * dp1[i - j].first % md * (i + 1) % md * ch[i - 1][j - 1] % md);
		ad(dp1[i].second, (ll)dp1[j - 1].first * dp1[i - j].second % md * (i + 1) % md * ch[i - 1][j - 1] % md);
		ad(dp1[i].first, (ll)w * (i + 1) % md);
	}

	dp2[0][0][0].first = dp2[1][0][0].first = 1;
	f(i, 0, n)f(j, 0, i + 1)f(ln, 1, n - i + 1){
		ad(dp2[1][i + ln][j].first, dp2[0][i][j].first);
		ad(dp2[1][i + ln][j].second, dp2[0][i][j].second);

		ad(dp2[0][i + ln][j + ln].first, (ll)dp2[1][i][j].first * dp1[ln].first % md * ch[j + ln][j] % md);
		ad(dp2[0][i + ln][j + ln].second, (ll)dp2[1][i][j].first * dp1[ln].second % md * ch[j + ln][j] % md);
		ad(dp2[0][i + ln][j + ln].second, (ll)dp2[1][i][j].second * dp1[ln].first % md * ch[j + ln][j] % md);
	}

	int an = dp2[0][n][m].second;
	ad(an, dp2[1][n][m].second);
	printf("%d\n", an);
}


//#pragma GCC optimize("O3")
//#pragma GCC target("arch=corei7-avx")
#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));
}

template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }

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;
        }
    }
    cin.exceptions(ios::failbit);
}

/*** TEMPLATE CODE ENDS HERE */

static ll choose[501][501];

int main(int argc, const char **argv)
{
    redirect(argc, argv);
    int N, M, P;
    cin >> N >> M >> P;
    for (int i = 0; i <= N; i++)
    {
        choose[i][0] = choose[i][i] = 1;
        for (int j = 1; j < i; j++)
            choose[i][j] = (choose[i - 1][j - 1] + choose[i - 1][j]) % P;
    }

    vector<ll> dp1(N + 1);
    vector<ll> dpw(N + 1);
    dp1[0] = 0;
    dpw[0] = 1;
    for (int m = 1; m <= M; m++)
    {
        for (int i = 0; i < m; i++)
        {
            ll w = dpw[i] * dpw[m - 1 - i] % P;
            w = w * choose[m - 1][i] % P;
            dpw[m] = (dpw[m] + w * (m + 1) % P) % P;

            ll s1 = dp1[i] * dpw[m - 1 - i] % P;
            ll s2 = dp1[m - 1 - i] * dpw[i] % P;
            ll add = (s1 + s2) % P * (m + 1) % P * choose[m - 1][i] % P;
            add += w * ((i * (i + 1) + (m - 1 - i) * (m - i)) / 2) % P;
            dp1[m] = (dp1[m] + add) % P;
        }
    }

    vector<vll> dp(N + 1, vll(N + 1)), dps(N + 1, vll(N + 1));
    dps[0][0] = 1;
    for (int i = 1; i <= N; i++)
    {
        dp[i][i] = dp1[i];
        dps[i][i] = dpw[i];
        dps[i][0] = 1;
        for (int j = 1; j < i; j++)
        {
            dp[i][j] = dp[i - 1][j];
            dps[i][j] = dps[i - 1][j];
            for (int k = 1; k <= j; k++)
            {
                dps[i][j] = (dps[i][j] + dpw[k] * dps[i - k - 1][j - k] % P * choose[j][k]) % P;
                ll add = (dp[i - k - 1][j - k] * dpw[k] % P + dps[i - k - 1][j - k] * dp1[k]) % P;
                dp[i][j] = (dp[i][j] + add * choose[j][k] % P) % P;
            }
        }
    }
    cout << dp[N][M] << '\n';

    return 0;
}


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

const int maxn = 510;

int m, n, mod;

inline int add (int x, int y) {return (1LL * x + y) % mod;}
inline int sub (int x, int y) {return x - y < 0 ? x - y + mod : x - y;}
inline int mul (int x, int y) {return 1LL * x * y % mod;}
int fac[maxn], inv[maxn], invfac[maxn];
void get_fac_and_inv(int n)
{
    fac[0] = inv[1] = fac[1] = invfac[0] = invfac[1] = 1LL;
    for (int i = 2; i <= n; i++) inv[i] = mul((mod - mod / i), inv[mod % i]);
    for (int i = 2; i <= n; i++) {fac[i] = mul (fac[i - 1], i); invfac[i] = mul (invfac[i - 1], inv[i]);}
}
inline int C (int n, int m) {if (n < m || m < 0) return 0; return mul(mul(fac[n], invfac[m]), invfac[n - m]);}
inline int P (int n, int m) {return C(n + m - 1, m - 1);}

int f[maxn], g[maxn], s[maxn];
int ff[maxn][maxn], gg[maxn][maxn];

int main()
{
    scanf ("%d %d %d", &n, &m, &mod);
    get_fac_and_inv (500);
    for (int i = 1; i <= n; i++) s[i] = add (s[i - 1], i);
    f[0] = 1; f[1] = 2;
    g[0] = 0; g[1] = 0;
    for (int i = 2; i <= n; i++)
    {
        for (int j = 0; j < i; j++)
        {
            int temp = mul (C (i - 1, j), mul(f[j], f[i - 1 - j]));
            f[i] = add (f[i], mul (temp, i + 1));
            g[i] = add (g[i], mul (temp, s[j] + s[i - 1 - j]));
            temp = mul (add (mul (g[j], f[i - 1 - j]), mul (g[i - 1 - j], f[j])), i + 1);
            g[i] = add (g[i], mul (temp, C(i - 1, j)));
        }
    }
    ff[0][0] = 1; gg[0][0] = 0;
    for (int i = 0; i <= m; i++)
        for (int j = 0; j <= m; j++)
        {
            if (!ff[i][j]) continue;
            for (int k = 1; k + j <= m; k++)
            {
                ff[i + 1][j + k] = add (ff[i + 1][j + k], mul (mul (ff[i][j], f[k]), C(j + k, k)));
                gg[i + 1][j + k] = add (gg[i + 1][j + k], mul (add (mul (gg[i][j], f[k]), mul (ff[i][j], g[k])), C(j + k, k)));
            }
        }
    int ans = 0;
    for (int i = 1; i <= m; i++)
        if (n + 1 - m >= i)
            ans = add (ans, mul (gg[i][m], P (n + 1 - m - i, i + 1)));
    printf ("%d\n", ans);
    return 0;
}


#include <bits/stdc++.h>

template <typename T, int NDIMS> struct tensor_view {
	static_assert(NDIMS >= 0, "NDIMS must be nonnegative");

protected:
	std::array<int, NDIMS> shape;
	std::array<int, NDIMS> strides;
	T* data;

	tensor_view(std::array<int, NDIMS> shape_, std::array<int, NDIMS> strides_, T* data_) : shape(shape_), strides(strides_), data(data_) {}

public:
	tensor_view() : shape{0}, strides{0}, data(nullptr) {}

protected:
	int flatten_index(std::array<int, NDIMS> idx) const {
		int res = 0;
		for (int i = 0; i < NDIMS; i++) { res += idx[i] * strides[i]; }
		return res;
	}
	int flatten_index_checked(std::array<int, NDIMS> idx) const {
		int res = 0;
		for (int i = 0; i < NDIMS; i++) {
			assert(0 <= idx[i] && idx[i] < shape[i]);
			res += idx[i] * strides[i];
		}
		return res;
	}

public:
	T& operator[] (std::array<int, NDIMS> idx) const {
		return data[flatten_index(idx)];
	}
	T& at(std::array<int, NDIMS> idx) const {
		return data[flatten_index_checked(idx)];
	}

	template <int D = NDIMS>
	std::enable_if_t<(0 < D), tensor_view<T, NDIMS-1>> operator[] (int idx) const {
		std::array<int, NDIMS-1> nshape; std::copy(shape.begin()+1, shape.end(), nshape.begin());
		std::array<int, NDIMS-1> nstrides; std::copy(strides.begin()+1, strides.end(), nstrides.begin());
		T* ndata = data + (strides[0] * idx);
		return tensor_view<T, NDIMS-1>(nshape, nstrides, ndata);
	}
	template <int D = NDIMS>
	std::enable_if_t<(0 < D), tensor_view<T, NDIMS-1>> at(int idx) const {
		assert(0 <= idx && idx < shape[0]);
		return operator[](idx);
	}

	template <int D = NDIMS>
	std::enable_if_t<(0 == D), T&> operator * () const {
		return *data;
	}

	template <typename U, int D> friend struct tensor_view;
	template <typename U, int D> friend struct tensor;
};

template <typename T, int NDIMS> struct tensor {
	static_assert(NDIMS >= 0, "NDIMS must be nonnegative");

protected:
	std::array<int, NDIMS> shape;
	std::array<int, NDIMS> strides;
	int len;
	T* data;

public:
	tensor() : shape{0}, strides{0}, len(0), data(nullptr) {}

	explicit tensor(std::array<int, NDIMS> shape_, const T& t = T()) {
		shape = shape_;
		strides[NDIMS-1] = 1;
		for (int i = NDIMS-1; i > 0; i--) {
			strides[i-1] = strides[i] * shape[i];
		}
		len = strides[0] * shape[0];
		data = new T[len];
		std::fill(data, data + len, t);
	}

	tensor(const tensor& o) : shape(o.shape), strides(o.strides), len(o.len), data(new T[len]) {
		for (int i = 0; i < len; i++) {
			data[i] = o.data[i];
		}
	}

	tensor& operator=(tensor&& o) noexcept {
		using std::swap;
		swap(shape, o.shape);
		swap(strides, o.strides);
		swap(len, o.len);
		swap(data, o.data);
		return *this;
	}
	tensor(tensor&& o) : tensor() {
		*this = std::move(o);
	}
	tensor& operator=(const tensor& o) {
		return *this = tensor(o);
	}
	~tensor() { delete[] data; }

	using view_t = tensor_view<T, NDIMS>;
	view_t view() {
		return tensor_view<T, NDIMS>(shape, strides, data);
	}
	operator view_t() {
		return view();
	}

	using const_view_t = tensor_view<const T, NDIMS>;
	const_view_t view() const {
		return tensor_view<const T, NDIMS>(shape, strides, data);
	}
	operator const_view_t() const {
		return view();
	}

	T& operator[] (std::array<int, NDIMS> idx) { return view()[idx]; }
	T& at(std::array<int, NDIMS> idx) { return view().at(idx); }
	const T& operator[] (std::array<int, NDIMS> idx) const { return view()[idx]; }
	const T& at(std::array<int, NDIMS> idx) const { return view().at(idx); }

	template <int D = NDIMS>
	std::enable_if_t<(0 < D), tensor_view<T, NDIMS-1>> operator[] (int idx) {
		return view()[idx];
	}
	template <int D = NDIMS>
	std::enable_if_t<(0 < D), tensor_view<T, NDIMS-1>> at(int idx) {
		return view().at(idx);
	}

	template <int D = NDIMS>
	std::enable_if_t<(0 < D), tensor_view<const T, NDIMS-1>> operator[] (int idx) const {
		return view()[idx];
	}
	template <int D = NDIMS>
	std::enable_if_t<(0 < D), tensor_view<const T, NDIMS-1>> at(int idx) const {
		return view().at(idx);
	}

	template <int D = NDIMS>
	std::enable_if_t<(0 == D), T&> operator * () {
		return *view();
	}
	template <int D = NDIMS>
	std::enable_if_t<(0 == D), const T&> operator * () const {
		return *view();
	}
};

template <int& MOD_> struct modnum {
	static constexpr int& MOD = MOD_;
	//static_assert(MOD_ > 0, "MOD must be positive");

private:
	using ll = long long;

	int v;

	static int minv(int a, int m) {
		a %= m;
		assert(a);
		return a == 1 ? 1 : int(m - ll(minv(m, a)) * ll(m) / a);
	}

public:

	modnum() : v(0) {}
	modnum(ll v_) : v(int(v_ % MOD)) { if (v < 0) v += MOD; }
	explicit operator int() const { return v; }
	friend std::ostream& operator << (std::ostream& out, const modnum& n) { return out << int(n); }
	friend std::istream& operator >> (std::istream& in, modnum& n) { ll v_; in >> v_; n = modnum(v_); return in; }

	friend bool operator == (const modnum& a, const modnum& b) { return a.v == b.v; }
	friend bool operator != (const modnum& a, const modnum& b) { return a.v != b.v; }

	modnum inv() const {
		modnum res;
		res.v = minv(v, MOD);
		return res;
	}
	friend modnum inv(const modnum& m) { return m.inv(); }
	modnum neg() const {
		modnum res;
		res.v = v ? MOD-v : 0;
		return res;
	}
	friend modnum neg(const modnum& m) { return m.neg(); }

	modnum operator- () const {
		return neg();
	}
	modnum operator+ () const {
		return modnum(*this);
	}

	modnum& operator ++ () {
		v ++;
		if (v == MOD) v = 0;
		return *this;
	}
	modnum& operator -- () {
		if (v == 0) v = MOD;
		v --;
		return *this;
	}
	modnum& operator += (const modnum& o) {
		v -= MOD-o.v;
		v = (v < 0) ? v + MOD : v;
		return *this;
	}
	modnum& operator -= (const modnum& o) {
		v -= o.v;
		v = (v < 0) ? v + MOD : v;
		return *this;
	}
	modnum& operator *= (const modnum& o) {
		v = int(ll(v) * ll(o.v) % MOD);
		return *this;
	}
	modnum& operator /= (const modnum& o) {
		return *this *= o.inv();
	}

	friend modnum operator ++ (modnum& a, int) { modnum r = a; ++a; return r; }
	friend modnum operator -- (modnum& a, int) { modnum r = a; --a; return r; }
	friend modnum operator + (const modnum& a, const modnum& b) { return modnum(a) += b; }
	friend modnum operator - (const modnum& a, const modnum& b) { return modnum(a) -= b; }
	friend modnum operator * (const modnum& a, const modnum& b) { return modnum(a) *= b; }
	friend modnum operator / (const modnum& a, const modnum& b) { return modnum(a) /= b; }
};

int MOD;

int main() {
	using namespace std;
	ios_base::sync_with_stdio(false), cin.tie(nullptr);
	int N, M; cin >> N >> M >> MOD;
	N++;
	using num = modnum<MOD>;
	vector<num> fact(N+1);
	fact[0] = 1;
	for (int i = 1; i <= N; i++) fact[i] = fact[i-1] * num(i);
	vector<num> ifact(N+1);
	ifact[N] = inv(fact[N]);
	for (int i = N; i >= 1; i--) ifact[i-1] = ifact[i] * num(i);

	vector<num> ways(N+1);
	vector<num> tot_val(N+1);
	ways[0] = 1, tot_val[0] = 0;

	for (int l = 1; l <= N; l++) {
		for (int i = 0; i < l; i++) {
			int a = i, b = l-1-i;

			num choose = fact[a+b] * ifact[a] * ifact[b];
			num sub_ways = ways[a] * ways[b] * choose;
			num sub_val = (tot_val[a] * ways[b] + tot_val[b] * ways[a]) * choose;

			ways[l] += sub_ways * num(l+1);
			tot_val[l] += sub_val * num(l+1) + sub_ways * num(a * (a+1) / 2 + b * (b+1) / 2);
		}
	}

	tensor<num, 2> pref_ways({N+1, M+1});
	tensor<num, 2> pref_vals({N+1, M+1});
	pref_ways[{0,0}] = 1;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j <= M; j++) {
			for (int k = 0; j+k <= M && i+1+k <= N; k++) {
				num choose = fact[j+k] * ifact[j] * ifact[k];
				pref_ways[{i+1+k,j+k}] += pref_ways[{i,j}] * ways[k] * choose;
				pref_vals[{i+1+k,j+k}] += (pref_ways[{i,j}] * tot_val[k] + pref_vals[{i,j}] * ways[k]) * choose;
			}
		}
	}

	cout << pref_vals[{N,M}] << '\n';

	return 0;
}