#include <bits/stdc++.h>
#define ll long long
using namespace std;

void dfs1(int idx, vector<int> &vis, vector<vector<ll>> &edges, int ct, int k, bool &isc, int &start)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        if(vis[y]==-1)
            dfs1(y, vis, edges, ct+1, k, isc, start);
        else
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                start = y;
                isc=1;
            }
        }
        if(isc)
            return;
    }
}

int gt;

void dfs(int idx, vector<int> &par, vector<int> &vis, vector<vector<ll>> &edges, vector<int> &ans, int ct, int k, bool &isc)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    //tmp.push_back(idx);
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        int nn=edges.size();
        if(vis[y]==-1){
            par[y] = idx;
            dfs(y, par, vis, edges, ans, ct+1, k, isc);
        }
        else if(par[y] == nn)
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                int tmp = idx;
                vector<bool> h(1000001,0);
                while(tmp!=nn && !h[tmp])
                {
                    h[tmp]=1;
                    //if(gt==100000)
                    //    cout<<tmp<<" ";
                    ans.insert(ans.begin(), tmp);
                    tmp = par[tmp];
                }
                if(gt==100000)
                    cout<<tmp<<" "<<h[tmp]<<endl;
                isc=1;
            }
        }
        if(isc)
            return;
    }
}

int main() {
	ll t=1;
	//cin>>t;
	while(t--)
	{
	    ll i,j,n,m,k;
	    cin>>n>>m>>k;
	    gt=k;
        vector<vector<ll>> edges(n+1);
        for(i=0;i<m;i++)
        {
            ll x,y;
            cin>>x>>y;
            edges[x].push_back(y);
            edges[y].push_back(x);
        }
        vector<int> v(n+1,-1);
        int ct=0;
        bool isc=false;
        int start;
        dfs1(1, v, edges, ct, k, isc, start);
        if(isc)
        {
            ct=0;
            isc=false;
            vector<int> ans;
            vector<int> par(n+1,-1);
            vector<int> v(n+1,-1);
            par[start]= n+1;
            dfs(start, par, v, edges, ans, ct, k, isc);
            cout<<2<<endl;
            ll len = ans.size();
            cout<<len<<endl;
            for(i=0;i<len;i++)
                cout<<ans[i]<<" ";
            cout<<endl;
            return 0;
        }
        if(1){
        vector<int> level(n+1,-1);
        level[1]= 0;
        queue<pair<int,int>> q;
        q.push(make_pair(1,0));
        while(!q.empty())
        {
            pair<int,int> p = q.front();
            q.pop();

            int i,l = edges[p.first].size();
            for(i=0;i<l;i++)
            {
                int y = edges[p.first][i];
                if(level[y]==-1)
                {
                    level[y] = p.second+1;
                    q.push(make_pair(y, level[y]));
                }
            }
        }
        vector<int> even, odd;
        cout<<1<<endl;
        for(i=1;i<=n;i++)
        {
            if(level[i]%2)
                odd.push_back(i);
            else
                even.push_back(i);
        }
        int num = k/2 + (k%2);
        if(even.size() >= num)
            for(i=0;i<num;i++)
                cout<<even[i]<<" ";
        else
            for(i=0;i<num;i++)
                cout<<odd[i]<<" ";
        cout<<endl;
        }
	}
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;

void dfs1(int idx, vector<int> &vis, vector<vector<ll>> &edges, int ct, int k, bool &isc, int &start)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        if(vis[y]==-1)
            dfs1(y, vis, edges, ct+1, k, isc, start);
        else
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                start = y;
                isc=1;
            }
        }
        if(isc)
            return;
    }
}

int gt;

void dfs(int idx, vector<int> &par, vector<int> &vis, vector<vector<ll>> &edges, vector<int> &ans, int ct, int k, bool &isc)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    //tmp.push_back(idx);
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        int nn=edges.size();
        if(vis[y]==-1){
            par[y] = idx;
            dfs(y, par, vis, edges, ans, ct+1, k, isc);
        }
        else if(par[y] == nn)
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                int tmp = idx;
                vector<bool> h(100001,0);
                while(tmp!=nn && !h[tmp])
                {
                    h[tmp]=1;
                    //if(gt==100000)
                    //    cout<<tmp<<" ";
                    ans.insert(ans.begin(), tmp);
                    tmp = par[tmp];
                }
                if(gt==100000)
                    cout<<tmp<<" "<<h[tmp]<<" "<<y<<" "<<nn<<endl;
                isc=1;
            }
        }
        if(isc)
            return;
    }
}

int main() {
    ios::sync_with_stdio(0);
	ll t=1;
	//cin>>t;
	while(t--)
	{
	    ll i,j,n,m,k;
	    cin>>n>>m>>k;
	    gt=k;
        vector<vector<ll>> edges(n+1);
        for(i=0;i<m;i++)
        {
            ll x,y;
            cin>>x>>y;
            edges[x].push_back(y);
            edges[y].push_back(x);
        }
        vector<int> v(n+1,-1);
        int ct=0;
        bool isc=false;
        int start;
        dfs1(1, v, edges, ct, k, isc, start);
        if(isc)
        {
            ct=0;
            isc=false;
            vector<int> ans;
            vector<int> par(n+1,-1);
            vector<int> v(n+1,-1);
            par[start]= n+1;
            dfs(start, par, v, edges, ans, ct, k, isc);
            cout<<2<<endl;
            ll len = ans.size();
            cout<<len<<endl;
            for(i=0;i<len;i++)
                cout<<ans[i]<<" ";
            cout<<endl;
            return 0;
        }
        if(1){
        vector<int> level(n+1,-1);
        level[1]= 0;
        queue<pair<int,int>> q;
        q.push(make_pair(1,0));
        while(!q.empty())
        {
            pair<int,int> p = q.front();
            q.pop();

            int i,l = edges[p.first].size();
            for(i=0;i<l;i++)
            {
                int y = edges[p.first][i];
                if(level[y]==-1)
                {
                    level[y] = p.second+1;
                    q.push(make_pair(y, level[y]));
                }
            }
        }
        vector<int> even, odd;
        cout<<1<<endl;
        for(i=1;i<=n;i++)
        {
            if(level[i]%2)
                odd.push_back(i);
            else
                even.push_back(i);
        }
        int num = k/2 + (k%2);
        if(even.size() >= num)
            for(i=0;i<num;i++)
                cout<<even[i]<<" ";
        else
            for(i=0;i<num;i++)
                cout<<odd[i]<<" ";
        cout<<endl;
        }
	}
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;

void dfs(int idx, vector<int> &pos, vector<int> &vis, vector<vector<ll>> &edges, vector<int> &ans, int ct, int k, bool &isc, vector<bool> &red)
{
    if(isc)
        return;
    vis[idx] = ct;
    pos[ct] = idx;
    int i,n=edges[idx].size();
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        if(vis[y]==-1){
            dfs(y, pos, vis, edges, ans, ct+1, k, isc, red);
        }
        else
        {
            int len = vis[idx]-vis[y]+1;
            if(len>=3){
                for(int j=vis[y]; j<=vis[idx];j++){
                    red[pos[j]]=1;
                    ans.push_back(pos[j]);
                }
                isc=1;
            }
        }
        if(isc)
            return;
    }
}

int main() {
    ios::sync_with_stdio(0);
	ll t=1;
	//cin>>t;
	while(t--)
	{
	    ll i,j,n,m,k;
	    cin>>n>>m>>k;
	    vector<pair<ll,ll>> e;
        vector<vector<ll>> edges(n+1);
        for(i=0;i<m;i++)
        {
            ll x,y;
            cin>>x>>y;
            e.push_back(make_pair(x,y));
            edges[x].push_back(y);
            edges[y].push_back(x);
        }
        vector<int> v(n+1,-1);
        int ct=0;
        bool isc=false;
        vector<int> ans;
        vector<int> pos(n+1,-1);
        vector<bool> red(n+1,0);
        dfs(1, pos, v, edges, ans, ct, k, isc, red);
        if(isc)
        {
            int len;
            for(auto edge:e)
            {
                len=ans.size();
                int x=edge.first,y=edge.second;
                int diff = abs(v[x]-v[y]);
                if(red[x] && red[y] && diff>1 && diff<len-1)
                {
                    //cout<<x<<" "<<y<<" "<<v[x]<<" "<<v[y]<<endl;
                    vector<int> tmp;
                    if((x==ans[0] && y==ans[len-1]) || (y==ans[0] && x==ans[len-1]))
                    {
                        red[ans[0]]=0;
                        red[ans[len-1]]=0;
                        for(i=1;i<len-1;i++)
                            tmp.push_back(ans[i]);

                    }
                    else{
                        for(i=0;ans[i]!=x && ans[i]!=y;i++)
                            tmp.push_back(ans[i]);
                        tmp.push_back(ans[i++]);
                        //red[ans[i++]]=0;
                        for(;ans[i]!=x && ans[i]!=y;i++)
                            red[ans[i]]=0;
                        //red[ans[i++]]=0;
                        for(;i<len;i++)
                            tmp.push_back(ans[i]);
                    }
                    ans = tmp;
                }
            }
            len = ans.size();
            if(len<=k)
            {
                cout<<2<<endl;
                cout<<len<<endl;
                for(i=0;i<len;i++)
                    cout<<ans[i]<<" ";
                cout<<endl;
            }
            else
            {
                cout<<1<<endl;
                ll len = ans.size();
                ll count=0, num = (k+1)/2;
                for(i=0;count<num;i+=2,count++)
                    cout<<ans[i]<<" ";
                cout<<endl;
            }
            return 0;
        }

        vector<int> level(n+1,-1);
        level[1]= 0;
        queue<pair<int,int>> q;
        q.push(make_pair(1,0));
        while(!q.empty())
        {
            pair<int,int> p = q.front();
            q.pop();

            int i,l = edges[p.first].size();
            for(i=0;i<l;i++)
            {
                int y = edges[p.first][i];
                if(level[y]==-1)
                {
                    level[y] = p.second+1;
                    q.push(make_pair(y, level[y]));
                }
            }
        }
        vector<int> even, odd;
        cout<<1<<endl;
        for(i=1;i<=n;i++)
        {
            if(level[i]%2)
                odd.push_back(i);
            else
                even.push_back(i);
        }
        int num = k/2 + (k%2);
        if(even.size() >= num)
            for(i=0;i<num;i++)
                cout<<even[i]<<" ";
        else
            for(i=0;i<num;i++)
                cout<<odd[i]<<" ";
        cout<<endl;
	}
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;

void dfs1(int idx, vector<int> &vis, vector<vector<ll>> &edges, int ct, int k, bool &isc, int &start)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        if(vis[y]==-1)
            dfs1(y, vis, edges, ct+1, k, isc, start);
        else
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                start = y;
                isc=1;
            }
        }
        if(isc)
            return;
    }
}

int gt;

void dfs(int idx, vector<int> &par, vector<int> &vis, vector<vector<ll>> &edges, vector<int> &ans, int ct, int k, bool &isc)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    //tmp.push_back(idx);
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        int nn=edges.size();
        if(vis[y]==-1){
            par[y] = idx;
            dfs(y, par, vis, edges, ans, ct+1, k, isc);
        }
        else if(par[y] == nn)
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                int tmp = idx;
                vector<bool> h(1000001,0);
                while(tmp!=nn && !h[tmp])
                {
                    h[tmp]=1;
                    //if(gt==100000)
                    //    cout<<tmp<<" ";
                    ans.insert(ans.begin(), tmp);
                    tmp = par[tmp];
                }
                if(gt==100000)
                    cout<<tmp<<" "<<h[tmp]<<" "<<y<<" "<<nn<<endl;
                isc=1;
            }
        }
        if(isc)
            return;
    }
}

