#include <bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;
const int maxn = 2e5 + 10;
struct no {
  int a, b, n;
} node[maxn * 2];
int h[maxn], fa[maxn], dep[maxn], tag[maxn], v[maxn * 2];
int cnt = 1, sq;
vector<int> ans, vec;
void cr(int a, int b) {
  node[++cnt].a = a;
  node[cnt].b = b;
  node[cnt].n = h[a];
  h[a] = cnt;
}
inline long long read() {
  long long s = 0, w = 1;
  char ch = getchar();
  while (ch < 48 || ch > 57) {
    if (ch == '-') w = -1;
    ch = getchar();
  }
  while (ch >= 48 && ch <= 57)
    s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
  return s * w;
}
void dfs(int a) {
  int i, j, b;
  vec.push_back(a);
  for (i = h[a]; i; i = node[i].n) {
    if (v[i]) continue;
    v[i] = v[i ^ 1] = 1;
    b = node[i].b;
    if (!dep[b]) {
      dep[b] = dep[a] + 1;
      dfs(b);
    } else {
      if (dep[a] - dep[b] >= sq - 1) {
        cout << "2\n" << dep[a] - dep[b] + 1 << endl;
        for (int j = dep[b] - 1; j < dep[a]; j++) cout << vec[j] << " ";
        exit(0);
      }
    }
  }
  if (!tag[a]) {
    tag[a] = 1;
    ans.push_back(a);
    for (i = h[a]; i; i = node[i].n) {
      b = node[i].b;
      tag[b] = 1;
    }
  }
  vec.pop_back();
}
int main() {
  int n, m, k;
  cin >> n >> m;
  sq = sqrt(n - 1) + 1;
  for (int i = 1; i <= m; i++) {
    int u, v;
    cin >> u >> v;
    cr(u, v);
    cr(v, u);
  }
  dep[1] = 1;
  dfs(1);
  cout << "1" << endl;
  for (int i = 0; i < sq; i++) cout << ans[i] << " ";
  cout << endl;
  return 0;
}
