#include <bits/stdc++.h>
using namespace std;
int n, m, k;
vector<int> adj[10];
int graph[10][10];
bool isSet[1 << 10][1 << 10];
int mat[1 << 10][1 << 10];
int func(int nodes, int deadEnds) {
  if (isSet[nodes][deadEnds]) return mat[nodes][deadEnds];
  isSet[nodes][deadEnds] = true;
  int cnt = __builtin_popcount(nodes);
  if (!cnt) return mat[nodes][deadEnds] = 0;
  if (cnt == 1) return mat[nodes][deadEnds] = (nodes == deadEnds);
  if (cnt == 2) {
    if (nodes != deadEnds) return mat[nodes][deadEnds] = 0;
    int f, s;
    int i = 0;
    for (; i < n; i++) {
      if (nodes & (1 << i)) {
        f = i;
        break;
      }
    }
    i += 1;
    for (; i < n; i++) {
      if (nodes & (1 << i)) {
        s = i;
        break;
      }
    }
    return mat[nodes][deadEnds] = graph[f][s];
  }
  int node = 0;
  int u = 0;
  for (; u < n; u++) {
    node = 1 << u;
    if ((nodes & node) && (deadEnds & node)) break;
  }
  if (u == n) return mat[nodes][deadEnds] = 0;
  int newNodes = nodes ^ node;
  int newDeadEnds = deadEnds ^ node;
  int result = 0;
  for (int i = 0; i < adj[u].size(); i++) {
    int v = adj[u][i];
    if (newNodes & (1 << v)) {
      if ((newDeadEnds & (1 << v)) == 0) {
        result += func(newNodes, newDeadEnds);
        result += func(newNodes, newDeadEnds ^ (1 << v));
      }
    }
  }
  return mat[nodes][deadEnds] = result;
}
int main() {
  int u, v;
  scanf("%d%d%d", &n, &m, &k);
  for (int i = 0; i < m; i++) {
    scanf("%d%d", &u, &v);
    u--;
    v--;
    graph[u][v] = graph[v][u] = 1;
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  int x = 1 << n;
  int result = 0;
  for (int i = 0; i < x; i++) {
    if (__builtin_popcount(i) == k) {
      result += func(x - 1, i);
    }
  }
  printf("%d\n", result);
  return 0;
}