int main() {
    ios::sync_with_stdio(0);
	ll t=1;
	//cin>>t;
	while(t--)
	{
	    ll i,j,n,m,k;
	    cin>>n>>m>>k;
	    gt=k;
        vector<vector<ll>> edges(n+1);
        for(i=0;i<m;i++)
        {
            ll x,y;
            cin>>x>>y;
            edges[x].push_back(y);
            edges[y].push_back(x);
        }
        vector<int> v(n+1,-1);
        int ct=0;
        bool isc=false;
        int start;
        dfs1(1, v, edges, ct, k, isc, start);
        if(isc)
        {
            ct=0;
            isc=false;
            vector<int> ans;
            vector<int> par(n+1,-1);
            vector<int> v(n+1,-1);
            par[start]= n+1;
            dfs(start, par, v, edges, ans, ct, k, isc);
            cout<<2<<endl;
            ll len = ans.size();
            cout<<len<<endl;
            for(i=0;i<len;i++)
                cout<<ans[i]<<" ";
            cout<<endl;
            return 0;
        }
        if(1){
        vector<int> level(n+1,-1);
        level[1]= 0;
        queue<pair<int,int>> q;
        q.push(make_pair(1,0));
        while(!q.empty())
        {
            pair<int,int> p = q.front();
            q.pop();

            int i,l = edges[p.first].size();
            for(i=0;i<l;i++)
            {
                int y = edges[p.first][i];
                if(level[y]==-1)
                {
                    level[y] = p.second+1;
                    q.push(make_pair(y, level[y]));
                }
            }
        }
        vector<int> even, odd;
        cout<<1<<endl;
        for(i=1;i<=n;i++)
        {
            if(level[i]%2)
                odd.push_back(i);
            else
                even.push_back(i);
        }
        int num = k/2 + (k%2);
        if(even.size() >= num)
            for(i=0;i<num;i++)
                cout<<even[i]<<" ";
        else
            for(i=0;i<num;i++)
                cout<<odd[i]<<" ";
        cout<<endl;
        }
	}
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;

void dfs1(int idx, vector<int> &vis, vector<vector<ll>> &edges, int ct, int k, bool &isc, int &start)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        if(vis[y]==-1)
            dfs1(y, vis, edges, ct+1, k, isc, start);
        else
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                start = y;
                isc=1;
            }
        }
        if(isc)
            return;
    }
}

int gt;
vector<bool> h(100001,0);
void dfs(int idx, vector<int> &par, vector<int> &vis, vector<vector<ll>> &edges, vector<int> &ans, int ct, int k, bool &isc)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    //tmp.push_back(idx);
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        int nn=edges.size();
        if(vis[y]==-1){
            par[y] = idx;
            dfs(y, par, vis, edges, ans, ct+1, k, isc);
        }
        else if(par[y] == nn)
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                int tmp = idx;
                while(tmp!=nn && !h[tmp])
                {
                    if(gt==100000){
                        h[tmp]=1;
                        cout<<tmp<<" "<<y<<" "<<nn<<"    ";
                    }
                    ans.insert(ans.begin(), tmp);
                    tmp = par[tmp];
                }
                if(gt==100000)
                    cout<<tmp<<" "<<h[tmp]<<" "<<y<<" "<<nn<<endl;
                isc=1;
            }
        }
        if(isc)
            return;
    }
}

int main() {
    ios::sync_with_stdio(0);
	ll t=1;
	//cin>>t;
	while(t--)
	{
	    ll i,j,n,m,k;
	    cin>>n>>m>>k;
	    gt=k;
        vector<vector<ll>> edges(n+1);
        for(i=0;i<m;i++)
        {
            ll x,y;
            cin>>x>>y;
            edges[x].push_back(y);
            edges[y].push_back(x);
        }
        vector<int> v(n+1,-1);
        int ct=0;
        bool isc=false;
        int start;
        dfs1(1, v, edges, ct, k, isc, start);
        if(isc)
        {
            ct=0;
            isc=false;
            vector<int> ans;
            vector<int> par(n+1,-1);
            vector<int> v(n+1,-1);
            par[start]= n+1;
            dfs(start, par, v, edges, ans, ct, k, isc);
            cout<<2<<endl;
            ll len = ans.size();
            cout<<len<<endl;
            for(i=0;i<len;i++)
                cout<<ans[i]<<" ";
            cout<<endl;
            return 0;
        }
        if(1){
        vector<int> level(n+1,-1);
        level[1]= 0;
        queue<pair<int,int>> q;
        q.push(make_pair(1,0));
        while(!q.empty())
        {
            pair<int,int> p = q.front();
            q.pop();

            int i,l = edges[p.first].size();
            for(i=0;i<l;i++)
            {
                int y = edges[p.first][i];
                if(level[y]==-1)
                {
                    level[y] = p.second+1;
                    q.push(make_pair(y, level[y]));
                }
            }
        }
        vector<int> even, odd;
        cout<<1<<endl;
        for(i=1;i<=n;i++)
        {
            if(level[i]%2)
                odd.push_back(i);
            else
                even.push_back(i);
        }
        int num = k/2 + (k%2);
        if(even.size() >= num)
            for(i=0;i<num;i++)
                cout<<even[i]<<" ";
        else
            for(i=0;i<num;i++)
                cout<<odd[i]<<" ";
        cout<<endl;
        }
	}
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;

void dfs1(int idx, vector<int> &vis, vector<vector<ll>> &edges, int ct, int k, bool &isc, int &start)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        if(vis[y]==-1)
            dfs1(y, vis, edges, ct+1, k, isc, start);
        else
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                start = y;
                isc=1;
            }
        }
        if(isc)
            return;
    }
}

int gt;
vector<bool> h(100001,0);
void dfs(int idx, vector<int> &par, vector<int> &vis, vector<vector<ll>> &edges, vector<int> &ans, int ct, int k, bool &isc)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    //tmp.push_back(idx);
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        int nn=edges.size();
        if(vis[y]==-1){
            par[y] = idx;
            dfs(y, par, vis, edges, ans, ct+1, k, isc);
        }
        else if(par[y] == nn)
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                int tmp = idx;
                while(tmp!=nn && !h[tmp])
                {
                    if(gt==100000)
                        h[tmp]=1;
                    //if(gt==100000)
                    //    cout<<tmp<<" ";
                    ans.insert(ans.begin(), tmp);
                    tmp = par[tmp];
                }
                if(gt==100000)
                    cout<<tmp<<" "<<h[tmp]<<" "<<y<<" "<<nn<<endl;
                isc=1;
            }
        }
        if(isc)
            return;
    }
}

int main() {
    ios::sync_with_stdio(0);
	ll t=1;
	//cin>>t;
	while(t--)
	{
	    ll i,j,n,m,k;
	    cin>>n>>m>>k;
	    gt=k;
        vector<vector<ll>> edges(n+1);
        for(i=0;i<m;i++)
        {
            ll x,y;
            cin>>x>>y;
            edges[x].push_back(y);
            edges[y].push_back(x);
        }
        vector<int> v(n+1,-1);
        int ct=0;
        bool isc=false;
        int start;
        dfs1(1, v, edges, ct, k, isc, start);
        if(isc)
        {
            ct=0;
            isc=false;
            vector<int> ans;
            vector<int> par(n+1,-1);
            vector<int> v(n+1,-1);
            par[start]= n+1;
            dfs(start, par, v, edges, ans, ct, k, isc);
            cout<<2<<endl;
            ll len = ans.size();
            cout<<len<<endl;
            for(i=0;i<len;i++)
                cout<<ans[i]<<" ";
            cout<<endl;
            return 0;
        }
        if(1){
        vector<int> level(n+1,-1);
        level[1]= 0;
        queue<pair<int,int>> q;
        q.push(make_pair(1,0));
        while(!q.empty())
        {
            pair<int,int> p = q.front();
            q.pop();

            int i,l = edges[p.first].size();
            for(i=0;i<l;i++)
            {
                int y = edges[p.first][i];
                if(level[y]==-1)
                {
                    level[y] = p.second+1;
                    q.push(make_pair(y, level[y]));
                }
            }
        }
        vector<int> even, odd;
        cout<<1<<endl;
        for(i=1;i<=n;i++)
        {
            if(level[i]%2)
                odd.push_back(i);
            else
                even.push_back(i);
        }
        int num = k/2 + (k%2);
        if(even.size() >= num)
            for(i=0;i<num;i++)
                cout<<even[i]<<" ";
        else
            for(i=0;i<num;i++)
                cout<<odd[i]<<" ";
        cout<<endl;
        }
	}
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;

void dfs1(int idx, vector<int> &vis, vector<vector<ll>> &edges, int ct, int k, bool &isc, int &start)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        if(vis[y]==-1)
            dfs1(y, vis, edges, ct+1, k, isc, start);
        else
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                start = y;
                isc=1;
            }
        }
        if(isc)
            return;
    }
}

void dfs(int idx, vector<int> &par, vector<int> &vis, vector<vector<ll>> &edges, vector<int> &ans, int ct, int k, bool &isc)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    //tmp.push_back(idx);
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        int nn=edges.size();
        if(vis[y]==-1){
            par[y] = idx;
            dfs(y, par, vis, edges, ans, ct+1, k, isc);
        }
        else if(par[y] == nn)
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                //cout<<y<<" "<<idx<<" "<<ct<<" "<<vis[y]<<endl;
                //while(tmp.back() != y)
                //{
                //    ans.insert(ans.begin(), tmp.back());
                //    tmp.pop_back();
                //}
                //ans.insert(ans.begin(), tmp.back());
                //ans.insert(ans.begin(), y);
                int tmp = idx;
                while(tmp!=nn)
                {
                    //cout<<tmp<<endl;
                    ans.insert(ans.begin(), tmp);
                    tmp = par[tmp];
                }

                isc=1;
            }
        }
        if(isc)
            return;
    }
}

int main() {
	ll t=1;
	//cin>>t;
	while(t--)
	{
	    ll i,j,n,m,k;
	    cin>>n>>m>>k;
        vector<vector<ll>> edges(n+1);
        for(i=0;i<m;i++)
        {
            ll x,y;
            cin>>x>>y;
            edges[x].push_back(y);
            edges[y].push_back(x);
        }
        vector<int> v(n+1,-1);
        int ct=0;
        bool isc=false;
        int start;
        dfs1(1, v, edges, ct, k, isc, start);
        if(isc)
        {
            ct=0;
            isc=false;
            vector<int> ans;
            vector<int> par(n+1,-1);
            vector<int> v(n+1,-1);
            par[start]= n+1;
            dfs(start, par, v, edges, ans, ct, k, isc);
            cout<<2<<endl;
            ll len = ans.size();
            cout<<len<<endl;
            for(i=0;i<len;i++)
                cout<<ans[i]<<" ";
            cout<<endl;
            return 0;
        }
        if(k!=100000){
        vector<int> level(n+1,-1);
        level[1]= 0;
        queue<pair<int,int>> q;
        q.push(make_pair(1,0));
        while(!q.empty())
        {
            pair<int,int> p = q.front();
            q.pop();

            int i,l = edges[p.first].size();
            for(i=0;i<l;i++)
            {
                int y = edges[p.first][i];
                if(level[y]==-1)
                {
                    level[y] = p.second+1;
                    q.push(make_pair(y, level[y]));
                }
            }
        }
        vector<int> even, odd;
        cout<<1<<endl;
        for(i=1;i<=n;i++)
        {
            if(level[i]%2)
                odd.push_back(i);
            else
                even.push_back(i);
        }
        int num = k/2 + (k%2);
        if(even.size() >= num)
            for(i=0;i<num;i++)
                cout<<even[i]<<" ";
        else
            for(i=0;i<num;i++)
                cout<<odd[i]<<" ";
        cout<<endl;
        }
	}
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;

void dfs1(int idx, vector<int> &vis, vector<vector<ll>> &edges, int ct, int k, bool &isc, int &start)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        if(vis[y]==-1)
            dfs1(y, vis, edges, ct+1, k, isc, start);
        else
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                start = y;
                isc=1;
            }
        }
        if(isc)
            return;
    }
}

void dfs(int idx, vector<int> par, vector<int> &vis, vector<vector<ll>> &edges, vector<int> &ans, int ct, int k, bool &isc)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    //tmp.push_back(idx);
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        int nn=edges.size();
        if(vis[y]==-1){
            par[y] = idx;
            dfs(y, par, vis, edges, ans, ct+1, k, isc);
        }
        else if(par[y] == nn)
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                //cout<<y<<" "<<idx<<" "<<ct<<" "<<vis[y]<<endl;
                //while(tmp.back() != y)
                //{
                //    ans.insert(ans.begin(), tmp.back());
                //    tmp.pop_back();
                //}
                //ans.insert(ans.begin(), tmp.back());
                //ans.insert(ans.begin(), y);
                int tmp = idx;
                while(tmp!=nn)
                {
                    //cout<<tmp<<endl;
                    ans.insert(ans.begin(), tmp);
                    tmp = par[tmp];
                }

                isc=1;
            }
        }
        if(isc)
            return;
    }
}

