1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include <algorithm>
#include <cstdio>
#include <vector>

struct {
  int values_[200005];
  int begin_, end_;
  void Add(int x) {
    values_[end_++] = x;
  }
  int Remove() {
    return values_[begin_++];
  }
  bool Empty() {
    return begin_ == end_;
  }
} queue;

struct {
  int link_[200005];
  int size_[200005];
  void Init(int n) {
    for (int i = 1; i <= n; i++) {
      link_[i] = i;
      size_[i] = 1;
    }
  }
  int Find(int w) {
    if (link_[w] == w) {
      return w;
    }
    return link_[w] = Find(link_[w]);
  }
  int Size(int w) {
    return size_[Find(w)];
  }
  void Union(int a, int b) {
    a = Find(a);
    b = Find(b);
    if (a != b) {
      if (size_[a] > size_[b]) {
        std::swap(a, b);
      }
      link_[a] = b;
      size_[b] += size_[a];
    }
  }
} find_union;

int n, m, d;

std::vector<int> graph[200005];
int degree[200005];
bool deleted[200005];

int main() {
  scanf("%d%d%d", &n, &m, &d);
  find_union.Init(n);
  while (m--) {
    int a, b;
    scanf("%d%d", &a, &b);
    graph[a].push_back(b);
    graph[b].push_back(a);
  }
  for (int i = 1; i <= n; i++) {
    degree[i] = (int) graph[i].size();
    if (degree[i] < d) {
      queue.Add(i);
      deleted[i] = true;
    }
  }
  while (!queue.Empty()) {
    int w = queue.Remove();
    for (int neighbour : graph[w]) {
      if (--degree[neighbour] < d) {
        if (!deleted[neighbour]) {
          queue.Add(neighbour);
          deleted[neighbour] = true;
        }
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    if (!deleted[i]) {
      for (int neighbour : graph[i]) {
        if (!deleted[neighbour]) {
          find_union.Union(i, neighbour);
        }
      }
    }
  }
  int max_size = 0;
  int max_size_root_node;
  for (int i = 1; i <= n; i++) {
    if (!deleted[i]) {
      if (find_union.Size(i) > max_size) {
        max_size = find_union.Size(i);
        max_size_root_node = find_union.Find(i);
      }
    }
  }
  if (max_size == 0) {
    printf("NIE\n");
  } else {
    printf("%d\n", max_size);
    for (int i = 1; i <= n; i++) {
      if (find_union.Find(i) == max_size_root_node) {
        printf("%d", i);
        if (--max_size) {
          printf(" ");
        }
      }
    }
    printf("\n");
  }
  return 0;
}