#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,sse4.1,sse4.2,popcnt,mmx,avx")
#include "bits/stdc++.h"
#include <assert.h>
using namespace std;
typedef long long ll;
typedef long double ld;
#define PB push_back
#define MP make_pair
#define endl "\n"
#define fst first
#define snd second
const int UNDEF = -1;
const int INF=1<<30;
template<typename T> inline bool chkmax(T &aa, T bb) { return aa < bb ? aa = bb, true : false; }
template<typename T> inline bool chkmin(T &aa, T bb) { return aa > bb ? aa = bb, true : false; }
typedef pair<ll,ll> pll;typedef vector<ll> vll;typedef pair<int,int> pii;typedef vector<int> vi;typedef vector<vi> vvi;
#ifdef ONLINE_JUDGE
#define assert(...) /* nothing */
#endif
#define DEBUG_CAT
#ifdef DEBUG_CAT
#define dbg(...)   printf( __VA_ARGS__ )
#else 
#define dbg(...)   /****nothing****/
#endif
// mt19937 rng; rng.seed(std::chrono::high_resolution_clock::now().time_since_epoch().count());
// template<typename T> int bins(vector<T> &v, T key) {int imin=0,imax=v.size();while(imin<imax) {int imid=(imin+imax)>>1;if (v[imid]<key) imin=imid+1;else imax=imid;}return imin;}

void go(int n) {
  vi v(3*n);
  for (int i=0;i<3*n;i++) v[i]=i;
  map<vi,vi> h;
  do {
    vi p;
    vvi a(n); for (int i=0;i<n;i++) {for (int j=0;j<3;j++) a[i].PB(v[3*i+j]);}
    for (int i=0;i<3*n;i++) {
      pii least=MP(INF,INF);
      for (int k=0;k<n;k++) {
        if (a[k].size()) {
          chkmin(least,MP(a[k][0],k));
        }
      }
      int k=least.snd;
      p.PB(least.fst);
      a[k].erase(a[k].begin());
    }
    h[p]=v;
  } while(next_permutation(v.begin(),v.end()));

  /*for (auto &p:s) {
    for (auto &x:p) printf("%d ",x+1);
    printf("\n");
  }*/
  printf("%d\n",(int)h.size());
  vi g(3*n); for (int i=0;i<3*n;i++) g[i]=i;
  do {
    bool ok=true;
    int hi=-1,c=0,t=0;
    for (int x=0;x<3*n;x++) {
      if (g[x]>hi) {
        hi=g[x];
        c=2;
      } else {
        --c;
        if (c==1) ++t;
        if (c<0) ok=false;
      }
    }
    if (t>n) ok=false;
    bool found=h.count(g);
    if (ok!=found) {
      for (auto &w:g) printf("%d ",w);
      printf("ok:%d found:%d\n",ok,found);
      if (found) {
        for (auto &w:h[g]) printf("%d ",w);
        printf("\n");
      }
      exit(0);
    }
    assert(ok==found);
  }  while(next_permutation(g.begin(),g.end()));
  
}

int MOD;

struct mint {
  unsigned x;
  inline int _norm(int x) {
    if (x<0) x+=MOD;
    return x;
  }
  mint() : x(0) {}
  mint(signed sig) {sig=_norm(sig); x=sig;}
  mint(signed long long sig) {sig=_norm(sig%MOD); x=sig;}
  int get() const { return (int)x; }
 
  mint &operator+=(mint that) { if((x += that.x) >= MOD) x -= MOD; return *this; }
  mint &operator-=(mint that) { if((x += MOD - that.x) >= MOD) x -= MOD; return *this; }
  mint &operator*=(mint that) { x = ((unsigned long long)x * that.x) % MOD; return *this; }
  mint &operator/=(mint that) { return *this *= that.inverse(); }

  mint &operator+=(int that) {that=_norm(that); if((x += that) >= MOD) x -= MOD; return *this; }
  mint &operator-=(int that) {that=_norm(that); if((x += MOD - that) >= MOD) x -= MOD; return *this; }
  mint &operator*=(int that) {that=_norm(that); x = ((unsigned long long)x * that) % MOD; return *this; }
  mint &operator/=(int that) {that=_norm(that); return *this *= mint(that).inverse(); }

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

  mint operator+(int that) const { return mint(*this) += that; }
  mint operator-(int that) const { return mint(*this) -= that; }
  mint operator*(int that) const { return mint(*this) *= that; }
  mint operator/(int that) const { return mint(*this) /= that; }


  mint inverse() const {
    signed a = x, b = MOD, u = 1, v = 0;
    while(b) {
      signed t = a / b;
      a -= t * b; std::swap(a, b);
      u -= t * v; std::swap(u, v);
    }
    if(u < 0) u += MOD;
    mint res; res.x = (unsigned)u;
    return res;
  }
 
  bool operator==(mint that) const { return x == that.x; }
  bool operator!=(mint that) const { return x != that.x; }
  mint operator-() const { mint t; t.x = x == 0 ? 0 : MOD - x; return t; }
  mint operator^(unsigned long long k) const {
    // 0^0 is 1. k must be taken modulo phi(MOD) (MOD-1 if prime) and NOT MOD itself
    mint a=(*this);
    mint r = 1;
    while(k) {
      if(k & 1) r *= a;
      a *= a;
      k >>= 1;
    }
    return r;
  }
};

const int mn=2008;
mint f[3*mn][mn];
int main(){	
  //go(4);
  int n; cin>>n>>MOD;
  f[0][0]=1;
  for (int pos=0;pos<3*n;pos++) {
    for (int k=0;k<=n;k++) {
      mint now=f[pos][k];
      f[pos+1][k]+=now;
      f[pos+2][k+1]+=now * (pos+1);
      f[pos+3][k+1]+=now * (((pos+1) * pos) + 2*(pos+1));
    }
  }
  /*for (int pos=0;pos<3*n;pos++) {
    for (int k=0;k<=n;k++) {
      printf("%d ",f[pos][k].get());
    }
    printf(" pos:%d\n",pos);
  }*/
  mint final=0;
  for (int k=0;k<=n;k++) final+=f[3*n][k];
  printf("%d\n",final.get());
}



Measured memory_bytes: 47616