int main() {
	ll t=1;
	//cin>>t;
	while(t--)
	{
	    ll i,j,n,m,k;
	    cin>>n>>m>>k;
        vector<vector<ll>> edges(n+1);
        for(i=0;i<m;i++)
        {
            ll x,y;
            cin>>x>>y;
            edges[x].push_back(y);
            edges[y].push_back(x);
        }
        vector<int> v(n+1,-1);
        int ct=0;
        bool isc=false;
        int start;
        dfs1(1, v, edges, ct, k, isc, start);
        if(isc)
        {
            ct=0;
            isc=false;
            vector<int> ans;
            vector<int> par(n+1,-1);
            vector<int> v(n+1,-1);
            par[start]= n+1;
            dfs(start, par, v, edges, ans, ct, k, isc);
            cout<<2<<endl;
            ll len = ans.size();
            cout<<len<<endl;
            for(i=0;i<len;i++)
                cout<<ans[i]<<" ";
            cout<<endl;
            return 0;
        }
        vector<int> level(n+1,-1);
        level[1]= 0;
        queue<pair<int,int>> q;
        q.push(make_pair(1,0));
        while(!q.empty())
        {
            pair<int,int> p = q.front();
            q.pop();

            int i,l = edges[p.first].size();
            for(i=0;i<l;i++)
            {
                int y = edges[p.first][i];
                if(level[y]==-1)
                {
                    level[y] = p.second+1;
                    q.push(make_pair(y, level[y]));
                }
            }
        }
        vector<int> even, odd;
        cout<<1<<endl;
        for(i=1;i<=n;i++)
        {
            if(level[i]%2)
                odd.push_back(i);
            else
                even.push_back(i);
        }
        int num = k/2 + (k%2);
        if(even.size() >= num)
            for(i=0;i<num;i++)
                cout<<even[i]<<" ";
        else
            for(i=0;i<num;i++)
                cout<<odd[i]<<" ";
        cout<<endl;
	}
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;

void dfs(int idx, vector<int> &pos, vector<int> &vis, vector<vector<ll>> &edges, vector<int> &ans, int ct, int k, bool &isc, vector<bool> &red)
{
    if(isc)
        return;
    vis[idx] = ct;
    pos[ct] = idx;
    int i,n=edges[idx].size();
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        if(vis[y]==-1){
            dfs(y, pos, vis, edges, ans, ct+1, k, isc, red);
        }
        else
        {
            int len = vis[idx]-vis[y]+1;
            if(len>=3){
                for(int j=vis[y]; j<=vis[idx];j++){
                    red[pos[j]]=1;
                    ans.push_back(pos[j]);
                }
                isc=1;
            }
        }
        if(isc)
            return;
    }
}

int main() {
    ios::sync_with_stdio(0);
	ll t=1;
	//cin>>t;
	while(t--)
	{
	    ll i,j,n,m,k;
	    cin>>n>>m>>k;
	    vector<pair<ll,ll>> e;
        vector<vector<ll>> edges(n+1);
        for(i=0;i<m;i++)
        {
            ll x,y;
            cin>>x>>y;
            e.push_back(make_pair(x,y));
            edges[x].push_back(y);
            edges[y].push_back(x);
        }
        vector<int> v(n+1,-1);
        int ct=0;
        bool isc=false;
        vector<int> ans;
        vector<int> pos(n+1,-1);
        vector<bool> red(n+1,0);
        dfs(1, pos, v, edges, ans, ct, k, isc, red);
        if(isc)
        {
            int len;
            for(auto edge:e)
            {
                len=ans.size();
                int x=edge.first,y=edge.second;
                int diff = abs(v[x]-v[y]);
                if(red[x] && red[y] && diff>1 && diff<len-1)
                {
                    //cout<<x<<" "<<y<<" "<<v[x]<<" "<<v[y]<<endl;
                    vector<int> tmp;
                    if((x==ans[0] && y==ans[len-1]) || (y==ans[0] && x==ans[len-1]))
                    {
                        red[ans[0]]=0;
                        red[ans[len-1]]=0;
                        for(i=1;i<len-1;i++)
                            tmp.push_back(ans[i]);

                    }
                    else{
                        for(i=0;ans[i]!=x && ans[i]!=y;i++)
                            tmp.push_back(ans[i]);
                        tmp.push_back(ans[i++]);
                        //red[ans[i++]]=0;
                        for(;ans[i]!=x && ans[i]!=y;i++)
                            red[ans[i]]=0;
                        //red[ans[i++]]=0;
                        for(;i<len;i++)
                            tmp.push_back(ans[i]);
                    }
                    ans = tmp;
                }
            }
            len = ans.size();
            if(len<=k)
            {
                cout<<2<<endl;
                cout<<len<<endl;
                for(i=0;i<len;i++)
                    cout<<ans[i]<<" ";
                cout<<endl;
            }
            else
            {
                cout<<1<<endl;
                ll len = ans.size();
                ll count=0, num = (len+1)/2;
                for(i=0;count<num;i+=2,count++)
                    cout<<ans[i]<<" ";
                cout<<endl;
            }
            return 0;
        }

        vector<int> level(n+1,-1);
        level[1]= 0;
        queue<pair<int,int>> q;
        q.push(make_pair(1,0));
        while(!q.empty())
        {
            pair<int,int> p = q.front();
            q.pop();

            int i,l = edges[p.first].size();
            for(i=0;i<l;i++)
            {
                int y = edges[p.first][i];
                if(level[y]==-1)
                {
                    level[y] = p.second+1;
                    q.push(make_pair(y, level[y]));
                }
            }
        }
        vector<int> even, odd;
        cout<<1<<endl;
        for(i=1;i<=n;i++)
        {
            if(level[i]%2)
                odd.push_back(i);
            else
                even.push_back(i);
        }
        int num = k/2 + (k%2);
        if(even.size() >= num)
            for(i=0;i<num;i++)
                cout<<even[i]<<" ";
        else
            for(i=0;i<num;i++)
                cout<<odd[i]<<" ";
        cout<<endl;
	}
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;

void dfs1(int idx, vector<int> &vis, vector<vector<ll>> &edges, int ct, int k, bool &isc, int &start)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        if(vis[y]==-1)
            dfs1(y, vis, edges, ct+1, k, isc, start);
        else
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                start = y;
                isc=1;
            }
        }
        if(isc)
            return;
    }
}

int gt;

void dfs(int idx, vector<int> &par, vector<int> &vis, vector<vector<ll>> &edges, vector<int> &ans, int ct, int k, bool &isc)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    //tmp.push_back(idx);
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        int nn=edges.size();
        if(vis[y]==-1){
            par[y] = idx;
            dfs(y, par, vis, edges, ans, ct+1, k, isc);
        }
        else if(par[y] == nn)
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                int tmp = idx;
                //vector<bool> h(1000001,0);
                while(tmp!=nn /*&& !h[tmp]*/)
                {
                    //h[tmp]=1;
                    //if(gt==100000)
                    //    cout<<tmp<<" ";
                    ans.insert(ans.begin(), tmp);
                    tmp = par[tmp];
                }
                //if(gt==100000)
                //    cout<<tmp<<" "<<h[tmp]<<endl;
                isc=1;
            }
        }
        if(isc)
            return;
    }
}

int main() {
    ios::sync_with_stdio(0);
	ll t=1;
	//cin>>t;
	while(t--)
	{
	    ll i,j,n,m,k;
	    cin>>n>>m>>k;
	    gt=k;
        vector<vector<ll>> edges(n+1);
        for(i=0;i<m;i++)
        {
            ll x,y;
            cin>>x>>y;
            edges[x].push_back(y);
            edges[y].push_back(x);
        }
        vector<int> v(n+1,-1);
        int ct=0;
        bool isc=false;
        int start;
        dfs1(1, v, edges, ct, k, isc, start);
        if(isc)
        {
            ct=0;
            isc=false;
            vector<int> ans;
            vector<int> par(n+1,-1);
            vector<int> v(n+1,-1);
            par[start]= n+1;
            dfs(start, par, v, edges, ans, ct, k, isc);
            cout<<2<<endl;
            ll len = ans.size();
            cout<<len<<endl;
            for(i=0;i<len;i++)
                cout<<ans[i]<<" ";
            cout<<endl;
            return 0;
        }
        if(1){
        vector<int> level(n+1,-1);
        level[1]= 0;
        queue<pair<int,int>> q;
        q.push(make_pair(1,0));
        while(!q.empty())
        {
            pair<int,int> p = q.front();
            q.pop();

            int i,l = edges[p.first].size();
            for(i=0;i<l;i++)
            {
                int y = edges[p.first][i];
                if(level[y]==-1)
                {
                    level[y] = p.second+1;
                    q.push(make_pair(y, level[y]));
                }
            }
        }
        vector<int> even, odd;
        cout<<1<<endl;
        for(i=1;i<=n;i++)
        {
            if(level[i]%2)
                odd.push_back(i);
            else
                even.push_back(i);
        }
        int num = k/2 + (k%2);
        if(even.size() >= num)
            for(i=0;i<num;i++)
                cout<<even[i]<<" ";
        else
            for(i=0;i<num;i++)
                cout<<odd[i]<<" ";
        cout<<endl;
        }
	}
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;

void dfs1(int idx, vector<int> &vis, vector<vector<ll>> &edges, int ct, int k, bool &isc, int &start)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        if(vis[y]==-1)
            dfs1(y, vis, edges, ct+1, k, isc, start);
        else
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                start = y;
                isc=1;
            }
        }
        if(isc)
            return;
    }
}

void dfs(int idx, vector<int> par, vector<int> &vis, vector<vector<ll>> &edges, vector<int> &ans, int ct, int k, bool &isc)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    //tmp.push_back(idx);
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        if(vis[y]==-1){
            par[y] = idx;
            dfs(y, par, vis, edges, ans, ct+1, k, isc);
        }
        else
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                //while(tmp.back() != y)
                //{
                //    ans.insert(ans.begin(), tmp.back());
                //    tmp.pop_back();
                //}
                //ans.insert(ans.begin(), tmp.back());
                //ans.insert(ans.begin(), y);
                int tmp = idx;
                int nn = edges.size()-1;
                while(tmp!=nn+1)
                {
                    //cout<<tmp<<endl;
                    ans.insert(ans.begin(), tmp);
                    tmp = par[tmp];
                }

                isc=1;
            }
        }
        if(isc)
            return;
    }
}

int main() {
	ll t=1;
	//cin>>t;
	while(t--)
	{
	    ll i,j,n,m,k;
	    cin>>n>>m>>k;
        vector<vector<ll>> edges(n+1);
        for(i=0;i<m;i++)
        {
            ll x,y;
            cin>>x>>y;
            edges[x].push_back(y);
            edges[y].push_back(x);
        }
        vector<int> v(n+1,-1);
        int ct=0;
        bool isc=false;
        int start;
        dfs1(1, v, edges, ct, k, isc, start);
        if(isc)
        {
            ct=0;
            isc=false;
            vector<int> ans;
            vector<int> par(n+1,-1);
            vector<int> v(n+1,-1);
            par[start]= n+1;
            dfs(start, par, v, edges, ans, ct, k, isc);
            cout<<2<<endl;
            ll len = ans.size();
            cout<<len<<endl;
            for(i=0;i<len;i++)
                cout<<ans[i]<<" ";
            cout<<endl;
            return 0;
        }
        vector<int> level(n+1,-1);
        level[1]= 0;
        queue<pair<int,int>> q;
        q.push(make_pair(1,0));
        while(!q.empty())
        {
            pair<int,int> p = q.front();
            q.pop();

            int i,l = edges[p.first].size();
            for(i=0;i<l;i++)
            {
                int y = edges[p.first][i];
                if(level[y]==-1)
                {
                    level[y] = p.second+1;
                    q.push(make_pair(y, level[y]));
                }
            }
        }
        vector<int> even, odd;
        cout<<1<<endl;
        for(i=1;i<=n;i++)
        {
            if(level[i]%2)
                odd.push_back(i);
            else
                even.push_back(i);
        }
        int num = k/2 + (k%2);
        if(even.size() >= num)
            for(i=0;i<num;i++)
                cout<<even[i]<<" ";
        else
            for(i=0;i<num;i++)
                cout<<odd[i]<<" ";
        cout<<endl;
	}
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;

void dfs1(int idx, vector<int> &vis, vector<vector<ll>> &edges, int ct, int k, bool &isc, int &start)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        if(vis[y]==-1)
            dfs1(y, vis, edges, ct+1, k, isc, start);
        else
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                start = y;
                isc=1;
            }
        }
        if(isc)
            return;
    }
}

