#include <bits/stdc++.h>
using namespace std;
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  for (; !isdigit(ch); ch = getchar()) {
    if (ch == '-') f = -1;
  }
  for (; isdigit(ch); ch = getchar()) {
    x = x * 10 + ch - 48;
  }
  return x * f;
}
const int N = 100;
int P;
long long pw[N + 3][N * N + 3], comb[N + 3][N + 3], f[2][N + 3][N + 3],
    trans[N + 3][N + 3];
int n, m, p;
long long quickpow(long long x, long long y) {
  long long cur = x, ret = 1ll;
  for (int i = 0; y; i++) {
    if (y & (1ll << i)) {
      y -= (1ll << i);
      ret = ret * cur % P;
    }
    cur = cur * cur % P;
  }
  return ret;
}
void initmath() {
  for (int i = 0; i <= N; i++) {
    pw[i][0] = 1ll;
    for (int j = 1; j <= N * N; j++) pw[i][j] = pw[i][j - 1] * i % P;
  }
  comb[0][0] = 1ll;
  for (int i = 1; i <= N; i++) {
    comb[i][0] = comb[i][i] = 1ll;
    for (int j = 1; j < i; j++)
      comb[i][j] = (comb[i - 1][j] + comb[i - 1][j - 1]) % P;
  }
}
long long updsum(long long &x, long long y) {
  x = x + y >= P ? x + y - P : x + y;
}
int main() {
  scanf("%d%d%d%lld", &n, &m, &p, &P);
  initmath();
  int curk = 0;
  f[0][0][0] = 1ll;
  for (int k = 1; k <= p; k++) {
    curk ^= 1;
    memset(f[curk], 0, sizeof(f[curk]));
    for (int j = 0; j <= m; j++)
      for (int ii = 0; ii <= n; ii++)
        trans[j][ii] = pw[k][ii * (m - j)] % P * pw[p - k + 1][ii * j] % P;
    for (int i = 0; i <= n; i++) {
      for (int j = 0; j <= m; j++) {
        long long x = f[curk ^ 1][i][j];
        if (!x) continue;
        for (int ii = 0; ii + i <= n; ii++) {
          updsum(f[curk][i + ii][j],
                 x * comb[i + ii][i] % P * trans[j][ii] % P);
        }
      }
    }
    curk ^= 1;
    memset(f[curk], 0, sizeof(f[curk]));
    for (int i = 0; i <= n; i++)
      for (int jj = 0; jj <= m; jj++)
        trans[i][jj] = pw[k][jj * (n - i)] % P * pw[p - k + 1][jj * i] % P;
    for (int i = 0; i <= n; i++) {
      for (int j = 0; j <= m; j++) {
        long long x = f[curk ^ 1][i][j];
        if (!x) continue;
        for (int jj = 0; jj + j <= m; jj++) {
          updsum(f[curk][i][j + jj],
                 x * comb[j + jj][j] % P * trans[i][jj] % P);
        }
      }
    }
    curk ^= 1;
    memset(f[curk], 0, sizeof(f[curk]));
    for (int j = 0; j <= m; j++)
      for (int ii = 0; ii <= n; ii++)
        trans[j][ii] = pw[k][ii * (m - j)] % P * pw[p - k][ii * j] % P;
    for (int i = 0; i <= n; i++) {
      for (int j = 0; j <= m; j++) {
        long long x = f[curk ^ 1][i][j];
        if (!x) continue;
        for (int ii = 0; ii + i <= n; ii++) {
          long long y = x * comb[i + ii][i] % P * trans[j][ii] % P;
          updsum(f[curk][i + ii][j], ii & 1 ? P - y : y);
        }
      }
    }
    curk ^= 1;
    memset(f[curk], 0, sizeof(f[curk]));
    for (int i = 0; i <= n; i++)
      for (int jj = 0; jj <= m; jj++)
        trans[i][jj] = pw[k][jj * (n - i)] % P * pw[p - k][i * jj] % P;
    for (int i = 0; i <= n; i++) {
      for (int j = 0; j <= m; j++) {
        long long x = f[curk ^ 1][i][j];
        if (!x) continue;
        for (int jj = 0; jj + j <= m; jj++) {
          long long y = x * comb[j + jj][j] % P * trans[i][jj] % P;
          updsum(f[curk][i][j + jj], jj & 1 ? P - y : y);
        }
      }
    }
  }
  printf("%lld\n", f[curk][n][m]);
  return 0;
}
