#include <iostream>
const int maxn = 100;
using namespace std;
int n; //图的顶点数
int k; //图的边数
int m; //可用颜色数
int graph[maxn][maxn]; //图的邻接矩阵graph[i][j]=1, 表示第i个顶点和第j
int x[maxn]; //当前解, 记录解空间树从根结点至当前结点的路径所表示的部分解
long long int sum; //当前已找到的可m着色方案数量
//判断顶点k是否与前面已着色的 k - 1个顶点发生冲突
bool Ok(int k)
{
for(int i = 1; i < k; i++)
{
if(graph[k][i] == 1 && x[k] == x[i]) //结点相连 && 结点同色
return false;
}
return true;
}
void Backtrack(int t)
{
if(t > n) //搜到叶结点,得到一种着色方案
{
sum++; //着色方案数增1
for(int i = 1; i <= n; i++) //打印当前的已找的着色方案
cout << x[i] << " ";
cout << endl;
return;
}
else
{
//该结点有x[i] = 1, …m个儿子结点,表示第k个结点可着第m种颜色,搜索当前扩展结点的每一个儿子结点
for(int i = 1; i <= m; i++)
{
x[t] = i;
if(Ok(t)) //Ok函数检查是否与前面已着色顶点发生冲突
Backtrack(t + 1);//如果满足约束条件(Ok函数)则继续DFS搜索, 不满足则剪去以该结点为根的子树
}
}
}
int main()
{
cin >> n >> k >> m;
for(int i = 0; i < k; i++)
{
int a, b;
cin >> a >> b;
graph[a][b] = graph[b][a] = 1;
}
Backtrack(1);
cout << sum << endl;
return 0;
}
/*
测试:
5 8 4
1 2
1 3
1 4
2 3
2 4
2 5
3 4
4 5
*/