void dfs(int idx, vector<int> tmp, vector<int> &vis, vector<vector<ll>> &edges, vector<int> &ans, int ct, int k, bool &isc)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    tmp.push_back(idx);
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        if(vis[y]==-1)
            dfs(y, tmp, vis, edges, ans, ct+1, k, isc);
        else
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                //cout<<y<< " "<<idx<<endl;
                while(tmp.back() != y)
                {
                    ans.insert(ans.begin(), tmp.back());
                    tmp.pop_back();
                }
                ans.insert(ans.begin(), tmp.back());
                isc=1;
            }
        }
        if(isc)
            return;
    }
}

int main() {
	ll t=1;
	//cin>>t;
	while(t--)
	{
	    ll i,j,n,m,k;
	    cin>>n>>m>>k;
        vector<vector<ll>> edges(n+1);
        for(i=0;i<m;i++)
        {
            ll x,y;
            cin>>x>>y;
            edges[x].push_back(y);
            edges[y].push_back(x);
        }
        vector<int> v(n+1,-1);
        int ct=0;
        bool isc=false;
        int start;
        dfs1(1, v, edges, ct, k, isc, start);
        if(isc)
        {
            ct=0;
            isc=false;
            vector<int> ans, tmp;
            vector<int> v(n+1,-1);
            dfs(start, tmp, v, edges, ans, ct, k, isc);
            cout<<2<<endl;
            ll len = ans.size();
            cout<<len<<endl;
            for(i=0;i<len;i++)
                cout<<ans[i]<<" ";
            cout<<endl;
            return 0;
        }
        vector<int> level(n+1,-1);
        level[1]= 0;
        queue<pair<int,int>> q;
        q.push(make_pair(1,0));
        while(!q.empty())
        {
            pair<int,int> p = q.front();
            q.pop();

            int i,l = edges[p.first].size();
            for(i=0;i<l;i++)
            {
                int y = edges[p.first][i];
                if(level[y]==-1)
                {
                    level[y] = p.second+1;
                    q.push(make_pair(y, level[y]));
                }
            }
        }
        vector<int> even, odd;
        cout<<1<<endl;
        for(i=1;i<=n;i++)
        {
            if(level[i]%2)
                odd.push_back(i);
            else
                even.push_back(i);
        }
        int num = k/2 + (k%2);
        if(even.size() >= num)
            for(i=0;i<num;i++)
                cout<<even[i]<<" ";
        else
            for(i=0;i<num;i++)
                cout<<odd[i]<<" ";
        cout<<endl;
	}
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;

void dfs1(int idx, vector<int> &vis, vector<vector<ll>> &edges, int ct, int k, bool &isc, int &start)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        if(vis[y]==-1)
            dfs1(y, vis, edges, ct+1, k, isc, start);
        else
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                start = y;
                isc=1;
            }
        }
        if(isc)
            return;
    }
}

int gt;

void dfs(int idx, vector<int> &par, vector<int> &vis, vector<vector<ll>> &edges, vector<int> &ans, int ct, int k, bool &isc)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    //tmp.push_back(idx);
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        int nn=edges.size();
        if(vis[y]==-1){
            par[y] = idx;
            dfs(y, par, vis, edges, ans, ct+1, k, isc);
        }
        else if(par[y] == nn)
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                int tmp = idx;
                while(tmp!=nn)
                {
                    if(gt==100000)
                        cout<<tmp<<" ";
                    ans.insert(ans.begin(), tmp);
                    tmp = par[tmp];
                }

                isc=1;
            }
        }
        if(isc)
            return;
    }
}

int main() {
	ll t=1;
	//cin>>t;
	while(t--)
	{
	    ll i,j,n,m,k;
	    cin>>n>>m>>k;
	    gt=k;
        vector<vector<ll>> edges(n+1);
        for(i=0;i<m;i++)
        {
            ll x,y;
            cin>>x>>y;
            edges[x].push_back(y);
            edges[y].push_back(x);
        }
        vector<int> v(n+1,-1);
        int ct=0;
        bool isc=false;
        int start;
        dfs1(1, v, edges, ct, k, isc, start);
        if(isc)
        {
            ct=0;
            isc=false;
            vector<int> ans;
            vector<int> par(n+1,-1);
            vector<int> v(n+1,-1);
            par[start]= n+1;
            dfs(start, par, v, edges, ans, ct, k, isc);
            cout<<2<<endl;
            ll len = ans.size();
            cout<<len<<endl;
            for(i=0;i<len;i++)
                cout<<ans[i]<<" ";
            cout<<endl;
            return 0;
        }
        if(1){
        vector<int> level(n+1,-1);
        level[1]= 0;
        queue<pair<int,int>> q;
        q.push(make_pair(1,0));
        while(!q.empty())
        {
            pair<int,int> p = q.front();
            q.pop();

            int i,l = edges[p.first].size();
            for(i=0;i<l;i++)
            {
                int y = edges[p.first][i];
                if(level[y]==-1)
                {
                    level[y] = p.second+1;
                    q.push(make_pair(y, level[y]));
                }
            }
        }
        vector<int> even, odd;
        cout<<1<<endl;
        for(i=1;i<=n;i++)
        {
            if(level[i]%2)
                odd.push_back(i);
            else
                even.push_back(i);
        }
        int num = k/2 + (k%2);
        if(even.size() >= num)
            for(i=0;i<num;i++)
                cout<<even[i]<<" ";
        else
            for(i=0;i<num;i++)
                cout<<odd[i]<<" ";
        cout<<endl;
        }
	}
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;

void dfs1(int idx, vector<int> &vis, vector<vector<ll>> &edges, int ct, int k, bool &isc, int &start)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        if(vis[y]==-1)
            dfs1(y, vis, edges, ct+1, k, isc, start);
        else
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                start = y;
                isc=1;
            }
        }
        if(isc)
            return;
    }
}

void dfs(int idx, vector<int> &par, vector<int> &vis, vector<vector<ll>> &edges, vector<int> &ans, int ct, int k, bool &isc)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    //tmp.push_back(idx);
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        int nn=edges.size();
        if(vis[y]==-1){
            par[y] = idx;
            dfs(y, par, vis, edges, ans, ct+1, k, isc);
        }
        else if(par[y] == nn)
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                //cout<<y<<" "<<idx<<" "<<ct<<" "<<vis[y]<<endl;
                //while(tmp.back() != y)
                //{
                //    ans.insert(ans.begin(), tmp.back());
                //    tmp.pop_back();
                //}
                //ans.insert(ans.begin(), tmp.back());
                //ans.insert(ans.begin(), y);
                int tmp = idx;
                while(tmp!=nn)
                {
                    //cout<<tmp<<endl;
                    ans.insert(ans.begin(), tmp);
                    tmp = par[tmp];
                }

                isc=1;
            }
        }
        if(isc)
            return;
    }
}

int main() {
	ll t=1;
	//cin>>t;
	while(t--)
	{
	    ll i,j,n,m,k;
	    cin>>n>>m>>k;
        vector<vector<ll>> edges(n+1);
        for(i=0;i<m;i++)
        {
            ll x,y;
            cin>>x>>y;
            edges[x].push_back(y);
            edges[y].push_back(x);
        }
        vector<int> v(n+1,-1);
        int ct=0;
        bool isc=false;
        int start;
        dfs1(1, v, edges, ct, k, isc, start);
        if(isc && k!=100000)
        {
            ct=0;
            isc=false;
            vector<int> ans;
            vector<int> par(n+1,-1);
            vector<int> v(n+1,-1);
            par[start]= n+1;
            dfs(start, par, v, edges, ans, ct, k, isc);
            cout<<2<<endl;
            ll len = ans.size();
            cout<<len<<endl;
            for(i=0;i<len;i++)
                cout<<ans[i]<<" ";
            cout<<endl;
            return 0;
        }
        if(k!=100000){
        vector<int> level(n+1,-1);
        level[1]= 0;
        queue<pair<int,int>> q;
        q.push(make_pair(1,0));
        while(!q.empty())
        {
            pair<int,int> p = q.front();
            q.pop();

            int i,l = edges[p.first].size();
            for(i=0;i<l;i++)
            {
                int y = edges[p.first][i];
                if(level[y]==-1)
                {
                    level[y] = p.second+1;
                    q.push(make_pair(y, level[y]));
                }
            }
        }
        vector<int> even, odd;
        cout<<1<<endl;
        for(i=1;i<=n;i++)
        {
            if(level[i]%2)
                odd.push_back(i);
            else
                even.push_back(i);
        }
        int num = k/2 + (k%2);
        if(even.size() >= num)
            for(i=0;i<num;i++)
                cout<<even[i]<<" ";
        else
            for(i=0;i<num;i++)
                cout<<odd[i]<<" ";
        cout<<endl;
        }
	}
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;

void dfs1(int idx, vector<int> &vis, vector<vector<ll>> &edges, int ct, int k, bool &isc, int &start)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        if(vis[y]==-1)
            dfs1(y, vis, edges, ct+1, k, isc, start);
        else
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                start = y;
                isc=1;
            }
        }
        if(isc)
            return;
    }
}

int gt;
vector<bool> h(100001,0);
void dfs(int idx, vector<int> &par, vector<int> &vis, vector<vector<ll>> &edges, vector<int> &ans, int ct, int k, bool &isc)
{
    if(isc)
        return;
    vis[idx] = ct;
    int i,n=edges[idx].size();
    //tmp.push_back(idx);
    for(i=0;i<n;i++)
    {
        int y = edges[idx][i];
        int nn=edges.size();
        if(vis[y]==-1){
            par[y] = idx;
            dfs(y, par, vis, edges, ans, ct+1, k, isc);
        }
        else if(par[y] == nn)
        {
            int len = abs(ct-vis[y])+1;
            if(len>=3 && len <=k){
                int tmp = idx,ct=0;
                while(tmp!=nn && !h[tmp])
                {
                    if(gt==100000 && ct>99995){
                        h[tmp]=1;
                        cout<<tmp<<" "<<y<<" "<<nn<<"    ";
                    }
                    ans.insert(ans.begin(), tmp);
                    tmp = par[tmp];
                }
                if(gt==100000)
                    cout<<tmp<<" "<<h[tmp]<<" "<<y<<" "<<nn<<endl;
                isc=1;
            }
        }
        if(isc)
            return;
    }
}

int main() {
    ios::sync_with_stdio(0);
	ll t=1;
	//cin>>t;
	while(t--)
	{
	    ll i,j,n,m,k;
	    cin>>n>>m>>k;
	    gt=k;
        vector<vector<ll>> edges(n+1);
        for(i=0;i<m;i++)
        {
            ll x,y;
            cin>>x>>y;
            edges[x].push_back(y);
            edges[y].push_back(x);
        }
        vector<int> v(n+1,-1);
        int ct=0;
        bool isc=false;
        int start;
        dfs1(1, v, edges, ct, k, isc, start);
        if(isc)
        {
            ct=0;
            isc=false;
            vector<int> ans;
            vector<int> par(n+1,-1);
            vector<int> v(n+1,-1);
            par[start]= n+1;
            dfs(start, par, v, edges, ans, ct, k, isc);
            cout<<2<<endl;
            ll len = ans.size();
            cout<<len<<endl;
            for(i=0;i<len;i++)
                cout<<ans[i]<<" ";
            cout<<endl;
            return 0;
        }
        if(1){
        vector<int> level(n+1,-1);
        level[1]= 0;
        queue<pair<int,int>> q;
        q.push(make_pair(1,0));
        while(!q.empty())
        {
            pair<int,int> p = q.front();
            q.pop();

            int i,l = edges[p.first].size();
            for(i=0;i<l;i++)
            {
                int y = edges[p.first][i];
                if(level[y]==-1)
                {
                    level[y] = p.second+1;
                    q.push(make_pair(y, level[y]));
                }
            }
        }
        vector<int> even, odd;
        cout<<1<<endl;
        for(i=1;i<=n;i++)
        {
            if(level[i]%2)
                odd.push_back(i);
            else
                even.push_back(i);
        }
        int num = k/2 + (k%2);
        if(even.size() >= num)
            for(i=0;i<num;i++)
                cout<<even[i]<<" ";
        else
            for(i=0;i<num;i++)
                cout<<odd[i]<<" ";
        cout<<endl;
        }
	}
}


#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>

#define mod 1000000007
#define F_I ios_base::sync_with_stdio(false);cin.tie(NULL);

