#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 100;
const long long inf = 2e18, mod = 1e9 + 7;
int n, m, h[maxn], sq;
vector<int> graph[maxn], ans, path;
bool visited[maxn], mark[maxn];
void printAndExit(int mode) {
  cout << mode << endl;
  if (mode == 2) {
    cout << ans.size() << endl;
  }
  for (int i : ans) {
    cout << i + 1 << ' ';
  }
  exit(0);
}
void dfs(int u, int curh) {
  path.push_back(u);
  h[u] = curh;
  visited[u] = true;
  for (int i : graph[u]) {
    if (!visited[i]) {
      dfs(i, curh + 1);
    } else if (curh - h[i] + 1 >= sq) {
      for (int j = curh; j >= h[i]; j--) {
        ans.push_back(path[j]);
      }
      printAndExit(2);
    }
  }
  path.pop_back();
}
void getSet(int u) {
  visited[u] = true;
  for (int i : graph[u]) {
    if (!visited[i]) {
      getSet(i);
    }
  }
  if (!mark[u]) {
    mark[u] = true;
    for (int i : graph[u]) {
      mark[i] = true;
    }
    ans.push_back(u);
    if (ans.size() == sq) {
      printAndExit(1);
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  memset(h, -1, sizeof(h));
  cin >> n >> m;
  while (sq * sq < n) {
    sq++;
  }
  for (int i = 0; i < m; i++) {
    int u, v;
    cin >> u >> v;
    u--;
    v--;
    graph[u].push_back(v);
    graph[v].push_back(u);
  }
  dfs(0, 0);
  memset(visited, false, sizeof(visited));
  getSet(0);
}