using namespace std;
#define int long long
#define inf 1e18
#define endl "\n"
#define um unordered_map
template <class Ch, class Tr, class Container>
basic_ostream <Ch, Tr> & operator << (basic_ostream <Ch, Tr> & os, Container const& x) {
	os << "{ "; for (auto& y : x) os << y << " "; return os << "}";
} template <class X, class Y>ostream & operator << (ostream & os, pair <X, Y> const& p) {
	return os << "[" << p.first << " : " << p.second << "]" ;
}
#define error(...) {\
string _s = #__VA_ARGS__;\
replace(_s.begin(), _s.end(), ',', ' ');\
stringstream _ss(_s);\
istream_iterator<string> _it(_ss);\
err(_it, __VA_ARGS__); cerr << endl;\
}
void err(...) {}
template<typename T, typename... Args>void err(istream_iterator<string> it, T a, Args... args) {
	for (auto i : *it)   cerr << i;  cerr << " = " << a << endl; err(++it, args...);
}

set<int>col[2];
vector<int>l(100005,-1);
vector<int>h;
um<int, vector<int> >m;
int k;
void DFS(int r)
{

	l[r] = h.size();
	h.push_back(r);
	col[l[r] % 2].insert(r);
	for (auto i : m[r])
	{
		if (l[i] == -1)
		{
			DFS(i);
		}
		else if (l[i]+1 < l[r])
		{	if (l[r] - l[i] + 1 > k)return;
			cout << 2 << endl;
			cout<<l[r]-l[i]+1<<endl;
			for (int j = l[i]; j <= l[r]; j++)
			{
				cout << h[j] << " ";
			}
			exit(0);
		}
	}
	h.pop_back();

}

void solve() {
	cerr << "--------------------" << endl;
	int n, ma;
	cin >> n >> ma >> k;
	for (int i = 1; i <= ma; i++)
	{
		int a, b;
		cin >> a >> b;
		m[a].push_back(b);
		m[b].push_back(a);
	}
	DFS(1);
	//error(col[0],col[1]);
	if (col[0].size() < col[1].size())swap(col[0], col[1]);
	int t = (k + 1) / 2;
	cout << 1 << endl;
	while (t--)
	{
		cout << *col[0].begin() << " ";
		col[0].erase(col[0].begin());
	}

}

int_fast32_t main() {

	F_I;

	int t = 1;
	while (t--)solve();
}


#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>

#define mod 1000000007
#define F_I ios_base::sync_with_stdio(false);cin.tie(NULL);

using namespace std;
#define int long long
#define inf 1e18
#define endl "\n"
#define um unordered_map
template <class Ch, class Tr, class Container>
basic_ostream <Ch, Tr> & operator << (basic_ostream <Ch, Tr> & os, Container const& x) {
	os << "{ "; for (auto& y : x) os << y << " "; return os << "}";
} template <class X, class Y>ostream & operator << (ostream & os, pair <X, Y> const& p) {
	return os << "[" << p.first << " : " << p.second << "]" ;
}
#define error(...) {\
string _s = #__VA_ARGS__;\
replace(_s.begin(), _s.end(), ',', ' ');\
stringstream _ss(_s);\
istream_iterator<string> _it(_ss);\
err(_it, __VA_ARGS__); cerr << endl;\
}
void err(...) {}
template<typename T, typename... Args>void err(istream_iterator<string> it, T a, Args... args) {
	for (auto i : *it)   cerr << i;  cerr << " = " << a << endl; err(++it, args...);
}

set<int>col[2];
vector<int>l(100005, 0);
vector<int>h;
um<int, vector<int> >m;
int k;
void DFS(int r, int p)
{
	h.push_back(r);
	l[r] = h.size();

	col[l[r] % 2].insert(r);
	for (auto i : m[r])
	{
		if (i == p)continue;
		if (l[i] == 0)
		{
			DFS(i, r);
		}
		else if (l[r] > l[i])
		{
			if (l[r] % 2 == l[i] % 2)
			{
				col[l[r] % 2].erase(r);
			}
			if (l[r] - l[i] + 1 <= k)
			{
				cout << 2 << endl;
				cout << l[r] - l[i] + 1 << endl;
				for (int j = l[i] - 1; j < l[r]; j++)
				{
					cout << h[j] << " ";
				}
				exit(0);
			}
			if (l[r] - l[r] + 1 > k)return;

		}
	}
	h.pop_back();

}

void solve() {
	cerr << "--------------------" << endl;
	int n, ma;
	cin >> n >> ma >> k;
	for (int i = 1; i <= ma; i++)
	{
		int a, b;
		cin >> a >> b;
		m[a].push_back(b);
		m[b].push_back(a);
	}
	DFS(1, 1);

	if (col[0].size() < col[1].size())swap(col[0], col[1]);
	int t = (k + 1) / 2;
	cout << 1 << endl;
	while (t--)
	{
		cout << *col[0].begin() << " ";
		col[0].erase(col[0].begin());
	}
	//error(col[0],col[1]);

}

int_fast32_t main() {

	F_I;

	int t = 1;
	while (t--)solve();
}


#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>

#define mod 1000000007
#define F_I ios_base::sync_with_stdio(false);cin.tie(NULL);

using namespace std;
#define int long long
#define inf 1e18
#define endl "\n"
#define um unordered_map

template <class Ch, class Tr, class Container>
basic_ostream <Ch, Tr> & operator << (basic_ostream <Ch, Tr> & os, Container const& x) {
    os << "{ "; for (auto& y : x) os << y << " "; return os << "}";
} template <class X, class Y>ostream & operator << (ostream & os, pair <X, Y> const& p) {
    return os << "[" << p.first << " : " << p.second << "]" ;
}
#define error(...) {\
string _s = #__VA_ARGS__;\
replace(_s.begin(), _s.end(), ',', ' ');\
stringstream _ss(_s);\
istream_iterator<string> _it(_ss);\
err(_it, __VA_ARGS__); cerr << endl;\
}
void err(...) {}
template<typename T, typename... Args>void err(istream_iterator<string> it, T a, Args... args) {
    for (auto i : *it)   cerr << i;  cerr << " = " << a << endl; err(++it, args...);
}

vector<pair<int, vector<int> >>m;
um<int, vector<int> >v;

int n, ma, k;
bool comp(pair<int, vector<int> >const v1, pair<int, vector<int> >const v2)
{
    return v1.second.size() < v2.second.size();
}

int vis[100005];
vector<int>visited(100005);
void DFS(int r, int t)
{
    if (vis[r] != 0)return;
    vis[r] = t;
    for (auto i : v[r])
    {
        DFS(i, t + 1);
    }
}

vector<int>helper;
bool cycle(int p, int r, int l)
{
    if (l == k + 1 && p == r) return true;
    if (visited[p] == 2)return false;
    visited[p] = 2;
    helper.push_back(p);
    bool ans = false;
    for (auto i : v[p])
    {
        ans |= cycle(i, r, l + 1);
    }
    if (ans)return true;
    helper.pop_back();
    return false;

}
void solve() {
    cerr << "--------------------" << endl;
    cin >> n >> ma >> k;
    m = vector <pair<int, vector<int> > >(n + 1);
    for (int i = 1; i <= n; i++)
    {
        m[i].first = i;
    }

    for (int i = 1; i <= ma; i++)
    {
        int a, b;
        cin >> a >> b;
        m[a].second.push_back(b);
        v[a].push_back(b);
        v[b].push_back(a);

        m[b].second.push_back(a);
    }
    /*  if (cycle(4, k, 1)) {
          cout << "OKKKKKK" << endl;
      }*/

    sort(m.begin() + 1, m.end(), comp);
    set<int>s;
    for (int i = 1; i <= n; i++)s.insert(i);
    for (int i = 1; i <= n; i++)
    {
        if (s.find(m[i].first) != s.end())
        {
            for (auto j : m[i].second)
            {
                s.erase(j);
            }
        }
    }

    int t = (k + 1) / 2;
    if (s.size() < t)
    {
        DFS(1, 1);
        for (auto i : v)
        {
            int st = vis[i.first];
            for (auto j : i.second)
            {
                int en = vis[j];
                if (abs(st - en) == k)
                {
                    cycle(st, k, 1);
                    cout << 2 << endl;
                    cout << helper.size() << endl;
                    //  error(helper);
                    // error(st);
                    for (auto x : helper)
                    {
                        cout << x << " ";
                    }
                    cout << endl;
                    return;
                }

            }

        }

        return;
    }
    cout << 1 << endl;
    while (t--)
    {

        cout << *s.begin() << " ";
        s.erase(s.begin());
    }
    cout << endl;

}

int_fast32_t main() {

    F_I;

    int t = 1;
    while (t--)solve();
}


#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>

#define mod 1000000007
#define F_I ios_base::sync_with_stdio(false);cin.tie(NULL);

using namespace std;
#define int long long
#define inf 1e18
#define endl "\n"
#define um unordered_map

template <class Ch, class Tr, class Container>
basic_ostream <Ch, Tr> & operator << (basic_ostream <Ch, Tr> & os, Container const& x) {
    os << "{ "; for (auto& y : x) os << y << " "; return os << "}";
} template <class X, class Y>ostream & operator << (ostream & os, pair <X, Y> const& p) {
    return os << "[" << p.first << " : " << p.second << "]" ;
}
#define error(...) {\
string _s = #__VA_ARGS__;\
replace(_s.begin(), _s.end(), ',', ' ');\
stringstream _ss(_s);\
istream_iterator<string> _it(_ss);\
err(_it, __VA_ARGS__); cerr << endl;\
}
void err(...) {}
template<typename T, typename... Args>void err(istream_iterator<string> it, T a, Args... args) {
    for (auto i : *it)   cerr << i;  cerr << " = " << a << endl; err(++it, args...);
}

vector<pair<int, vector<int> >>m;
um<int, vector<int> >v;

int n, ma, k;
bool comp(pair<int, vector<int> >const v1, pair<int, vector<int> >const v2)
{
    return v1.second.size() < v2.second.size();
}

vector<int>vis;
vector<int>visited;
void DFS(int r, int t)
{
    if (vis[r] != 0)return;
    vis[r] = t;
    for (auto i : v[r])
    {
        DFS(i, t + 1);
    }
}

vector<int>helper;
bool cycle(int p, int r, int l)
{
    if (l == k + 1 && p == r) return true;
    if (visited[p] == 2)return false;
    visited[p] = 2;
    helper.push_back(p);
    bool ans = false;
    for (auto i : v[p])
    {
        ans |= cycle(i, r, l + 1);
    }
    if (ans)return true;
    helper.pop_back();
    return false;

}
void solve() {
    cerr << "--------------------" << endl;
    cin >> n >> ma >> k;
    visited.resize(n + 1, 0);
    vis.resize(n + 1, 0);
    m = vector <pair<int, vector<int> > >(n + 1);
    for (int i = 1; i <= n; i++)
    {
        m[i].first = i;
    }

    for (int i = 1; i <= ma; i++)
    {
        int a, b;
        cin >> a >> b;
        m[a].second.push_back(b);
        v[a].push_back(b);
        v[b].push_back(a);

        m[b].second.push_back(a);
    }
    /*  if (cycle(4, k, 1)) {
          cout << "OKKKKKK" << endl;
      }*/

    sort(m.begin() + 1, m.end(), comp);
    set<int>s;
    for (int i = 1; i <= n; i++)s.insert(i);
    for (int i = 1; i <= n; i++)
    {
        if (s.find(m[i].first) != s.end())
        {
            for (auto j : m[i].second)
            {
                s.erase(j);
            }
        }
    }

    int t = (k + 1) / 2;
    if (s.size() < t)
    {
        DFS(1, 1);
       // error(vis);
        for (auto i : v)
        {
            int st = vis[i.first];
            for (auto j : i.second)
            {
                int en = vis[j];
                if (abs(st - en) + 1  == k)
                {
                    cycle(st, k, 1);
                    cout << 2 << endl;
                    cout << helper.size() << endl;
                    //  error(helper);
                    // error(st);
                    for (auto x : helper)
                    {
                        cout << x << " ";
                    }
                    cout << endl;
                    return;
                }

            }

        }

        return;
    }
    cout << 1 << endl;
    while (t--)
    {

        cout << *s.begin() << " ";
        s.erase(s.begin());
    }
    cout << endl;

}

int_fast32_t main() {

    F_I;

    int t = 1;
    while (t--)solve();
}


#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>

#define mod 1000000007
#define F_I ios_base::sync_with_stdio(false);cin.tie(NULL);

using namespace std;
//#define int long long
#define inf 1e18
#define endl "\n"
#define um unordered_map

set<int>col[2];
vector<int>l(100005, 0);
vector<int>h;
um<int, vector<int> >m;
int k;
void DFS(int r, int p)
{
	h.push_back(r);
	l[r] = h.size();

	col[l[r] % 2].insert(r);
	for (auto i : m[r])
	{
		if (i == p)continue;
		if (l[i] == 0)
		{
			DFS(i, r);
		}
		else if (l[r] > l[i])
		{
			if (l[r] % 2 == l[i] % 2)
			{
				col[l[r] % 2].erase(r);
			}
			if (l[r] - l[i] + 1 <= k)
			{
				cout << 2 << endl;
				cout << l[r] - l[i] + 1 << endl;
				for (int j = l[i] - 1; j < l[r]; j++)
				{
					cout << h[j] << " ";
				}
				exit(0);
			}
			if (l[r] - l[r] + 1 > k)return;

		}
	}
	h.pop_back();

}

void solve() {
	//cerr << "--------------------" << endl;
	int n, ma;
	cin >> n >> ma >> k;
	for (int i = 1; i <= ma; i++)
	{
		int a, b;
		cin >> a >> b;
		m[a].push_back(b);
		m[b].push_back(a);
	}
	DFS(1, 1);

	if (col[0].size() < col[1].size())swap(col[0], col[1]);
	int t = (k + 1) / 2;
	cout << 1 << endl;
	while (t--)
	{
		cout << *col[0].begin() << " ";
		col[0].erase(col[0].begin());
	}
	//error(col[0],col[1]);

}

int_fast32_t main() {

	F_I;

	int t = 1;
	while (t--)solve();
}


#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>

#define mod 1000000007
#define F_I ios_base::sync_with_stdio(false);cin.tie(NULL);

using namespace std;
#define int long long
#define inf 1e18
#define endl "\n"
#define um unordered_map
template <class Ch, class Tr, class Container>
basic_ostream <Ch, Tr> & operator << (basic_ostream <Ch, Tr> & os, Container const& x) {
	os << "{ "; for (auto& y : x) os << y << " "; return os << "}";
} template <class X, class Y>ostream & operator << (ostream & os, pair <X, Y> const& p) {
	return os << "[" << p.first << " : " << p.second << "]" ;
}
#define error(...) {\
string _s = #__VA_ARGS__;\
replace(_s.begin(), _s.end(), ',', ' ');\
stringstream _ss(_s);\
istream_iterator<string> _it(_ss);\
err(_it, __VA_ARGS__); cerr << endl;\
}
void err(...) {}
template<typename T, typename... Args>void err(istream_iterator<string> it, T a, Args... args) {
	for (auto i : *it)   cerr << i;  cerr << " = " << a << endl; err(++it, args...);
}

set<int>col[2];
vector<int>l(100005, 0);
vector<int>h;
um<int, vector<int> >m;
int k;
void DFS(int r, int p)
{
	h.push_back(r);
	l[r] = h.size();

	col[l[r] % 2].insert(r);
	for (auto i : m[r])
	{
		if (i == p)continue;
		if (l[i] == 0)
		{
			DFS(i, r);
		}
		else if (l[r] > l[i])
		{
			if (l[r] - l[i] + 1 <= k)
			{
				cout << 2 << endl;
				cout << l[r] - l[i] + 1 << endl;
				for (int j = l[i] - 1; j < l[r]; j++)
				{
					cout << h[j] << " ";
				}
				exit(0);
			}
			if(l[r]-l[r]+1>k)return;

		}
	}
	h.pop_back();

}

void solve() {
	cerr << "--------------------" << endl;
	int n, ma;
	cin >> n >> ma >> k;
	for (int i = 1; i <= ma; i++)
	{
		int a, b;
		cin >> a >> b;
		m[a].push_back(b);
		m[b].push_back(a);
	}
	DFS(1, 1);

	if (col[0].size() < col[1].size())swap(col[0], col[1]);
	int t = (k + 1) / 2;
	cout << 1 << endl;
	while (t--)
	{
		cout << *col[0].begin() << " ";
		col[0].erase(col[0].begin());
	}
	//error(col[0],col[1]);

}

int_fast32_t main() {

	F_I;

	int t = 1;
	while (t--)solve();
}


#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>

#define mod 1000000007
#define F_I ios_base::sync_with_stdio(false);cin.tie(NULL);

using namespace std;
#define int long long
#define inf 1e18
#define endl "\n"
#define um unordered_map

template <class Ch, class Tr, class Container>
basic_ostream <Ch, Tr> & operator << (basic_ostream <Ch, Tr> & os, Container const& x) {
    os << "{ "; for (auto& y : x) os << y << " "; return os << "}";
} template <class X, class Y>ostream & operator << (ostream & os, pair <X, Y> const& p) {
    return os << "[" << p.first << " : " << p.second << "]" ;
}
#define error(...) {\
string _s = #__VA_ARGS__;\
replace(_s.begin(), _s.end(), ',', ' ');\
stringstream _ss(_s);\
istream_iterator<string> _it(_ss);\
err(_it, __VA_ARGS__); cerr << endl;\
}
void err(...) {}
template<typename T, typename... Args>void err(istream_iterator<string> it, T a, Args... args) {
    for (auto i : *it)   cerr << i;  cerr << " = " << a << endl; err(++it, args...);
}

vector<pair<int, vector<int> >>m;
um<int, vector<int> >v;

int n, ma, k;
bool comp(pair<int, vector<int> >const v1, pair<int, vector<int> >const v2)
{
    return v1.second.size() < v2.second.size();
}

int vis[100005];
vector<int>visited(100005);
void DFS(int r, int t)
{
    if (vis[r] != 0)return;
    vis[r] = t;
    for (auto i : v[r])
    {
        DFS(i, t + 1);
    }
}

vector<int>helper;
bool cycle(int p, int r, int l)
{
    if (l == k + 1 && p == r) return true;
    if (visited[p] == 2)return false;
    visited[p] = 2;
    helper.push_back(p);
    bool ans = false;
    for (auto i : v[p])
    {
        ans |= cycle(i, r, l + 1);
    }
    if (ans)return true;
    helper.pop_back();
    return false;

}
void solve() {
    cerr << "--------------------" << endl;
    cin >> n >> ma >> k;
    m = vector <pair<int, vector<int> > >(n + 1);
    for (int i = 1; i <= n; i++)
    {
        m[i].first = i;
    }

    for (int i = 1; i <= ma; i++)
    {
        int a, b;
        cin >> a >> b;
        m[a].second.push_back(b);
        v[a].push_back(b);
        v[b].push_back(a);

        m[b].second.push_back(a);
    }
    /*  if (cycle(4, k, 1)) {
          cout << "OKKKKKK" << endl;
      }*/

    sort(m.begin() + 1, m.end(), comp);
    set<int>s;
    for (int i = 1; i <= n; i++)s.insert(i);
    for (int i = 1; i <= n; i++)
    {
        if (s.find(m[i].first) != s.end())
        {
            for (auto j : m[i].second)
            {
                s.erase(j);
            }
        }
    }

    int t = (k + 1) / 2;
    if (s.size() < t)
    {
        DFS(1, 1);
        for (auto i : v)
        {
            int st = vis[i.first];
            for (auto j : i.second)
            {
                int en = vis[j];
                if (abs(st - en) == k)
                {
                    cycle(st, k, 1);
                    cout << 2 << endl;
                    cout << helper.size() << endl;
                  //  error(helper);
                   // error(st);
                    for (auto x : helper)
                    {
                        cout << x << " ";
                    }
                    return;
                }

            }

        }

        return;
    }
    cout << 1 << endl;
    while (t--)
    {

        cout << *s.begin() << " ";
        s.erase(s.begin());
    }

}

int_fast32_t main() {

    F_I;

    int t = 1;
    while (t--)solve();
}


#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>

#define mod 1000000007
#define F_I ios_base::sync_with_stdio(false);cin.tie(NULL);

using namespace std;
#define int long long
#define inf 1e18
#define endl "\n"
#define um unordered_map
template <class Ch, class Tr, class Container>
basic_ostream <Ch, Tr> & operator << (basic_ostream <Ch, Tr> & os, Container const& x) {
	os << "{ "; for (auto& y : x) os << y << " "; return os << "}";
} template <class X, class Y>ostream & operator << (ostream & os, pair <X, Y> const& p) {
	return os << "[" << p.first << " : " << p.second << "]" ;
}
#define error(...) {\
string _s = #__VA_ARGS__;\
replace(_s.begin(), _s.end(), ',', ' ');\
stringstream _ss(_s);\
istream_iterator<string> _it(_ss);\
err(_it, __VA_ARGS__); cerr << endl;\
}
void err(...) {}
template<typename T, typename... Args>void err(istream_iterator<string> it, T a, Args... args) {
	for (auto i : *it)   cerr << i;  cerr << " = " << a << endl; err(++it, args...);
}

set<int>col[2];
vector<int>l(100005, 0);
vector<int>h;
um<int, vector<int> >m;
int k;
void DFS(int r)
{
	h.push_back(r);
	l[r] = h.size();

	col[l[r] % 2].insert(r);
	for (auto i : m[r])
	{
		if (l[i]==0)
		{
			DFS(i);
		}
		else if (l[i] + 1 < l[r])
		{	if (l[r] - l[i] + 1 > k)
			{
				if (col[0].size() < col[1].size())swap(col[0], col[1]);
				int t = (k + 1) / 2;
				cout << 1 << endl;
				while (t--)
				{
					cout << *col[0].begin() << " ";
					col[0].erase(col[0].begin());
				}
				exit(0);
			}
			cout << 2 << endl;
			cout << l[r] - l[i] + 1 << endl;
			for (int j = l[i]; j <= l[r]; j++)
			{
				cout << h[j] << " ";
			}
			exit(0);
		}
	}
	h.pop_back();

}

void solve() {
	cerr << "--------------------" << endl;
	int n, ma;
	cin >> n >> ma >> k;
	for (int i = 1; i <= ma; i++)
	{
		int a, b;
		cin >> a >> b;
		m[a].push_back(b);
		m[b].push_back(a);
	}
	DFS(1);
	if (col[0].size() < col[1].size())swap(col[0], col[1]);
	int t = (k + 1) / 2;
	cout << 1 << endl;
	while (t--)
	{
		cout << *col[0].begin() << " ";
		col[0].erase(col[0].begin());
	}
	//error(col[0],col[1]);

}

int_fast32_t main() {

	F_I;

	int t = 1;
	while (t--)solve();
}


#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>

#define mod 1000000007
#define F_I ios_base::sync_with_stdio(false);cin.tie(NULL);

using namespace std;
#define int long long
#define inf 1e18
#define endl "\n"
#define um unordered_map
template <class Ch, class Tr, class Container>
basic_ostream <Ch, Tr> & operator << (basic_ostream <Ch, Tr> & os, Container const& x) {
	os << "{ "; for (auto& y : x) os << y << " "; return os << "}";
} template <class X, class Y>ostream & operator << (ostream & os, pair <X, Y> const& p) {
	return os << "[" << p.first << " : " << p.second << "]" ;
}
#define error(...) {\
string _s = #__VA_ARGS__;\
replace(_s.begin(), _s.end(), ',', ' ');\
stringstream _ss(_s);\
istream_iterator<string> _it(_ss);\
err(_it, __VA_ARGS__); cerr << endl;\
}
void err(...) {}
template<typename T, typename... Args>void err(istream_iterator<string> it, T a, Args... args) {
	for (auto i : *it)   cerr << i;  cerr << " = " << a << endl; err(++it, args...);
}

set<int>col[2];
vector<int>l(100005, 0);
vector<int>h;
um<int, vector<int> >m;
int k;
void DFS(int r, int p)
{
	h.push_back(r);
	l[r] = h.size();

	col[l[r] % 2].insert(r);
	for (auto i : m[r])
	{
		if (i == p)continue;
		if (l[i] == 0)
		{
			DFS(i, r);
		}

		else if (l[r] - l[i] + 1 <= k)
		{
			cout << 2 << endl;
			cout << l[r] - l[i] + 1 << endl;
			for (int j = l[i] - 1; j < l[r]; j++)
			{
				cout << h[j] << " ";
			}
			exit(0);
		}
		else
		{
			if (l[r] > l[i])
			{
				if (col[r] == col[i])
				{
					col[l[r] % 2].erase(r);
				}
			}
		}

	}
	h.pop_back();

}

void solve() {
	cerr << "--------------------" << endl;
	int n, ma;
	cin >> n >> ma >> k;
	for (int i = 1; i <= ma; i++)
	{
		int a, b;
		cin >> a >> b;
		m[a].push_back(b);
		m[b].push_back(a);
	}
	DFS(1, 1);

	if (col[0].size() < col[1].size())swap(col[0], col[1]);
	int t = (k + 1) / 2;
	cout << 1 << endl;
	while (t--)
	{
		cout << *col[0].begin() << " ";
		col[0].erase(col[0].begin());
	}
	//error(col[0],col[1]);

}

int_fast32_t main() {

	F_I;

	int t = 1;
	while (t--)solve();
}


                                        /******SHOW US THE BEST YOU CAN DO******/

#include<bits/stdc++.h>

using namespace std;

#define ll long long int

ll gcd(ll a, ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a, ll b){return a * b / gcd(a, b);}

const int N = 1e5 + 10;

vector<int>ad[N], ans[2];
int vis[N], p[N], n, m, k, f, d[N];

void dfs(int v, int dep){
    vis[v] = 1;
    d[v] = dep;
    if(dep < k)
        ans[dep % 2].push_back(v);
    for(auto u : ad[v]){
        if(u == p[v])continue;
        if(vis[u]){
            if(d[v] > d[u]){
                int da = d[v] - d[u] + 1;
                if(da <= k){
                    vector<int>t;
                    int cur = v;
                    while(cur != u)t.push_back(cur), cur = p[cur];
                    t.push_back(u);
                    printf("%d\n%d\n", 2, (int)t.size());
                    for(auto u : t)printf("%d ", u);
                    puts("");
                    exit(0);
                }
            }
        }else{
            p[u] = v;
            dfs(u, dep + 1);
        }
    }
}

int main(){
    //freopen("output.in","r",stdin);
    //freopen("output.txt","w",stdout);
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1; i <= m; i++){
        int x, y;
        scanf("%d%d", &x, &y);
        ad[x].push_back(y);
        ad[y].push_back(x);
    }
    dfs(1, 0);
    puts("1");
    if(ans[0].size() < ans[1].size())swap(ans[0], ans[1]);
    for(int i = 0; i < (k + 1) / 2; i++)printf("%d ", ans[0][i]);
    puts("");
    return 0;
}


                                        /******SHOW US THE BEST YOU CAN DO******/

#include<bits/stdc++.h>

using namespace std;

#define ll long long int

ll gcd(ll a, ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a, ll b){return a * b / gcd(a, b);}

const int N = 1e5 + 10;

vector<int>ad[N], path;
int vis[N], col[N], n, m, k, f;
void dfs(int v, int c){
    col[v] = c;
    for(auto u : ad[v]){
        if(col[u] && col[u] == c){
            f = 1;
            return;
        }
        if(!col[u])
            dfs(u, 3 - c);
    }
}

void dfs(int v){
    vis[v] = 1;
    path.push_back(v);
    for(auto u : ad[v]){
        if(vis[u] == 1){
            vector<int>t;
            int idx = (int)path.size() - 1;
            while(path[idx] != u)t.push_back(path[idx--]);
            t.push_back(u);
            if((int)t.size() <= k && (int)t.size() >= 3){
                printf("%d\n%d\n", 2, (int)t.size());
                for(auto u : t)printf("%d ", u);
                puts("");
                exit(0);
            }
        }else if(vis[u] == 0)
            dfs(u);
    }
    vis[v] = 2;
    path.pop_back();
}

int myceil(int a, int b){
    return (a + b - 1) / b;
}

int main(){
    //freopen("output.in","r",stdin);
    //freopen("output.txt","w",stdout);
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1; i <= m; i++){
        int x, y;
        scanf("%d%d", &x, &y);
        ad[x].push_back(y);
        ad[y].push_back(x);
    }
    dfs(1, 1);
    if(!f){
        int cntr = 0;
        for(int i = 1; i <= n; i++)if(col[i] == 2)cntr++;
        int need = myceil(n, 2);
        int c = -1;
        if(cntr == need)c = 2;
        else if(n - cntr == need)c = 1;
        if(c == -1)goto fin;
        puts("1");
        for(int i = 1; i <= n; i++)
            if(col[i] == c)printf("%d ", i);
        puts("");
        return 0;
    }
    fin:;
    dfs(1);
    return 0;
}


                                        /******SHOW US THE BEST YOU CAN DO******/

#include<bits/stdc++.h>

using namespace std;

#define ll long long int

ll gcd(ll a, ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a, ll b){return a * b / gcd(a, b);}

const int N = 1e5 + 10;

vector<int>ad[N], path;
int vis[N], col[N], n, m, k, f, d[N];
void dfs(int v, int c){
    col[v] = c;
    for(auto u : ad[v]){
        if(col[u] && col[u] == c){
            f = 1;
            return;
        }
        if(!col[u])
            dfs(u, 3 - c);
    }
}

void dfs(int v){
    vis[v] = 1;
    path.push_back(v);
    for(auto u : ad[v]){
        if(vis[u] == 1){
            vector<int>t;
            int idx = (int)path.size() - 1;
            while(path[idx] != u)t.push_back(path[idx--]);
            t.push_back(u);
            if((int)t.size() <= k && (int)t.size() >= 3){
                printf("%d\n%d\n", 2, (int)t.size());
                for(auto u : t)printf("%d ", u);
                puts("");
                exit(0);
            }
        }else if(vis[u] == 0){
            d[u] = d[v] + 1;
            dfs(u);
        }
    }
    vis[v] = 2;
    path.pop_back();
}

int main(){
    //freopen("output.in","r",stdin);
    //freopen("output.txt","w",stdout);
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1; i <= m; i++){
        int x, y;
        scanf("%d%d", &x, &y);
        ad[x].push_back(y);
        ad[y].push_back(x);
    }
    dfs(1, 1);
    if(!f){
        int cntr = 0;
        for(int i = 1; i <= n; i++)if(col[i] == 2)cntr++;
        int need = (k + 1) / 2;
        int c = -1;
        if(cntr >= need)c = 2;
        else if(n - cntr >= need)c = 1;
        if(c == -1)goto fin;
        puts("1");
        for(int i = 1; i <= n; i++)
            if(col[i] == c)printf("%d ", i);
        puts("");
        return 0;
    }
    fin:;
    dfs(1);
    puts("1");
    vector<int>o, e;
    for(int i = 1; i <= n; i++)if(d[i]&1)o.push_back(i);else e.push_back(i);
    if(o.size() >= (k + 1) / 2){
        for(int i = 0; i < (k + 1) / 2; i++)
            printf("%d ", o[i]);
        puts("");
    }else{
        for(int i = 0; i < (k + 1) / 2; i++)
            printf("%d ", e[i]);
        puts("");
    }
    return 0;
}


                                        /******SHOW US THE BEST YOU CAN DO******/

#include<bits/stdc++.h>

using namespace std;

#define ll long long int

ll gcd(ll a, ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a, ll b){return a * b / gcd(a, b);}

const int N = 1e5 + 10;

vector<int>ad[N], path;
int vis[N], p[N], n, m, k, f, d[N], st, en;

void dfs(int v, int dep){
    vis[v] = 1;
    d[v] = dep;
    for(auto u : ad[v]){
        if(u == p[v])continue;
        if(vis[u]){
            if(d[v] > d[u]){
                int da = d[v] - d[u] + 1;
                if(da <= k){
                    vector<int>t;
                    int cur = v;
                    st = v;
                    en = u;
                    while(cur != u)t.push_back(cur), cur = p[cur];
                    t.push_back(u);
                    printf("%d\n%d\n", 2, (int)t.size());
                    for(auto u : t)printf("%d ", u);
                    puts("");
                    exit(0);
                }
            }
        }else{
            p[u] = v;
            dfs(u, dep + 1);
        }
    }
}

int main(){
    //freopen("output.in","r",stdin);
    //freopen("output.txt","w",stdout);
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1; i <= m; i++){
        int x, y;
        scanf("%d%d", &x, &y);
        ad[x].push_back(y);
        ad[y].push_back(x);
    }
    dfs(1, 1);
    puts("1");
    vector<int>o, e;
    for(int i = 1; i <= n; i++)if(d[i]&1)o.push_back(i);else e.push_back(i);
    if(o.size() >= (k + 1) / 2){
        for(int i = 0; i < (k + 1) / 2; i++)
            printf("%d ", o[i]);
        puts("");
        return 0;
    }else if(e.size() >= (k + 1) / 2){
        for(int i = 0; i < (k + 1) / 2; i++)
            printf("%d ", e[i]);
        puts("");
        return 0;
    }
    vector<int>ans;
    while(st != 0 && d[st] >= d[en]){
        ans.push_back(st);
        st = p[st];
        st = p[st];
    }
    assert(ans.size() >= (k + 1) / 2);
    for(int i : ans)printf("%d ", i);puts("");
    return 0;
}


                                        /******SHOW US THE BEST YOU CAN DO******/

#include<bits/stdc++.h>

using namespace std;

#define ll long long int

ll gcd(ll a, ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a, ll b){return a * b / gcd(a, b);}

const int N = 1e5 + 10;

vector<int>ad[N], path;
int vis[N], col[N], n, m, k, f, d[N];
void dfs(int v, int c){
    col[v] = c;
    for(auto u : ad[v]){
        if(col[u] && col[u] == c){
            f = 1;
            return;
        }
        if(!col[u])
            dfs(u, 3 - c);
    }
}

void dfs(int v){
    vis[v] = 1;
    path.push_back(v);
    for(auto u : ad[v]){
        if(vis[u] == 1){
            vector<int>t;
            int idx = (int)path.size() - 1;
            while(path[idx] != u)t.push_back(path[idx--]);
            t.push_back(u);
            if((int)t.size() <= k && (int)t.size() >= 3){
                printf("%d\n%d\n", 2, (int)t.size());
                for(auto u : t)printf("%d ", u);
                puts("");
                exit(0);
            }
        }else if(vis[u] == 0){
            d[u] = d[v] + 1;
            dfs(u);
        }
    }
    vis[v] = 2;
    path.pop_back();
}

int myceil(int a, int b){
    return (a + b - 1) / b;
}

int main(){
    //freopen("output.in","r",stdin);
    //freopen("output.txt","w",stdout);
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1; i <= m; i++){
        int x, y;
        scanf("%d%d", &x, &y);
        ad[x].push_back(y);
        ad[y].push_back(x);
    }
    dfs(1, 1);
    if(!f){
        int cntr = 0;
        for(int i = 1; i <= n; i++)if(col[i] == 2)cntr++;
        int need = myceil(n, 2);
        int c = -1;
        if(cntr >= need)c = 2;
        else if(n - cntr >= need)c = 1;
        if(c == -1)goto fin;
        puts("1");
        for(int i = 1; i <= n; i++)
            if(col[i] == c)printf("%d ", i);
        puts("");
        return 0;
    }
    fin:;
    dfs(1);
    puts("1");
    printf("%d\n", myceil(n, 2));
    vector<int>o, e;
    for(int i = 1; i <= n; i++)if(d[i]&1)o.push_back(i);else e.push_back(i);
    if(o.size() > myceil(n, 2)){
        for(int i = 0; i < myceil(n, 2); i++)
            printf("%d ", o[i]);
        puts("");
    }else{
        for(int i = 0; i < myceil(n, 2); i++)
            printf("%d ", e[i]);
        puts("");
    }
    return 0;
}


                                        /******SHOW US THE BEST YOU CAN DO******/

#include<bits/stdc++.h>

using namespace std;

#define ll long long int

ll gcd(ll a, ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a, ll b){return a * b / gcd(a, b);}

const int N = 1e5 + 10;

vector<int>ad[N], path;
int vis[N], p[N], n, m, k, f, d[N];

void dfs(int v, int dep){
    vis[v] = 1;
    d[v] = dep;
    for(auto u : ad[v]){
        if(u == p[v])continue;
        if(vis[u]){
            if(d[v] > d[u]){
                int da = d[v] - d[u] + 1;
                if(da <= k){
                    vector<int>t;
                    int cur = v;
                    while(cur != u)t.push_back(cur), cur = p[cur];
                    t.push_back(u);
                    printf("%d\n%d\n", 2, (int)t.size());
                    for(auto u : t)printf("%d ", u);
                    puts("");
                    exit(0);
                }
            }
        }else{
            p[u] = v;
            dfs(u, dep + 1);
        }
    }
}

int main(){
    //freopen("output.in","r",stdin);
    //freopen("output.txt","w",stdout);
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1; i <= m; i++){
        int x, y;
        scanf("%d%d", &x, &y);
        ad[x].push_back(y);
        ad[y].push_back(x);
    }
    dfs(1, 1);
    puts("1");
    vector<int>o, e;
    for(int i = 1; i <= n; i++)if(d[i]&1)o.push_back(i);else e.push_back(i);
    if(o.size() >= (k + 1) / 2){
        for(int i = 0; i < (k + 1) / 2; i++)
            printf("%d ", o[i]);
        puts("");
    }else{
        for(int i = 0; i < (k + 1) / 2; i++)
            printf("%d ", e[i]);
        puts("");
    }
    return 0;
}


                                        /******SHOW US THE BEST YOU CAN DO******/

#include<bits/stdc++.h>

using namespace std;

#define ll long long int

ll gcd(ll a, ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a, ll b){return a * b / gcd(a, b);}

const int N = 1e5 + 10;

vector<int>ad[N], path;
int vis[N], col[N], n, m, k, f, d[N];
void dfs(int v, int c){
    col[v] = c;
    for(auto u : ad[v]){
        if(col[u] && col[u] == c){
            f = 1;
            return;
        }
        if(!col[u])
            dfs(u, 3 - c);
    }
}

void dfs(int v){
    vis[v] = 1;
    path.push_back(v);
    for(auto u : ad[v]){
        if(vis[u] == 1){
            vector<int>t;
            int idx = (int)path.size() - 1;
            while(path[idx] != u)t.push_back(path[idx--]);
            t.push_back(u);
            if((int)t.size() <= k && (int)t.size() >= 3){
                printf("%d\n%d\n", 2, (int)t.size());
                for(auto u : t)printf("%d ", u);
                puts("");
                exit(0);
            }
        }else if(vis[u] == 0){
            d[u] = d[v] + 1;
            dfs(u);
        }
    }
    vis[v] = 2;
    path.pop_back();
}

int myceil(int a, int b){
    return (a + b - 1) / b;
}

int main(){
    //freopen("output.in","r",stdin);
    //freopen("output.txt","w",stdout);
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1; i <= m; i++){
        int x, y;
        scanf("%d%d", &x, &y);
        ad[x].push_back(y);
        ad[y].push_back(x);
    }
    dfs(1, 1);
    if(!f){
        int cntr = 0;
        for(int i = 1; i <= n; i++)if(col[i] == 2)cntr++;
        int need = myceil(n, 2);
        int c = -1;
        if(cntr >= need)c = 2;
        else if(n - cntr >= need)c = 1;
        if(c == -1)goto fin;
        puts("1");
        for(int i = 1; i <= n; i++)
            if(col[i] == c)printf("%d ", i);
        puts("");
        return 0;
    }
    fin:;
    dfs(1);
    puts("1");
    vector<int>o, e;
    for(int i = 1; i <= n; i++)if(d[i]&1)o.push_back(i);else e.push_back(i);
    if(o.size() > myceil(n, 2)){
        for(int i = 0; i < myceil(n, 2); i++)
            printf("%d ", o[i]);
        puts("");
    }else{
        for(int i = 0; i < myceil(n, 2); i++)
            printf("%d ", e[i]);
        puts("");
    }
    return 0;
}


                                        /******SHOW US THE BEST YOU CAN DO******/

#include<bits/stdc++.h>

using namespace std;

#define ll long long int

ll gcd(ll a, ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a, ll b){return a * b / gcd(a, b);}

const int N = 1e5 + 10;

vector<int>ad[N], path;
int vis[N], col[N], n, m, k, f;
void dfs(int v, int c){
    col[v] = c;
    for(auto u : ad[v]){
        if(col[u] && col[u] == c){
            continue;
        }
        if(!col[u])
            dfs(u, 3 - c);
    }
}

void dfs(int v){
    vis[v] = 1;
    path.push_back(v);
    for(auto u : ad[v]){
        if(vis[u] == 1){
            vector<int>t;
            int idx = (int)path.size() - 1;
            while(path[idx] != u)t.push_back(path[idx--]);
            t.push_back(u);
            if((int)t.size() <= k && (int)t.size() >= 3){
                printf("%d\n%d\n", 2, (int)t.size());
                for(auto u : t)printf("%d ", u);
                puts("");
                exit(0);
            }
        }else if(vis[u] == 0)
            dfs(u);
    }
    vis[v] = 2;
    path.pop_back();
}

int myceil(int a, int b){
    return (a + b - 1) / b;
}

int main(){
    //freopen("output.in","r",stdin);
    //freopen("output.txt","w",stdout);
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1; i <= m; i++){
        int x, y;
        scanf("%d%d", &x, &y);
        ad[x].push_back(y);
        ad[y].push_back(x);
    }
    dfs(1, 1);
    {
        int cntr = 0;
        for(int i = 1; i <= n; i++)if(col[i] == 2)cntr++;
        int need = myceil(n, 2);
        int c = -1;
        if(cntr >= need)c = 2;
        else if(n - cntr >= need)c = 1;
        if(c == -1)goto fin;
        puts("1");
        cntr = 0;
        for(int i = 1; i <= n && cntr < need; i++)
            if(col[i] == c){
                printf("%d ", i);
                cntr++;
            }
        puts("");
        return 0;
    }
    fin:;
    dfs(1);

    return 0;
}


                                        /******SHOW US THE BEST YOU CAN DO******/

#include<bits/stdc++.h>

using namespace std;

#define ll long long int

ll gcd(ll a, ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a, ll b){return a * b / gcd(a, b);}

const int N = 1e5 + 10;

vector<int>ad[N], ans, path;
int vis[N], col[N], n, m, k, f;
vector<vector<int>>cycles;
void dfs(int v, int c){
    col[v] = c;
    for(auto u : ad[v]){
        if(col[u] == c){
            f = 1;
            return;
        }
        if(!col[u])
            dfs(u, 3 - c);
    }
}

void dfs(int v){
    vis[v] = 1;
    path.push_back(v);
    for(auto u : ad[v]){
        if(vis[u] == 1){
            vector<int>t;
            int idx = (int)path.size() - 1;
            while(path[idx] != u)t.push_back(path[idx--]);
            t.push_back(u);
            if((int)t.size() - 1 <= k){
               cycles.push_back(t);
            }
        }else if(vis[u] == 0)
            dfs(u);
    }
    vis[v] = 2;
    path.pop_back();
}

int myceil(int a, int b){
    return (a + b - 1) / b;
}

int main(){
    //freopen("output.in","r",stdin);
    //freopen("output.txt","w",stdout);
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1; i <= m; i++){
        int x, y;
        scanf("%d%d", &x, &y);
        ad[x].push_back(y);
        ad[y].push_back(x);
    }
    dfs(1, 1);
    if(!f){
        int cntr = 0;
        for(int i = 1; i <= n; i++)if(col[i] == 2)cntr++;
        int need = myceil(n, 2);
        int c = -1;
        if(cntr == need)c = 2;
        else if(n - cntr == need)c = 1;
        if(c == -1)goto fin;
        puts("1");
        for(int i = 1; i <= n; i++)
            if(col[i] == c)printf("%d ", i);
        puts("");
        return 0;
    }
    fin:;
    dfs(1);
    for(auto v : cycles)if((int)v.size() >= 3 && v.size() <= k){ans = v; break;}
    printf("%d\n%d\n", 2, (int)ans.size());
    for(auto u : ans)printf("%d ", u);
    puts("");
    return 0;
}


                                        /******SHOW US THE BEST YOU CAN DO******/

#include<bits/stdc++.h>

using namespace std;

#define ll long long int

ll gcd(ll a, ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a, ll b){return a * b / gcd(a, b);}

const int N = 1e5 + 10;

vector<int>ad[N], path;
int vis[N], col[N], p[N], n, m, k, f, d[N];
void dfs(int v, int c){
    col[v] = c;
    for(auto u : ad[v]){
        if(col[u] && col[u] == c){
            f = 1;
            return;
        }
        if(!col[u])
            dfs(u, 3 - c);
    }
}

void dfss(int u, int dep) {
    vis[u] = 1;
    d[u] = dep;
    for(int v : ad[u]) {
        if(v == p[u]) continue;
        if(!vis[v]) {
            p[v] = u;
            dfss(v, dep+1);
        }
        else {
            if(d[v] < d[u]) {
                int da = d[u]-d[v]+1;
                if(da <= k) {
                    vector<int> cyc;
                    int node = u;
                    while(1) {
                        cyc.push_back(node);
                        if(node == v) break;
                        node = p[node];
                    }
                    cout << "2" << endl;
                    cout << cyc.size() << endl;
                    for(int x : cyc) {
                        cout << x << " ";
                    }
                    exit(0);
                }
            }
        }
    }
}

int main(){
    //freopen("output.in","r",stdin);
    //freopen("output.txt","w",stdout);
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1; i <= m; i++){
        int x, y;
        scanf("%d%d", &x, &y);
        ad[x].push_back(y);
        ad[y].push_back(x);
    }
    dfs(1, 1);
    if(!f){
        int cntr = 0;
        for(int i = 1; i <= n; i++)if(col[i] == 2)cntr++;
        int need = (k + 1) / 2;
        int c = -1;
        if(cntr >= need)c = 2;
        else if(n - cntr >= need)c = 1;
        if(c == -1)goto fin;
        puts("1");
        for(int i = 1; i <= n; i++)
            if(col[i] == c)printf("%d ", i);
        puts("");
        return 0;
    }
    fin:;
    dfss(1, 1);
    puts("1");
    vector<int>o, e;
    for(int i = 1; i <= n; i++)if(d[i]&1)o.push_back(i);else e.push_back(i);
    if(o.size() >= (k + 1) / 2){
        for(int i = 0; i < (k + 1) / 2; i++)
            printf("%d ", o[i]);
        puts("");
    }else{
        for(int i = 0; i < (k + 1) / 2; i++)
            printf("%d ", e[i]);
        puts("");
    }
    return 0;
}


                                        /******SHOW US THE BEST YOU CAN DO******/

#include<bits/stdc++.h>

using namespace std;

#define ll long long int

ll gcd(ll a, ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a, ll b){return a * b / gcd(a, b);}

const int N = 1e5 + 10;

vector<int>ad[N], path;
int vis[N], col[N], p[N], n, m, k, f, d[N];
void dfs(int v, int c){
    col[v] = c;
    for(auto u : ad[v]){
        if(col[u] && col[u] == c){
            f = 1;
            return;
        }
        if(!col[u])
            dfs(u, 3 - c);
    }
}

void dfss(int v, int dep){
    vis[v] = 1;
    d[v] = dep;
    for(auto u : ad[v]){
        if(u == p[v])continue;
        if(vis[u]){
            if(d[v] > d[u]){
                int da = d[v] - d[u] + 1;
                if(da <= k){
                    vector<int>t;
                    int cur = v;
                    while(cur != u)t.push_back(cur), cur = p[cur];
                    t.push_back(u);
                    printf("%d\n%d\n", 2, (int)t.size());
                    for(auto u : t)printf("%d ", u);
                    puts("");
                    exit(0);
                }
            }
        }else{
            p[u] = v;
            dfss(u, dep + 1);
        }
    }
}

int main(){
    //freopen("output.in","r",stdin);
    //freopen("output.txt","w",stdout);
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1; i <= m; i++){
        int x, y;
        scanf("%d%d", &x, &y);
        ad[x].push_back(y);
        ad[y].push_back(x);
    }
    dfs(1, 1);
    if(!f){
        int cntr = 0;
        for(int i = 1; i <= n; i++)if(col[i] == 2)cntr++;
        int need = (k + 1) / 2;
        int c = -1;
        if(cntr >= need)c = 2;
        else if(n - cntr >= need)c = 1;
        if(c == -1)goto fin;
        puts("1");
        for(int i = 1; i <= n; i++)
            if(col[i] == c)printf("%d ", i);
        puts("");
        return 0;
    }
    fin:;
    dfss(1, 1);
    puts("1");
    vector<int>o, e;
    for(int i = 1; i <= n; i++)if(d[i]&1)o.push_back(i);else e.push_back(i);
    if(o.size() >= (k + 1) / 2){
        for(int i = 0; i < (k + 1) / 2; i++)
            printf("%d ", o[i]);
        puts("");
    }else{
        for(int i = 0; i < (k + 1) / 2; i++)
            printf("%d ", e[i]);
        puts("");
    }
    return 0;
}