#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <cstdio>
#include <cmath>
#include <map>
#include <set>
#include <assert.h>
#include <queue>
#include <cstring>
#include <numeric>
#include <hash_map>

using namespace std;

typedef unsigned long long ll;
#define mp make_pair

ll n, m;

ll l2(ll t)
{
	ll cur = 1;
	ll step = 1;
	while (cur * 2 <= t)
		cur *= 2, step++;
	return step;
}

struct T
{
	ll q, w;
};

bool cmp(T a, T b)
{
	if (a.w != b.w)
		return a.w < b.w;
	return a.q < b.q;
}

const ll N = 2e6 + 100;

T a[N];

ll f(ll t)
{
	if (t & 1)
		return t * (t - 1) / 2;
	return t * (t - 1) / 2 + t / 2;
}

int main()
{

	cin >> n >> m;

	for (ll i = 0; i < m; i++)
		cin >> a[i].q >> a[i].w;
	sort(a, a + m, cmp);
	reverse(a, a + m);
	ll ans = 0;
	ll r = 0;
	for (ll i = 1; 1; i++)
	{
		if (f(i + 1) > n)
		{
			r = i;
			break;
		}
	}
	for (ll i = 0; i < min(r + 1, m); i++)
		ans += a[i].w;
	cout << ans;

	return 0;
}


#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <cstdio>
#include <cmath>
#include <map>
#include <set>
#include <assert.h>
#include <queue>
#include <cstring>
#include <numeric>
#include <hash_map>

using namespace std;

typedef unsigned long long ll;
#define mp make_pair

ll n, m;

struct T
{
	ll q, w;
};

bool cmp(T a, T b)
{
	if (a.w != b.w)
		return a.w < b.w;
	return a.q < b.q;
}

const ll N = 2e6 + 100;

T a[N];

ll f(ll t)
{
	if (t & 1)
		return t * (t - 1) / 2;
	return t * (t - 1) / 2 + t / 2 - 1;
}

int main()
{

	cin >> n >> m;

	for (ll i = 0; i < m; i++)
		cin >> a[i].q >> a[i].w;
	sort(a, a + m, cmp);
	reverse(a, a + m);
	ll ans = 0;
	ll r = 0;
	for (ll i = 1; 1; i++)
	{
		if (f(i + 1) >= n)
		{
			r = i;
			break;
		}
	}
	for (ll i = 0; i < min(r, m); i++)
		ans += a[i].w;
	cout << ans;

	return 0;
}


#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <cstdio>
#include <cmath>
#include <map>
#include <set>
#include <assert.h>
#include <queue>
#include <cstring>
#include <numeric>
#include <hash_map>

using namespace std;

typedef unsigned long long ll;
#define mp make_pair

ll n, m;

struct T
{
	ll q, w;
};

bool cmp(T a, T b)
{
	if (a.w != b.w)
		return a.w < b.w;
	return a.q < b.q;
}

const ll N = 2e6 + 100;

T a[N];

ll f(ll t)
{
	if (t & 1)
		return t * (t - 1) / 2;
	return t * (t - 1) / 2 + t / 2 - 1;
}

int main()
{

	cin >> n >> m;

	for (ll i = 0; i < m; i++)
		cin >> a[i].q >> a[i].w;
	sort(a, a + m, cmp);
	reverse(a, a + m);
	ll ans = 0;
	ll r = 0;
	for (ll i = 0; 1; i++)
	{
		if (f(i + 1) > n)
		{
			r = i;
			break;
		}
	}
	for (ll i = 0; i < min(r, m); i++)
		ans += a[i].w;
	cout << ans;

	return 0;
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;

typedef long long ll;

int n, m;
int a[100010];

ll need(int k) {
    if (k&1) return k*ll(k-1)/2 + 1;
    else return k*ll(k-1)/2 + k/2;
}

int main() {
    for(int i = 1; i <= 10; i++) printf("%d\n", need(i));
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= m; i++) scanf("%d%d", a+i, a+i);
    sort(a+1, a+1+m, greater<int>());
    ll ret = 0;
    for(int i = 1; i <= m; i++) {
        if (need(i) > n) break;
        ret += a[i];
    }
    printf("%I64d", ret);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;

typedef long long ll;

int n, m;
int a[100010];

ll need(int k) {
    if (k&1) return k*ll(k-1)/2 + 1;
    else return k*ll(k-1)/2 + k/2 + 1;
}

int main() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= m; i++) scanf("%d%d", a+i, a+i);
    sort(a+1, a+1+m, greater<int>());
    ll ret = 0;
    for(int i = 1; i <= m; i++) {
        if (need(i) > n) break;
        ret += a[i];
    }
    printf("%I64d", ret);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;

int n, m;
int f[100010];
int a[100010];

int main() {

    scanf("%d%d", &n, &m);
    for(int i = 1; i <= m; i++) {
        scanf("%d", a+i);
        scanf("%d", a+i);
    }
    sort(a+1, a+1+m, greater<int>());
    f[1] = 1;
    f[2] = 2;
    for(int i = 3; i <= m; i++) f[i] = f[i-1] + 2*(i-2);
    long long ret = 0;
    for(int i = 1; i <= m; i++) {
        if (f[i] > n) break;
        ret += a[i];
    }
    printf("%I64d", ret);

    return 0;
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;

int n, m;
long long f[100010];
int a[100010];

int main() {

    scanf("%d%d", &n, &m);
    f[1] = 1;
    f[2] = 2;
    for(int i = 3; i <= m; i++)
        f[i] = f[i-1] + 2*(i-2);
    for(int i = 1; i <= m; i++) {
        scanf("%d", a+i);
        scanf("%d", a+i);
    }
    sort(a+1, a+1+m, greater<int>());

    long long ret = 0;
    for(int i = 1; i <= m; i++) {
        if (f[i] > n) break;
        ret += a[i];
    }
    printf("%I64d", ret);

    return 0;
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;

typedef long long ll;

int n, m;
int a[100010];

ll need(int k) {
    if (k&1) return k*ll(k-1)/2 + 1;
    else return k*ll(k-1)/2 + k/2;
}

int main() {
    //for(int i = 1; i <= 10; i++) printf("%d\n", need(i));
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= m; i++) scanf("%d%d", a+i, a+i);
    sort(a+1, a+1+m, greater<int>());
    ll ret = 0;
    for(int i = 1; i <= m; i++) {
        if (need(i) > n) break;
        ret += a[i];
    }
    printf("%I64d", ret);
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <string>
using namespace std;

bool file = 0;

long long n, m;
long long w[100100];

long long q;

int main()
{
    if(file)
    {
        freopen("inp.in","r",stdin);
        freopen("inp.out","w",stdout);
    }

    cin >> n >> m;
    for (int i = 0; i < m; i++)
        cin >> q >> w[i];

    sort(w, w + m);
    reverse(w, w + m);

    while(m)
    {
        long long min_n_for_m;
        if(m % 2)
            min_n_for_m = m * (m - 1) / 2 + 1;
        else
            min_n_for_m = m * (m - 1) / 2 + m / 2;
        if(min_n_for_m <= n)
            break;
        m--;
    }

    long long ans = 0;
    for (int i = 0; i < m; i++)
        ans += w[i];

    cout << ans << endl;

    return 0;
}


#include<iostream>
#include<algorithm>
using namespace std;
int mallow(int e) {
	if(e%2 == 1) return e*(e-1)/2 + 1;
	return e*(e-1)/2 + 1 + (e/2 - 1);
}
int main() {
	int n, m, p, w[100000], sz;
	long long sum=0;
	cin >> n >> m;
	for(int i=0;i<m;i++) cin >> p >> w[i];
	sort(w, w+m);
	reverse(w, w+m);
	for(sz=1;mallow(sz) <= n && sz <= m;sz++);
	sz--;
	for(int i=0;i<sz;i++)
		sum += w[i];
	cout << sum << '\n';
	return 0;
}


#include<iostream>
#include<algorithm>
using namespace std;
int mallow(int e) {
	if(e%2 == 1) return e*(e-1)/2 + 1;
	return e*(e-1)/2 + 1 + max((e-3), 0);
}
int main() {
	int n, m, p, w[100000], sz;
	long long sum=0;
	cin >> n >> m;
	for(int i=0;i<m;i++) cin >> p >> w[i];
	sort(w, w+m);
	reverse(w, w+m);
	for(sz=1;mallow(sz) <= n && sz <= m;sz++);
	sz--;
	for(int i=0;i<sz;i++)
		sum += w[i];
	cout << sum << '\n';
	return 0;
}


#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < (n); ++i)
#define srep(i,s,t) for (int i = s; i < t; ++i)
#define drep(i,n) for(int i = (n)-1; i >= 0; --i)
using namespace std;
typedef long long int ll;
typedef pair<int,int> P;
#define yn {puts("Yes");}else{puts("No");}
#define MAX_N 200005

int main() {
    srand((unsigned) time(NULL));
    int n;
    cin >> n;
    int a[n+1] = {};
    int b[n+1] = {};

    if(n <= 3){
        cout << 0 << endl;
        fflush(stdout);
        return 0;
    }

    int ma = 0;
    int argma = 0;

    srep(i,1,10000){
        if(n/(i+1) <= 1)break;
        int tmp = (n/(i+1))*i - i;
        if(tmp > ma){
            ma = tmp;
            argma = i;
        }
    }

    argma++;
    srep(i,1,n+1){
        if(i % argma != 0){
            b[i] = 1;
        }
    }

    while(true){
        int cnt = 0;
        vector<int> v;
        srep(i,1,n+1){
            if(b[i] == 1 && a[i] == 0){
                cnt++;
                v.push_back(i);
                a[i] = 1;
            }
        }
        if(cnt == 0)break;
        cout << cnt << ' ';
        rep(i,cnt){
            cout << v[i];
            if(i == cnt - 1)cout << endl;
            else cout << ' ';
        }
        fflush(stdout);
        int x;
        cin >> x;
        /*
        int argma = 1;
        int ma = -1;
        srep(i,1,n+1){
            int y = i;
            int tmpma = 0;
            rep(j,cnt){
                tmpma += a[y];
                y++;
                if(y > n)y = 1;
            }
            if(tmpma > ma){
                ma = tmpma;
                argma = i;
            }
        }
        x = argma;
        */

        int cnt2 = 0;
        rep(i,cnt){
            if(a[x] == 1){
                cnt2++;
                a[x] = 0;
            }
            x++;
            if(x > n)x = 1;
        }
        if(cnt2 == cnt)break;
    }

    /*
    int two = 1;
    int sum = 0;
    int xx = 1;
    rep(looop,20){
        two *= 2;
        int addd = 0;
        srep(i,1,n+1){
            if(i%two == (two/2)){
                b[i] = 1;
                sum++;
                addd++;
            }
        }
        if(addd == 0)break;

        int tyokin = 0;

    }
    */
    cout << 0 << endl;
    fflush(stdout);

    int ans = 0;
    srep(i,1,n+1){
        ans += a[i];
    }
    // cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < (n); ++i)
#define srep(i,s,t) for (int i = s; i < t; ++i)
#define drep(i,n) for(int i = (n)-1; i >= 0; --i)
using namespace std;
typedef long long int ll;
typedef pair<int,int> P;
#define yn {puts("Yes");}else{puts("No");}
#define MAX_N 200005

int main() {
    int n;
    cin >> n;
    int a[n+1] = {};

    if(n <= 3){
        cout << 0 << endl;
        fflush(stdout);
        return 0;
    }

    rep(loop, n/2-1){

        int check_cnt = 0;
        srep(i,1,n+1){
            if(a[i] == 1)check_cnt++;
        }
        if(check_cnt >= n/2-1)break;

        cout << 2 << ' ';
        int cnt = 0;
        srep(i,1,n+1){
            if(i%2 == 1 && a[i] == 0){
                cout << i;
                cnt++;
                if(cnt == 1) cout << ' ';
                else cout << endl;
                a[i] = 1;
                if(cnt == 2)break;
            }
        }
        fflush(stdout);
        int x;
        cin >> x;
        a[x] = 0;
        x++;
        if(x > n){
            x = 1;
        }
        a[x] = 0;
    }

    int cnt = 0;
    srep(i,1,n+1){
        if(a[i] == 0){
            cnt++;
        }
    }

    cout << (cnt+1)/2 << ' ';

    int cnt2 = 0;
    int cnt3 = (cnt+1)/2;
    srep(i,1,n+1){
        if(a[i] == 0){
            if(cnt2 % 2 == 0){
                cout << i;
                cnt3--;
                if(cnt3 == 0)cout << endl;
                else cout << ' ';
            }
            cnt2++;
        }
        fflush(stdout);
    }
    int x;
    cin >> x;

    cout << 0 << endl;
    fflush(stdout);
    return 0;
}


#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < (n); ++i)
#define srep(i,s,t) for (int i = s; i < t; ++i)
#define drep(i,n) for(int i = (n)-1; i >= 0; --i)
using namespace std;
typedef long long int ll;
typedef pair<int,int> P;
#define yn {puts("Yes");}else{puts("No");}
#define MAX_N 200005

int main() {
    int n;
    cin >> n;
    int a[n+1] = {};

    if(n <= 3){
        cout << 0 << endl;
        fflush(stdout);
        return 0;
    }

    rep(loop, n/2-1){
        cout << 2 << ' ';
        int cnt = 0;
        srep(i,1,n+1){
            if(i%2 == 1 && a[i] == 0){
                cout << i;
                cnt++;
                if(cnt == 1) cout << ' ';
                else cout << endl;
                a[i] = 1;
                if(cnt == 2)break;
            }
        }
        fflush(stdout);
        int x;
        cin >> x;
        a[x] = 0;
        x++;
        if(x > n){
            x = 1;
        }
        a[x] = 0;
    }

    int cnt = 0;
    srep(i,1,n+1){
        if(a[i] == 0){
            cnt++;
        }
    }

    cout << cnt << ' ';
    srep(i,1,n+1){
        if(a[i] == 0){
            cout << i;
            cnt--;
            if(cnt == 0)cout << endl;
            else cout << ' ';
        }
        fflush(stdout);
    }
    int x;
    cin >> x;

    cout << 0 << endl;
    fflush(stdout);
    return 0;
}


#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < (n); ++i)
#define srep(i,s,t) for (int i = s; i < t; ++i)
#define drep(i,n) for(int i = (n)-1; i >= 0; --i)
using namespace std;
typedef long long int ll;
typedef pair<int,int> P;
#define yn {puts("Yes");}else{puts("No");}
#define MAX_N 200005

int main() {
    int n;
    cin >> n;
    int a[n+1] = {};

    if(n <= 3){
        cout << 0 << endl;
        fflush(stdout);
        return 0;
    }

    rep(loop, n/2-1){

        int check_cnt = 0;
        srep(i,1,n+1){
            if(a[i] == 1)check_cnt++;
        }
        if(check_cnt >= n/2-1)break;

        cout << 2 << ' ';
        int cnt = 0;
        srep(i,1,n+1){
            if(i%2 == 1 && a[i] == 0){
                cout << i;
                cnt++;
                if(cnt == 1) cout << ' ';
                else cout << endl;
                a[i] = 1;
                if(cnt == 2)break;
            }
        }
        fflush(stdout);
        int x;
        cin >> x;
        a[x] = 0;
        x++;
        if(x > n){
            x = 1;
        }
        a[x] = 0;
    }

    int cnt = 0;
    srep(i,1,n+1){
        if(a[i] == 0){
            cnt++;
        }
    }

    cout << (cnt)/2 << ' ';

    int cnt2 = 0;
    int cnt3 = (cnt)/2;
    srep(i,1,n+1){
        if(a[i] == 0){
            if(cnt2 % 2 == 0){
                cout << i;
                cnt3--;
                if(cnt3 == 0){
                    cout << endl;
                    break;
                }
                else cout << ' ';
            }
            cnt2++;
        }
    }
    fflush(stdout);
    int x;
    cin >> x;

    cout << 0 << endl;
    fflush(stdout);
    return 0;
}


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

int main() {
    int n;
    cin >> n;
    vector<bool> on(n / 2);
    for (;;) {
        int off = 0;
        for (int i = 0; i < n / 2; i++) {
            if (not on.at(i)) off++;
        }
        if (off <= 1) {
            cout << 0 << endl;
            return 0;
        }
        cout << off;
        for (int i = 0; i < n / 2; i++) {
            if (not on.at(i)) {
                on.at(i) = true;
                cout << " " << 2 * i + 2;
            }
        }
        cout << endl;
        int x;
        cin >> x;
        if (x == -1) {
            return 0;
        }
        for (int i = 0; i < n / 2; i++) {
            int m = 2 * i + 2;
            if ((x <= m and m < x + off) or (x - n <= m and m < x - n + off)) {
                on.at(i) = false;
            }
        }
    }
}


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

int main() {
    int n;
    cin >> n;
    vector<bool> on(n / 2);
    for (;;) {
        int off = 0;
        for (int i = 0; i < n / 2; i++) {
            if (not on.at(i)) off++;
        }
        if (off <= 1) {
            cout << 0 << endl;
            return 0;
        }
        cout << off;
        for (int i = 0; i < n / 2; i++) {
            if (not on.at(i)) {
                on.at(i) = true;
                cout << " " << 2 * i + 2;
            }
        }
        cout << endl;
        int x;
        cin >> x;
        if (x == -1) {
            return 0;
        }
        for (int i = 0; i < n / 2; i++) {
            int m = 2 * i + 2;
            if ((x <= m and m < x + off) or (x + off - n <= m and m < x + off - n)) {
                on.at(i) = false;
            }
        }
    }
}


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

int main() {
    int n;
    cin >> n;
    vector<bool> on(n / 2);
    for (;;) {
        int off = 0;
        for (int i = 0; i < n / 2; i++) {
            if (not on.at(i)) off++;
        }
        if (off <= 1) {
            cout << 0 << endl;
            return 0;
        }
        cout << off;
        for (int i = 0; i < n / 2; i++) {
            if (not on.at(i)) {
                on.at(i) = true;
                cout << " " << 2 * i + 2;
            }
        }
        cout << endl;
        int x;
        cin >> x;
        if (x == -1) {
            for (;;);
        }
        for (int i = 0; i < n / 2; i++) {
            int m = 2 * i + 2;
            if ((x <= m and m < x + off) or m + n < x + off) {
                on.at(i) = false;
            }
        }
    }
}


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

int main() {
    int n, k = 1;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        if ((n - 1) / i + i < (n - 1) / k + k) k = i;
    }
    vector<bool> on(n);
    for (;;) {
        int off = 0;
        for (int i = 0; i < n; i++) {
            if (i % k == 0) continue;
            if (not on.at(i)) off++;
        }
        if (off < k) {
            cout << 0 << endl;
            return 0;
        }
        cout << off;
        for (int i = 0; i < n; i++) {
            if (i % k == 0) continue;
            if (not on.at(i)) {
                on.at(i) = true;
                cout << " " << i + 1;
            }
        }
        cout << endl;
        int x;
        cin >> x;
        if (x == -1) {
            return 0;
        }
        for (int i = 0; i < n; i++) {
            int m = i + 1;
            if ((x <= m and m < x + off) or m < x - n + off) {
                on.at(i) = false;
            }
        }
    }
}


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

int main() {
    int n;
    cin >> n;
    vector<bool> on(n / 2);
    for (;;) {
        int off = 0;
        for (int i = 0; i < n / 2; i++) {
            if (not on.at(i)) off++;
        }
        if (off == 1) {
            cout << 0 << endl;
            return 0;
        }
        cout << off;
        for (int i = 0; i < n / 2; i++) {
            if (not on.at(i)) {
                on.at(i) = true;
                cout << " " << 2 * i + 2;
            }
        }
        cout << endl;
        int x;
        cin >> x;
        if (x == -1) {
            return 0;
        }
        for (int i = 0; i < n / 2; i++) {
            int m = 2 * i + 2;
            if ((x <= m and m < x + off) or m + n < x + off) {
                on.at(i) = false;
            }
        }
    }
}


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

int main() {
    int n;
    cin >> n;
    vector<bool> on(n / 2);
    for (;;) {
        int off = 0;
        for (int i = 0; i < n / 2; i++) {
            if (not on.at(i)) off++;
        }
        if (off <= 1) {
            cout << 0 << endl;
            return 0;
        }
        cout << off;
        for (int i = 0; i < n / 2; i++) {
            if (not on.at(i)) {
                on.at(i) = true;
                cout << " " << 2 * i + 2;
            }
        }
        cout << endl;
        int x;
        cin >> x;
        if (x == -1) {
            return 0;
        }
        for (int i = 0; i < n / 2; i++) {
            int m = 2 * i + 2;
            if ((x <= m and m < x + off) or m + n < x + off) {
                on.at(i) = false;
            }
        }
    }
}


#include <stdio.h>
#include <vector>
using namespace std;

int N, C; bool O[1010];

int main()
{
	scanf ("%d", &N);
	if (N > 3){
		if (N <= 5){
			puts("2 1 3"); fflush(stdout);
			scanf ("%*d");
		}
		else{
			vector<int> cand;
			C = N / 2 - 1;

			for (int i = 0; i < N; i++) if (i % C) cand.push_back(i + 1);

			for (int k = 0; k < 10000 && cand.size() >= C; k++){
				printf ("%d", C);
				for (int i = 0; i < C; i++){
					printf (" %d", cand.back());
					O[cand.back()] = 1;
					cand.pop_back();
				}
				puts("");
				fflush(stdout);
				int p; scanf ("%d", &p);

				for (int k = 0; k < C; k++){
					int z = ((p - 1) + k) % N + 1;
					if (O[z]){
						cand.push_back(z);
						O[z] = false;
					}
				}
			}
		}
	}

	puts("0");
	fflush(stdout);
	return 0;
}


#include <stdio.h>
#include <vector>
using namespace std;

int N, C; bool O[1010];

int main()
{
	scanf ("%d", &N);
	if (N > 3){
		if (N <= 5){
			puts("2 1 3"); fflush(stdout);
			scanf ("%*d");
		}
		else{
			vector<int> cand;
			C = N / 2 - 1;
			int z = (N + C - 1) / C;
			int d = N / z;

			for (int i = 0; i < N; i++) if (i % d) cand.push_back(i + 1);

			for (int k = 0; k < 10000 && cand.size() >= C; k++){
				printf ("%d", C);
				for (int i = 0; i < C; i++){
					printf (" %d", cand.back());
					O[cand.back()] = 1;
					cand.pop_back();
				}
				puts("");
				fflush(stdout);
				int p; scanf ("%d", &p);

				for (int k = 0; k < C; k++){
					int z = ((p - 1) + k) % N + 1;
					if (O[z]){
						cand.push_back(z);
						O[z] = false;
					}
				}
			}
		}
	}

	puts("0");
	fflush(stdout);
	return 0;
}


#include <stdio.h>
#include <vector>
using namespace std;

int N, C; bool O[1010];

int main()
{
	scanf ("%d", &N);
	if (N > 3){
		if (N <= 5){
			puts("2 1 3"); fflush(stdout);
			scanf ("%*d");
		}
		else{
			vector<int> cand;

			C = (N + 2) / 3;

			for (int i = 0; i < N; i++) if (i % C) cand.push_back(i + 1);

			for (int k = 0; k < 10000 && cand.size() >= C; k++){
				printf ("%d", C);
				for (int i = 0; i < C; i++){
					printf (" %d", cand.back());
					O[cand.back()] = 1;
					cand.pop_back();
				}
				puts("");
				fflush(stdout);
				int p; scanf ("%d", &p);

				for (int k = 0; k < C; k++){
					int z = ((p - 1) + k) % N + 1;
					if (O[z]){
						cand.push_back(z);
						O[z] = false;
					}
				}
			}

			printf ("%d", cand.size());
			while (!cand.empty()){
				printf (" %d", cand.back());
				O[cand.back()] = 1;
				cand.pop_back();
			}
			puts("");
			fflush(stdout);
			scanf ("%*d");
		}
	}

	puts("0");
	fflush(stdout);
	return 0;
}


#include <stdio.h>
#include <vector>
using namespace std;

int N, C; bool O[1010];

int main()
{
	scanf ("%d", &N);
	if (N > 3){
		if (N <= 5){
			puts("2 1 3"); fflush(stdout);
			scanf ("%*d");
		}
		else{
			vector<int> cand;
			C = N / 2 - 1;
			int z = (N + C - 1) / C;
			C = (N + z - 1) / z;

			for (int i = 0; i < N; i++) if (i % C) cand.push_back(i + 1);

			for (int k = 0; k < 10000 && cand.size() >= C; k++){
				printf ("%d", C);
				for (int i = 0; i < C; i++){
					printf (" %d", cand.back());
					O[cand.back()] = 1;
					cand.pop_back();
				}
				puts("");
				fflush(stdout);
				int p; scanf ("%d", &p);

				for (int k = 0; k < C; k++){
					int z = ((p - 1) + k) % N + 1;
					if (O[z]){
						cand.push_back(z);
						O[z] = false;
					}
				}
			}
		}
	}

	puts("0");
	fflush(stdout);
	return 0;
}


#include <stdio.h>
#include <vector>
using namespace std;

int N, C; bool O[1010];

int main()
{
	scanf ("%d", &N);
	if (N > 3){
		if (N <= 5){
			puts("2 1 3"); fflush(stdout);
			scanf ("%*d");
		}
		else{
			vector<int> cand;

			C = (N + 1) / 2;

			for (int i = 0; i < N; i++) if (i % C) cand.push_back(i + 1);

			for (int k = 0; k < 10000 && cand.size() >= C; k++){
				printf ("%d", C);
				for (int i = 0; i < C; i++){
					printf (" %d", cand.back());
					O[cand.back()] = 1;
					cand.pop_back();
				}
				puts("");
				fflush(stdout);
				int p; scanf ("%d", &p);

				for (int k = 0; k < C; k++){
					int z = ((p - 1) + k) % N + 1;
					if (O[z]){
						cand.push_back(z);
						O[z] = false;
					}
				}
			}

			if (!cand.empty()){
				printf ("%d", cand.size());
				while (!cand.empty()){
					printf (" %d", cand.back());
					cand.pop_back();
				}
				puts("");
				fflush(stdout);
				scanf ("%*d");
			}
		}
	}

	puts("0");
	fflush(stdout);
	return 0;
}


#include <stdio.h>
#include <vector>
using namespace std;

int N, C; bool O[1010];

int main()
{
	scanf ("%d", &N);
	if (N > 3){
		if (N <= 5){
			puts("2 1 3"); fflush(stdout);
			scanf ("%*d");
		}
		else{
			vector<int> cand;

			C = (N + 2) / 3;

			for (int i = 0; i < N; i++) if (i % C) cand.push_back(i + 1);

			for (int k = 0; k < 10000 && cand.size() >= C; k++){
				printf ("%d", C);
				for (int i = 0; i < C; i++){
					printf (" %d", cand.back());
					O[cand.back()] = 1;
					cand.pop_back();
				}
				puts("");
				fflush(stdout);
				int p; scanf ("%d", &p);

				for (int k = 0; k < C; k++){
					int z = ((p - 1) + k) % N + 1;
					if (O[z]){
						cand.push_back(z);
						O[z] = false;
					}
				}
			}

			if (!cand.empty()){
				printf ("%d", cand.size());
				while (!cand.empty()){
					printf (" %d", cand.back());
					cand.pop_back();
				}
				puts("");
				fflush(stdout);
				scanf ("%*d");
			}
		}
	}

	puts("0");
	fflush(stdout);
	return 0;
}


#include <stdio.h>
#include <vector>
using namespace std;

int N, C; bool O[1010];

int main()
{
	scanf ("%d", &N);
	if (N > 3){
		if (N <= 5){
			puts("2 1 3"); fflush(stdout);
			scanf ("%*d");
		}
		else{
			vector<int> cand;
			C = N / 2 - 1;
			int z = (N + C - 1) / C;
			int d = (N + z - 1) / z;

			for (int i = 0; i < N; i++) if (i % d) cand.push_back(i + 1);

			for (int k = 0; k < 10000 && cand.size() >= C; k++){
				printf ("%d", C);
				for (int i = 0; i < C; i++){
					printf (" %d", cand.back());
					O[cand.back()] = 1;
					cand.pop_back();
				}
				puts("");
				fflush(stdout);
				int p; scanf ("%d", &p);

				for (int k = 0; k < C; k++){
					int z = ((p - 1) + k) % N + 1;
					if (O[z]){
						cand.push_back(z);
						O[z] = false;
					}
				}
			}
		}
	}

	puts("0");
	fflush(stdout);
	return 0;
}


#include <stdio.h>
#include <vector>
using namespace std;

int N, C; bool O[1010];

int main()
{
	scanf ("%d", &N);
	if (N > 3){
		if (N <= 5){
			puts("2 1 3"); fflush(stdout);
			scanf ("%*d");
		}
		else{
			vector<int> cand;

			C = 1;
			while (C * C <= N) C++; C--;

			for (int i = 0; i < N; i++) if (i % C) cand.push_back(i + 1);

			for (int k = 0; k < 10000 && cand.size() >= C; k++){
				printf ("%d", C);
				for (int i = 0; i < C; i++){
					printf (" %d", cand.back());
					O[cand.back()] = 1;
					cand.pop_back();
				}
				puts("");
				fflush(stdout);
				int p; scanf ("%d", &p);

				for (int k = 0; k < C; k++){
					int z = ((p - 1) + k) % N + 1;
					if (O[z]){
						cand.push_back(z);
						O[z] = false;
					}
				}
			}

			if (!cand.empty()){
				printf ("%d", cand.size());
				while (!cand.empty()){
					printf (" %d", cand.back());
					cand.pop_back();
				}
				puts("");
				fflush(stdout);
				scanf ("%*d");
			}
		}
	}

	puts("0");
	fflush(stdout);
	return 0;
}


#include <stdio.h>
#include <vector>
using namespace std;

int N, C; bool O[1010];

int main()
{
	scanf ("%d", &N);
	if (N > 3){
		if (N <= 5){
			puts("2 1 3"); fflush(stdout);
			scanf ("%*d");
		}
		else{
			vector<int> cand;

			C = (N + 2) / 3;

			for (int i = 0; i < N; i++) if (i % C) cand.push_back(i + 1);

			for (int k = 0; k < 10000 && cand.size() >= C; k++){
				printf ("%d", C);
				for (int i = 0; i < C; i++){
					printf (" %d", cand.back());
					O[cand.back()] = 1;
					cand.pop_back();
				}
				puts("");
				fflush(stdout);
				int p; scanf ("%d", &p);

				for (int k = 0; k < C; k++){
					int z = ((p - 1) + k) % N + 1;
					if (O[z]){
						cand.push_back(z);
						O[z] = false;
					}
				}
			}
		}
	}

	puts("0");
	fflush(stdout);
	return 0;
}


#include <stdio.h>
#include <vector>
using namespace std;

int N, C; bool O[1010];

int main()
{
	scanf ("%d", &N);
	if (N > 3){
		if (N <= 5){
			puts("2 1 3"); fflush(stdout);
			scanf ("%*d");
		}
		else{
			vector<int> cand;
			C = N / 2 - 1;

			for (int i = 0; i < N; i++) if (i % C) cand.push_back(i + 1);

			for (int k = 0; k < 10000 && cand.size() >= C; k++){
				printf ("%d", C);
				for (int i = 0; i < C; i++){
					printf (" %d", cand.back());
					O[cand.back()] = 1;
					cand.pop_back();
				}
				puts("");
				fflush(stdout);
				int p; scanf ("%d", &p);

				for (int k = 0; k < 2; k++){
					int z = ((p - 1) + k) % N + 1;
					if (O[z]){
						cand.push_back(z);
						O[z] = false;
					}
				}
			}
		}
	}

	puts("0");
	fflush(stdout);
	return 0;
}


#include <stdio.h>
#include <vector>
using namespace std;

int N, C; bool O[1010];

int main()
{
	scanf ("%d", &N);
	if (N > 3){
		vector<int> cand;
		C = N / 2 - 1;

		int v = 1, c = 0;
		while (c < C){
			cand.push_back(v);
			v += 2; c++;
		}

		while (1){
			int x = cand.back(); cand.pop_back();
			int y = -1; bool ed = false;
			if (cand.empty()){
				y = v;
				ed = true;
			}
			else{
				y = cand.back(); cand.pop_back();
			}
			printf ("2 %d %d\n", x, y);
			fflush(stdout);
			int p; scanf ("%d", &p);
			if (ed) break;

			O[x] = O[y] = true;
			for (int k = 0; k < 2; k++){
				int z = ((p - 1) + k) % N + 1;
				if (O[z]){
					cand.push_back(z);
					O[z] = false;
				}
			}
		}
	}

	puts("0");
	fflush(stdout);
	return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#pragma GCC optimize ("Ofast")
#pragma GCC optimization ("unroll-loops, no-stack-protector")
#pragma GCC target ("avx")
#pragma GCC target ("avx2")
#pragma GCC target ("fma")
#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define ll long long
#define ull unsigned long long
#define ld long double
#define pii pair <int, int>
#define pll pair <ll, ll>
#define pci pair <char, int>
#define pld pair <ld, ld>
#define ppld pair <pld, pld>
#define ppll pair <pll, pll>
#define pldl pair <ld, ll>
#define vll vector <ll>
#define vvll vector <vll>
#define vpll vector <pll>
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fi first
#define se second
#define mll map <ll, ll>
#define fastmap gp_hash_table
#define cd complex <double>
#define vcd vector <cd>
#define PI 3.14159265358979
#define ordered_set tree <ll, null_type, less <ll>, rb_tree_tag, tree_order_statistics_node_update>
#pragma 03
using namespace std;
using namespace __gnu_pbds;
// this is my best bet. there's no second...
// the idea is to divide it into subarrays of size k.
// (it seems to be correct... or not?)
bool token[1005];
bool frd[1005];
bool ntok[1005];
ll qry[1005];
int main(){
	ll n; cin >> n;
	if (n == 1 || n == 2 || n == 3){
		cout << 0 << endl; return 0;
	}
	ll mx = -1, k = -1;
	for (ll i = 1; i < n - 1; i++){
		ll grp = n / (i + 1);
		ll sel = grp * i;
		sel -= i;
		if (mx < sel){
			mx = sel; k = i;
		}
	}
	for (ll i = 0; i < n; i++) frd[i] = 1;
	// divide into subarrays of size k.
	ll tkn = n / (k + 1); tkn -= k;
	ll gcnt = n / (k + 1);
	for (ll i = 0; i < gcnt; i++){
		for (ll j = 0; j < k; j++) token[i * (k + 1) + j] = 1;
	}
	for (ll i = 0; i < tkn; i++){
		ll sz = 0;
		for (ll j = 0; j < n; j++) ntok[j] = 0;
		for (ll j = 0; j < n; j++){
			if (token[j] && frd[j] && (sz < k)){
				qry[sz] = j; frd[qry[sz]] = 0; ntok[j] = 1; sz++;
			}
		}
		for (ll j = 0; j < n; j++){
			if (token[j] && frd[j] && (!ntok[(j + n - 1) % n]) && (!ntok[(j + 1) % n]) && (sz <= k)){
				qry[sz] = j; frd[qry[sz]] = 0; sz++;
			}
		}
		cout << sz << " ";
		for (ll j = 0; j < sz; j++) cout << qry[j] + 1 << " ";
		cout << endl;
		ll x; cin >> x;
		for (ll j = x; j <= x + sz; j++) frd[j % n] = 1;
	}
	cout << 0 << endl; return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#pragma GCC optimize ("Ofast")
#pragma GCC optimization ("unroll-loops, no-stack-protector")
#pragma GCC target ("avx")
#pragma GCC target ("avx2")
#pragma GCC target ("fma")
#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define ll long long
#define ull unsigned long long
#define ld long double
#define pii pair <int, int>
#define pll pair <ll, ll>
#define pci pair <char, int>
#define pld pair <ld, ld>
#define ppld pair <pld, pld>
#define ppll pair <pll, pll>
#define pldl pair <ld, ll>
#define vll vector <ll>
#define vvll vector <vll>
#define vpll vector <pll>
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fi first
#define se second
#define mll map <ll, ll>
#define fastmap gp_hash_table
#define cd complex <double>
#define vcd vector <cd>
#define PI 3.14159265358979
#define ordered_set tree <ll, null_type, less <ll>, rb_tree_tag, tree_order_statistics_node_update>
#pragma 03
using namespace std;
using namespace __gnu_pbds;
// this is my best bet. there's no second...
// the idea is to divide it into subarrays of size k.
// (it seems to be correct... or not?)
bool token[1005];
bool frd[1005];
bool ntok[1005];
ll qry[1005];
int main(){
	ll n; cin >> n;
	if (n == 1 || n == 2 || n == 3){
		cout << 0 << endl; return 0;
	}
	ll mx = -1, k = -1;
	for (ll i = 1; i < n - 1; i++){
		ll grp = n / (i + 1);
		ll sel = grp * i;
		sel -= i;
		if (mx < sel){
			mx = sel; k = i;
		}
	}
	for (ll i = 0; i < n; i++) frd[i] = 1;
	// divide into subarrays of size k.
	ll tkn = n / (k + 1); tkn *= k; tkn -= k;
	ll gcnt = n / (k + 1);
	for (ll i = 0; i < gcnt; i++){
		for (ll j = 0; j < k; j++) token[i * (k + 1) + j] = 1;
	}
	for (ll i = 0; i < tkn; i++){
		ll sz = 0;
		for (ll j = 0; j < n; j++) ntok[j] = 0;
		for (ll j = 0; j < n; j++){
			if (token[j] && frd[j] && (sz <= k)){
				qry[sz] = j; frd[qry[sz]] = 0; ntok[j] = 1; sz++;
			}
		}
		cout << sz << " ";
		for (ll j = 0; j < sz; j++) cout << qry[j] + 1 << " ";
		cout << endl;
		ll x; cin >> x; x--;
		for (ll j = x; j < x + sz; j++) frd[j % n] = 1;
	}
	ll cntt = 0;
	for (ll i = 0; i < n; i++){
		if (!frd[i]) cntt++;
	}
	if (ccnt != tkn){
		return -1;
	}
	cout << 0 << endl; return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#pragma GCC optimize ("Ofast")
#pragma GCC optimization ("unroll-loops, no-stack-protector")
#pragma GCC target ("avx")
#pragma GCC target ("avx2")
#pragma GCC target ("fma")
#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define ll long long
#define ull unsigned long long
#define ld long double
#define pii pair <int, int>
#define pll pair <ll, ll>
#define pci pair <char, int>
#define pld pair <ld, ld>
#define ppld pair <pld, pld>
#define ppll pair <pll, pll>
#define pldl pair <ld, ll>
#define vll vector <ll>
#define vvll vector <vll>
#define vpll vector <pll>
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fi first
#define se second
#define mll map <ll, ll>
#define fastmap gp_hash_table
#define cd complex <double>
#define vcd vector <cd>
#define PI 3.14159265358979
#define ordered_set tree <ll, null_type, less <ll>, rb_tree_tag, tree_order_statistics_node_update>
#pragma 03
using namespace std;
using namespace __gnu_pbds;
// this is my best bet. there's no second...
// the idea is to divide it into subarrays of size k.
// (it seems to be correct... or not?)
bool token[1005];
bool frd[1005];
bool ntok[1005];
ll qry[1005];
int main(){
	ll n; cin >> n;
	if (n == 1 || n == 2 || n == 3){
		cout << 0 << endl; return 0;
	}
	ll mx = -1, k = -1;
	for (ll i = 1; i < n - 1; i++){
		ll grp = n / (i + 1);
		ll sel = grp * i;
		sel -= i;
		if (mx < sel){
			mx = sel; k = i;
		}
	}
	for (ll i = 0; i < n; i++) frd[i] = 1;
	// divide into subarrays of size k.
	ll tkn = n / (k + 1); tkn -= k;
	ll gcnt = n / (k + 1);
	for (ll i = 0; i < gcnt; i++){
		for (ll j = 0; j < k; j++) token[i * (k + 1) + j] = 1;
	}
	for (ll i = 0; i < tkn; i++){
		ll sz = 0;
		for (ll j = 0; j < n; j++) ntok[j] = 0;
		for (ll j = 0; j < n; j++){
			if (token[j] && frd[j] && (sz < k)){
				qry[sz] = j; frd[qry[sz]] = 0; ntok[j] = 1; sz++;
			}
		}
		for (ll j = 0; j < n; j++){
			if (token[j] && frd[j] && (!ntok[(j + n - 1) % n]) && (!ntok[(j + 1) % n]) && (sz <= k)){
				qry[sz] = j; frd[qry[sz]] = 0; sz++;
			}
		}
		cout << sz << " ";
		for (ll j = 0; j < sz; j++) cout << qry[j] + 1 << " ";
		cout << endl;
		ll x; cin >> x;
		for (ll j = x; j <= x + sz; j++) frd[j % n] = 1;
	}
	ll cntt = 0;
	for (ll i = 0; i < n; i++){
		if (!frd[i]) cntt++;
	}
	if (cntt != tkn){
		return -1;
	}
	cout << 0 << endl; return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#pragma GCC optimize ("Ofast")
#pragma GCC optimization ("unroll-loops, no-stack-protector")
#pragma GCC target ("avx")
#pragma GCC target ("avx2")
#pragma GCC target ("fma")
#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define ll long long
#define ull unsigned long long
#define ld long double
#define pii pair <int, int>
#define pll pair <ll, ll>
#define pci pair <char, int>
#define pld pair <ld, ld>
#define ppld pair <pld, pld>
#define ppll pair <pll, pll>
#define pldl pair <ld, ll>
#define vll vector <ll>
#define vvll vector <vll>
#define vpll vector <pll>
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fi first
#define se second
#define mll map <ll, ll>
#define fastmap gp_hash_table
#define cd complex <double>
#define vcd vector <cd>
#define PI 3.14159265358979
#define ordered_set tree <ll, null_type, less <ll>, rb_tree_tag, tree_order_statistics_node_update>
#pragma 03
using namespace std;
using namespace __gnu_pbds;
// this is my best bet. there's no second...
// the idea is to divide it into subarrays of size k.
// (it seems to be correct... or not?)
bool token[1005];
bool frd[1005];
bool ntok[1005];
ll qry[1005];
int main(){
	ll n; cin >> n;
	if (n == 1 || n == 2 || n == 3){
		cout << 0 << endl; return 0;
	}
	ll mx = -1, k = -1;
	for (ll i = 1; i < n - 1; i++){
		ll grp = n / (i + 1);
		ll sel = grp * i;
		sel -= i;
		if (mx < sel){
			mx = sel; k = i;
		}
	}
	for (ll i = 0; i < n; i++) frd[i] = 1;
	// divide into subarrays of size k.
	ll tkn = n / (k + 1); tkn *= k; tkn -= k;
	ll gcnt = n / (k + 1);
	for (ll i = 0; i < gcnt; i++){
		for (ll j = 0; j < k; j++) token[i * (k + 1) + j] = 1;
	}
	for (ll i = 0; i < tkn; i++){
		ll sz = 0;
		for (ll j = 0; j < n; j++) ntok[j] = 0;
		for (ll j = 0; j < n; j++){
			if (token[j] && frd[j] && (sz < k)){
				qry[sz] = j; frd[qry[sz]] = 0; ntok[j] = 1; sz++;
			}
		}
		for (ll j = 0; j < n; j++){
			if (token[j] && frd[j] && (!ntok[(j + n - 1) % n]) && (!ntok[(j + 1) % n]) && (sz <= k)){
				qry[sz] = j; frd[qry[sz]] = 0; sz++;
			}
		}
		cout << sz << " ";
		for (ll j = 0; j < sz; j++) cout << qry[j] + 1 << " ";
		cout << endl;
		ll x; cin >> x; x--;
		for (ll j = x; j < x + sz; j++) frd[j % n] = 1;
	}
	ll cntt = 0;
	for (ll i = 0; i < n; i++){
		if (!frd[i]) cntt++;
	}
	cout << 0 << endl; return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#pragma GCC optimize ("Ofast")
#pragma GCC optimization ("unroll-loops, no-stack-protector")
#pragma GCC target ("avx")
#pragma GCC target ("avx2")
#pragma GCC target ("fma")
#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define ll long long
#define ull unsigned long long
#define ld long double
#define pii pair <int, int>
#define pll pair <ll, ll>
#define pci pair <char, int>
#define pld pair <ld, ld>
#define ppld pair <pld, pld>
#define ppll pair <pll, pll>
#define pldl pair <ld, ll>
#define vll vector <ll>
#define vvll vector <vll>
#define vpll vector <pll>
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fi first
#define se second
#define mll map <ll, ll>
#define fastmap gp_hash_table
#define cd complex <double>
#define vcd vector <cd>
#define PI 3.14159265358979
#define ordered_set tree <ll, null_type, less <ll>, rb_tree_tag, tree_order_statistics_node_update>
#pragma 03
using namespace std;
using namespace __gnu_pbds;
// this is my best bet. there's no second...
// the idea is to divide it into subarrays of size k.
// (it seems to be correct... or not?)
bool token[1005];
bool frd[1005];
bool ntok[1005];
ll qry[1005];
int main(){
	ll n; cin >> n;
	if (n == 1 || n == 2 || n == 3){
		cout << 0 << endl; return 0;
	}
	ll mx = -1, k = -1;
	for (ll i = 1; i < n - 1; i++){
		ll grp = n / (i + 1);
		ll sel = grp * i;
		sel -= i;
		if (mx < sel){
			mx = sel; k = i;
		}
	}
	for (ll i = 0; i < n; i++) frd[i] = 1;
	// divide into subarrays of size k.
	ll tkn = n / (k + 1); tkn *= k; tkn -= k;
	ll gcnt = n / (k + 1);
	for (ll i = 0; i < gcnt; i++){
		for (ll j = 0; j < k; j++) token[i * (k + 1) + j] = 1;
	}
	for (ll i = 0; i < tkn; i++){
		ll sz = 0;
		for (ll j = 0; j < n; j++) ntok[j] = 0;
		for (ll j = 0; j < n; j++){
			if (token[j] && frd[j] && (sz < k)){
				qry[sz] = j; frd[qry[sz]] = 0; ntok[j] = 1; sz++;
			}
		}
		for (ll j = 0; j < n; j++){
			if (token[j] && frd[j] && (!ntok[(j + n - 1) % n]) && (!ntok[(j + 1) % n]) && (sz <= k)){
				qry[sz] = j; frd[qry[sz]] = 0; sz++;
			}
		}
		cout << sz << " ";
		for (ll j = 0; j < sz; j++) cout << qry[j] + 1 << " ";
		cout << endl;
		ll x; cin >> x; x--;
		for (ll j = x; j < x + sz; j++) frd[j % n] = 1;
	}
	ll cntt = 0;
	for (ll i = 0; i < n; i++){
		if (!frd[i]) cntt++;
	}
	if (cntt != tkn){
		return -1;
	}
	cout << 0 << endl; return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#pragma GCC optimize ("Ofast")
#pragma GCC optimization ("unroll-loops, no-stack-protector")
#pragma GCC target ("avx")
#pragma GCC target ("avx2")
#pragma GCC target ("fma")
#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define ll long long
#define ull unsigned long long
#define ld long double
#define pii pair <int, int>
#define pll pair <ll, ll>
#define pci pair <char, int>
#define pld pair <ld, ld>
#define ppld pair <pld, pld>
#define ppll pair <pll, pll>
#define pldl pair <ld, ll>
#define vll vector <ll>
#define vvll vector <vll>
#define vpll vector <pll>
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fi first
#define se second
#define mll map <ll, ll>
#define fastmap gp_hash_table
#define cd complex <double>
#define vcd vector <cd>
#define PI 3.14159265358979
#define ordered_set tree <ll, null_type, less <ll>, rb_tree_tag, tree_order_statistics_node_update>
#pragma 03
using namespace std;
using namespace __gnu_pbds;
// this is my best bet. there's no second...
// the idea is to divide it into subarrays of size k.
// (it seems to be correct... or not?)
bool token[1005];
bool frd[1005];
bool ntok[1005];
ll qry[1005];
int main(){
	ll n; cin >> n;
	if (n == 1 || n == 2 || n == 3){
		cout << 0 << endl; return 0;
	}
	ll mx = -1, k = -1;
	for (ll i = 1; i < n - 1; i++){
		ll grp = n / (i + 1);
		ll sel = grp * i;
		sel -= i;
		if (mx < sel){
			mx = sel; k = i;
		}
	}
	for (ll i = 0; i < n; i++) frd[i] = 1;
	// divide into subarrays of size k.
	ll tkn = n / (k + 1); tkn *= k; tkn -= k;
	ll gcnt = n / (k + 1);
	for (ll i = 0; i < gcnt; i++){
		for (ll j = 0; j < k; j++) token[i * (k + 1) + j] = 1;
	}
	for (ll i = 0; i < tkn; i++){
		ll sz = 0;
		for (ll j = 0; j < n; j++) ntok[j] = 0;
		for (ll j = 0; j < n; j++){
			if (token[j] && frd[j] && (sz <= k)){
				qry[sz] = j; frd[qry[sz]] = 0; ntok[j] = 1; sz++;
			}
		}
		cout << sz << " ";
		for (ll j = 0; j < sz; j++) cout << qry[j] + 1 << " ";
		cout << endl;
		ll x; cin >> x; x--;
		for (ll j = x; j < x + sz; j++) frd[j % n] = 1;
	}
	ll cntt = 0;
	for (ll i = 0; i < n; i++){
		if (!frd[i]) cntt++;
	}
	cout << 0 << endl; return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#pragma GCC optimize ("Ofast")
#pragma GCC optimization ("unroll-loops, no-stack-protector")
#pragma GCC target ("avx")
#pragma GCC target ("avx2")
#pragma GCC target ("fma")
#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define ll long long
#define ull unsigned long long
#define ld long double
#define pii pair <int, int>
#define pll pair <ll, ll>
#define pci pair <char, int>
#define pld pair <ld, ld>
#define ppld pair <pld, pld>
#define ppll pair <pll, pll>
#define pldl pair <ld, ll>
#define vll vector <ll>
#define vvll vector <vll>
#define vpll vector <pll>
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fi first
#define se second
#define mll map <ll, ll>
#define fastmap gp_hash_table
#define cd complex <double>
#define vcd vector <cd>
#define PI 3.14159265358979
#define ordered_set tree <ll, null_type, less <ll>, rb_tree_tag, tree_order_statistics_node_update>
#pragma 03
using namespace std;
using namespace __gnu_pbds;
// this is my best bet. there's no second...
// the idea is to divide it into subarrays of size k.
// (it seems to be correct... or not?)
bool token[1005];
bool frd[1005];
bool ntok[1005];
ll qry[1005];
int main(){
	ll n; cin >> n;
	if (n == 1 || n == 2 || n == 3){
		cout << 0 << endl; return 0;
	}
	ll mx = -1, k = -1;
	for (ll i = 1; i < n - 1; i++){
		ll grp = n / (i + 1);
		ll sel = grp * i;
		sel -= i;
		ll rem = n % (i + 1);
		sel += min(i, max(0LL, rem - 1));
		if (mx < sel){
			mx = sel; k = i;
		}
	}
	for (ll i = 0; i < n; i++) frd[i] = 1;
	// divide into subarrays of size k.
	ll tkn = n / (k + 1); tkn *= k; tkn -= k;
	ll rem = n % (k + 1); tkn += min(k, max(0LL, rem - 1));
	ll gcnt = n / (k + 1);
	for (ll i = 0; i < gcnt; i++){
		for (ll j = 0; j < k; j++) token[i * (k + 1) + j] = 1;
	}
	ll nd = (gcnt - 1) * (k + 1) + (k - 1);
	for (ll i = nd + 2; i < n - 1; i++) token[i] = 1;
	for (ll i = 0; i < tkn; i++){
		ll sz = 0;
		for (ll j = 0; j < n; j++) ntok[j] = 0;
		for (ll j = 0; j < n; j++){
			if (token[j] && frd[j] && (sz <= k)){
				qry[sz] = j; frd[qry[sz]] = 0; ntok[j] = 1; sz++;
			}
		}
		cout << sz << " ";
		for (ll j = 0; j < sz; j++) cout << qry[j] + 1 << " ";
		cout << endl;
		ll x; cin >> x; x--;
		for (ll j = x; j < x + sz; j++) frd[j % n] = 1;
	}
	ll cntt = 0;
	for (ll i = 0; i < n; i++){
		if (!frd[i]) cntt++;
	}
	cout << 0 << endl; return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#pragma GCC optimize ("Ofast")
#pragma GCC optimization ("unroll-loops, no-stack-protector")
#pragma GCC target ("avx")
#pragma GCC target ("avx2")
#pragma GCC target ("fma")
#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define ll long long
#define ull unsigned long long
#define ld long double
#define pii pair <int, int>
#define pll pair <ll, ll>
#define pci pair <char, int>
#define pld pair <ld, ld>
#define ppld pair <pld, pld>
#define ppll pair <pll, pll>
#define pldl pair <ld, ll>
#define vll vector <ll>
#define vvll vector <vll>
#define vpll vector <pll>
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fi first
#define se second
#define mll map <ll, ll>
#define fastmap gp_hash_table
#define cd complex <double>
#define vcd vector <cd>
#define PI 3.14159265358979
#define ordered_set tree <ll, null_type, less <ll>, rb_tree_tag, tree_order_statistics_node_update>
#pragma 03
using namespace std;
using namespace __gnu_pbds;
// this is my best bet. there's no second...
// the idea is to divide it into subarrays of size k.
// (it seems to be correct... or not?)
bool token[1005];
bool frd[1005];
bool ntok[1005];
ll qry[1005];
int main(){
	ll n; cin >> n;
	if (n == 1 || n == 2 || n == 3){
		cout << 0 << endl; return 0;
	}
	ll mx = -1, k = -1;
	for (ll i = 1; i < n - 1; i++){
		ll grp = n / (i + 1);
		ll sel = grp * i;
		sel -= i;
		if (mx < sel){
			mx = sel; k = i;
		}
	}
	for (ll i = 0; i < n; i++) frd[i] = 1;
	// divide into subarrays of size k.
	ll tkn = n / (k + 1); tkn *= k; tkn -= k;
	ll gcnt = n / (k + 1);
	for (ll i = 0; i < gcnt; i++){
		for (ll j = 0; j < k; j++) token[i * (k + 1) + j] = 1;
	}
	for (ll i = 0; i < tkn; i++){
		ll sz = 0;
		for (ll j = 0; j < n; j++) ntok[j] = 0;
		for (ll j = 0; j < n; j++){
			if (token[j] && frd[j] && (sz <= k)){
				qry[sz] = j; frd[qry[sz]] = 0; ntok[j] = 1; sz++;
			}
		}
		cout << sz << " ";
		for (ll j = 0; j < sz; j++) cout << qry[j] + 1 << " ";
		cout << endl;
		ll x; cin >> x; x--;
		for (ll j = x; j < x + sz; j++) frd[j % n] = 1;
	}
	ll cntt = 0;
	for (ll i = 0; i < n; i++){
		if (!frd[i]) cntt++;
	}
	if (cntt != tkn){
		return -1;
	}
	cout << 0 << endl; return 0;
}


#include<bits/stdc++.h>
#define LL long long
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
using namespace std;
namespace IO
{
    const int sz=1<<15;
    char inbuf[sz],outbuf[sz];
    char *pinbuf=inbuf+sz;
    char *poutbuf=outbuf;
    inline char _getchar()
    {
        if (pinbuf==inbuf+sz)fread(inbuf,1,sz,stdin),pinbuf=inbuf;
        return *(pinbuf++);
    }
    inline void _putchar(char x)
    {
        if (poutbuf==outbuf+sz)fwrite(outbuf,1,sz,stdout),poutbuf=outbuf;
        *(poutbuf++)=x;
    }
    inline void flush()
    {
        if (poutbuf!=outbuf)fwrite(outbuf,1,poutbuf-outbuf,stdout),poutbuf=outbuf;
    }
}
inline int read(){
	int v=0,f=1;
	char c=getchar();
	while (c<'0' || c>'9'){
		if (c=='-') f=-1;
		c=getchar();
	}
	while (c>='0' && c<='9'){
		v=v*10+c-'0';
		c=getchar();
	}
	return v*f;
}

const int Maxn=1005;
bool F[Maxn];
int main(){
	int n;
	scanf("%d",&n);
	if (n<=3){
		printf("0\n");
		fflush(stdout);
		return 0;
	}
	vector<int> V;
	int Mx=-1,B=2,CC=0;
	for (int Bl=2;Bl<=n;Bl++){
		int cb=n/Bl;
		cb--;
		if (cb*(Bl-1)>Mx){
			Mx=cb*(Bl-1);B=Bl;CC=cb;
		}
	}
	for (int i=1,_=0;_<=CC;_++,i+=B){
		for (int j=0;j<B-1;j++)V.pb(i+j);
	}
	while (1){
		vector<int> t;
		for (int i=0;i<V.size();i++){
			if (!F[V[i]]){
				t.pb(V[i]);
			}
		}
		if (t.size()==B-1){
			printf("0\n");
			fflush(stdout);
			return 0;
		}
		printf("%d ",t.size());
		for (int i=0;i<t.size();i++) printf("%d ",t[i]),F[t[i]]=1;
		printf("\n");
		fflush(stdout);
		int x,k=t.size();
		scanf("%d",&x);
		for (int i=x,j=0;j<k;j++,i++){
			if (i>n) i=1;
			F[i]=0;
		}
	}
}


#include<bits/stdc++.h>
#define LL long long
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
using namespace std;
namespace IO
{
    const int sz=1<<15;
    char inbuf[sz],outbuf[sz];
    char *pinbuf=inbuf+sz;
    char *poutbuf=outbuf;
    inline char _getchar()
    {
        if (pinbuf==inbuf+sz)fread(inbuf,1,sz,stdin),pinbuf=inbuf;
        return *(pinbuf++);
    }
    inline void _putchar(char x)
    {
        if (poutbuf==outbuf+sz)fwrite(outbuf,1,sz,stdout),poutbuf=outbuf;
        *(poutbuf++)=x;
    }
    inline void flush()
    {
        if (poutbuf!=outbuf)fwrite(outbuf,1,poutbuf-outbuf,stdout),poutbuf=outbuf;
    }
}
inline int read(){
	int v=0,f=1;
	char c=getchar();
	while (c<'0' || c>'9'){
		if (c=='-') f=-1;
		c=getchar();
	}
	while (c>='0' && c<='9'){
		v=v*10+c-'0';
		c=getchar();
	}
	return v*f;
}

const int Maxn=1005;
bool F[Maxn];
int main(){
	int n;
	scanf("%d",&n);
	vector<int> V;
	for (int i=1;i<n;i+=2){
		V.pb(i);
	}

	while (1){
		vector<int> t;
		for (int i=0;i<V.size();i++){
			if (!F[V[i]]){
				t.pb(V[i]);
			}
		}
		if (t.size()==1){
			printf("0\n");
			fflush(stdout);
			return 0;
		}
		printf("%d ",t.size());
		for (int i=0;i<t.size();i++) printf("%d ",t[i]),F[t[i]]=1;
		printf("\n");
		fflush(stdout);
		int x,k=t.size();
		scanf("%d",&x);
		for (int i=x,j=0;j<k;j++,i++){
			if (i>n) i=1;
			F[i]=0;
		}
	}
}


#include<bits/stdc++.h>
#define LL long long
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
using namespace std;
namespace IO
{
    const int sz=1<<15;
    char inbuf[sz],outbuf[sz];
    char *pinbuf=inbuf+sz;
    char *poutbuf=outbuf;
    inline char _getchar()
    {
        if (pinbuf==inbuf+sz)fread(inbuf,1,sz,stdin),pinbuf=inbuf;
        return *(pinbuf++);
    }
    inline void _putchar(char x)
    {
        if (poutbuf==outbuf+sz)fwrite(outbuf,1,sz,stdout),poutbuf=outbuf;
        *(poutbuf++)=x;
    }
    inline void flush()
    {
        if (poutbuf!=outbuf)fwrite(outbuf,1,poutbuf-outbuf,stdout),poutbuf=outbuf;
    }
}
inline int read(){
	int v=0,f=1;
	char c=getchar();
	while (c<'0' || c>'9'){
		if (c=='-') f=-1;
		c=getchar();
	}
	while (c>='0' && c<='9'){
		v=v*10+c-'0';
		c=getchar();
	}
	return v*f;
}

const int Maxn=1005;
bool F[Maxn];
int main(){
	int n;
	scanf("%d",&n);
	vector<int> V;
	int Mx=-1,B,CC;
	for (int Bl=2;Bl<=n;Bl++){
		int cb=n/Bl;
		cb--;
		if (cb*(Bl-1)>Mx){
			Mx=cb*(Bl-1);B=Bl;CC=cb;
		}
	}
	for (int i=1,_=0;_<CC;_++,i+=B){
		for (int j=0;j<B-1;j++)V.pb(i+j);
	}

	while (1){
		vector<int> t;
		for (int i=0;i<V.size();i++){
			if (!F[V[i]]){
				t.pb(V[i]);
			}
		}
		if (t.size()==1 || t.size()==0){
			printf("0\n");
			fflush(stdout);
			return 0;
		}
		printf("%d ",t.size());
		for (int i=0;i<t.size();i++) printf("%d ",t[i]),F[t[i]]=1;
		printf("\n");
		fflush(stdout);
		int x,k=t.size();
		scanf("%d",&x);
		for (int i=x,j=0;j<k;j++,i++){
			if (i>n) i=1;
			F[i]=0;
		}
	}
}


#include<bits/stdc++.h>
#define LL long long
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
using namespace std;
namespace IO
{
    const int sz=1<<15;
    char inbuf[sz],outbuf[sz];
    char *pinbuf=inbuf+sz;
    char *poutbuf=outbuf;
    inline char _getchar()
    {
        if (pinbuf==inbuf+sz)fread(inbuf,1,sz,stdin),pinbuf=inbuf;
        return *(pinbuf++);
    }
    inline void _putchar(char x)
    {
        if (poutbuf==outbuf+sz)fwrite(outbuf,1,sz,stdout),poutbuf=outbuf;
        *(poutbuf++)=x;
    }
    inline void flush()
    {
        if (poutbuf!=outbuf)fwrite(outbuf,1,poutbuf-outbuf,stdout),poutbuf=outbuf;
    }
}
inline int read(){
	int v=0,f=1;
	char c=getchar();
	while (c<'0' || c>'9'){
		if (c=='-') f=-1;
		c=getchar();
	}
	while (c>='0' && c<='9'){
		v=v*10+c-'0';
		c=getchar();
	}
	return v*f;
}

const int Maxn=1005;
bool F[Maxn];
int main(){
	int n;
	scanf("%d",&n);
	vector<int> V;
	for (int i=1;i<n;i+=2){
		V.pb(i);
	}

	while (1){
		vector<int> t;
		for (int i=0;i<V.size();i++){
			if (!F[V[i]]){
				t.pb(V[i]);
			}
		}
		if (t.size()==1 || t.size()==0){
			printf("0\n");
			fflush(stdout);
			return 0;
		}
		printf("%d ",t.size());
		for (int i=0;i<t.size();i++) printf("%d ",t[i]),F[t[i]]=1;
		printf("\n");
		fflush(stdout);
		int x,k=t.size();
		scanf("%d",&x);
		for (int i=x,j=0;j<k;j++,i++){
			if (i>n) i=1;
			F[i]=0;
		}
	}
}


#include<bits/stdc++.h>
#define LL long long
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
using namespace std;
namespace IO
{
    const int sz=1<<15;
    char inbuf[sz],outbuf[sz];
    char *pinbuf=inbuf+sz;
    char *poutbuf=outbuf;
    inline char _getchar()
    {
        if (pinbuf==inbuf+sz)fread(inbuf,1,sz,stdin),pinbuf=inbuf;
        return *(pinbuf++);
    }
    inline void _putchar(char x)
    {
        if (poutbuf==outbuf+sz)fwrite(outbuf,1,sz,stdout),poutbuf=outbuf;
        *(poutbuf++)=x;
    }
    inline void flush()
    {
        if (poutbuf!=outbuf)fwrite(outbuf,1,poutbuf-outbuf,stdout),poutbuf=outbuf;
    }
}
inline int read(){
	int v=0,f=1;
	char c=getchar();
	while (c<'0' || c>'9'){
		if (c=='-') f=-1;
		c=getchar();
	}
	while (c>='0' && c<='9'){
		v=v*10+c-'0';
		c=getchar();
	}
	return v*f;
}

const int Maxn=1005;
bool F[Maxn];
int main(){
	int n;
	scanf("%d",&n);
	if (n<=3){
		printf("0\n");
		fflush(stdout);
		return 0;
	}
	vector<int> V;
	int Mx=-1,B=2,CC=0;
	for (int Bl=2;Bl<=n;Bl++){
		int cb=n/Bl;
		cb--;
		int rem=n%Bl;
		int fuck=cb*(Bl-1);
		if (rem>=2) fuck+=rem-1;
		if (fuck>Mx){
			Mx=fuck;B=Bl;CC=cb;
		}
	}
	for (int i=1,_=0;_<=CC;_++,i+=B){
		for (int j=0;j<B-1;j++)V.pb(i+j);
	}
	int rem=n%B;
	if (rem>=2){
		for (int i=n-rem+1;i<=n-1;i++){
			V.pb(i);
		}
	}
	while (1){
		vector<int> t;
		for (int i=0;i<V.size();i++){
			if (!F[V[i]]){
				t.pb(V[i]);
			}
		}
		if (t.size()==B-1){
			printf("0\n");
			fflush(stdout);
			return 0;
		}
		printf("%d ",t.size());
		for (int i=0;i<t.size();i++) printf("%d ",t[i]),F[t[i]]=1;
		printf("\n");
		fflush(stdout);
		int x,k=t.size();
		scanf("%d",&x);
		for (int i=x,j=0;j<k;j++,i++){
			if (i>n) i=1;
			F[i]=0;
		}
	}
}


// while (clock()<=69*CLOCKS_PER_SEC)
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("Ofast")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define pb push_back
#define SZ(x) ((int)(x).size())
#define ALL(x) x.begin(),x.end()
#define all(x) x.begin(),x.end()
#define fi first
#define se second
#define _upgrade ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define erase_duplicates(x) sort(all(x)); (x).resize(distance((x).begin(), unique(all(x))));

using namespace std;
using namespace __gnu_pbds;
template<typename T>
using ordered_set = tree<
T,
null_type,
less<T>,
rb_tree_tag,
tree_order_statistics_node_update>;

//X.find_by_order(k); - zwraca iterator na k-ty element (numeracja od zerowego)
//X.order_of_key(k); - zwraca liczbę elementów ostro mniejszych niż k

typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
typedef vector<PII> VPII;
typedef vector<PLL> VPLL;
typedef vector<LL> VLL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<char> VC;
typedef long double LD;
typedef pair<LD,LD> PLD;
typedef vector<LD> VLD;
typedef vector<PLD> VPLD;

template<class TH> void _dbg(const char *sdbg, TH h){ cerr<<sdbg<<" = "<<h<<endl; }
template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
  while(*sdbg!=',')cerr<<*sdbg++;
  cerr<<" = "<<h<<", "; _dbg(sdbg+1, a...);
}

#ifdef LOCAL
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define dbg(...)
#define cerr if(0)cout
#endif

const int maxn = (1e6)+7;
const int maxk = 20;
const int inf = (1e9)+7;
const LL LLinf = ((LL)1e18)+7LL;
const LD eps = 1e-9;
const LL mod = 1e9+7;

// ***************************** CODE ***************************** //

int tab[maxn];
int ile;

void ustaw(int pos, int val)
{
  if(tab[pos] == val)
    return;
  if(tab[pos] == 0)
    ile++;
  else
    ile--;
  tab[pos] = val;
}

int main()
{
	_upgrade
  int n;
  cin>>n;
  int k = 0;
  while(k * k <= n)
    k++;
  k--;
  int v = min(1, n - k * k - 3);
  while(ile < k * (k - 1) - k + 1 + max(0, v))
  {
    VI V;
    for(int i = 0;i < k;i++)
      for(int j = 0;i + j * k < n;j++)
        if(tab[i + j * k] == 0)
        {
          if(SZ(V) < k)
          {
            V.pb(i + j * k);
            ustaw(i + j * k, 1);
          }
        }
    if(SZ(V) < k)
    {
      for(int i = 0;i < n;i++)
        if(tab[i] == 0 and SZ(V) < k)
        {
          V.pb(i);
          ustaw(i, 1);
        }
    }
    assert(SZ(V) == k);
    cout<<k<<" ";
    for(auto s : V)
      cout<<s + 1<<" ";
    cout<<endl;
    int x;
    cin>>x;
    assert(x != -1);
    x--;
    for(int i = 0;i < k;i++)
    {
      ustaw(x, 0);
      x++;
      x %= n;
    }
  }
  cout<<0<<endl;

	return 0;
}


// while (clock()<=69*CLOCKS_PER_SEC)
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("Ofast")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define pb push_back
#define SZ(x) ((int)(x).size())
#define ALL(x) x.begin(),x.end()
#define all(x) x.begin(),x.end()
#define fi first
#define se second
#define _upgrade ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define erase_duplicates(x) sort(all(x)); (x).resize(distance((x).begin(), unique(all(x))));

using namespace std;
using namespace __gnu_pbds;
template<typename T>
using ordered_set = tree<
T,
null_type,
less<T>,
rb_tree_tag,
tree_order_statistics_node_update>;

//X.find_by_order(k); - zwraca iterator na k-ty element (numeracja od zerowego)
//X.order_of_key(k); - zwraca liczbę elementów ostro mniejszych niż k

typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
typedef vector<PII> VPII;
typedef vector<PLL> VPLL;
typedef vector<LL> VLL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<char> VC;
typedef long double LD;
typedef pair<LD,LD> PLD;
typedef vector<LD> VLD;
typedef vector<PLD> VPLD;

template<class TH> void _dbg(const char *sdbg, TH h){ cerr<<sdbg<<" = "<<h<<endl; }
template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
  while(*sdbg!=',')cerr<<*sdbg++;
  cerr<<" = "<<h<<", "; _dbg(sdbg+1, a...);
}

#ifdef LOCAL
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define dbg(...)
#define cerr if(0)cout
#endif

const int maxn = (1e6)+7;
const int maxk = 20;
const int inf = (1e9)+7;
const LL LLinf = ((LL)1e18)+7LL;
const LD eps = 1e-9;
const LL mod = 1e9+7;

// ***************************** CODE ***************************** //

int tab[maxn];
int ile;

void ustaw(int pos, int val)
{
  if(tab[pos] == val)
    return;
  if(tab[pos] == 0)
    ile++;
  else
    ile--;
  tab[pos] = val;
}

int main()
{
	_upgrade
  int n;
  cin>>n;
  int k = 0;
  while(k * k <= n)
    k++;
  k--;
  int v = min(1, n - k * k - 2);
  while(ile < k * (k - 1) - k + 1 + max(0, v))
  {
    VI V;
    for(int i = 0;i < k;i++)
      for(int j = 0;j < k;j++)
        if(tab[i + j * k] == 0)
        {
          if(SZ(V) < k)
          {
            V.pb(i + j * k);
            ustaw(i + j * k, 1);
          }
        }
    if(SZ(V) < k)
    {
      for(int i = 0;i < n;i++)
        if(tab[i] == 0 and SZ(V) < k)
        {
          V.pb(i);
          ustaw(i, 1);
        }
    }
    assert(SZ(V) == k);
    cout<<k<<" ";
    for(auto s : V)
      cout<<s + 1<<" ";
    cout<<endl;
    int x;
    cin>>x;
    assert(x != -1);
    x--;
    for(int i = 0;i < k;i++)
    {
      ustaw(x, 0);
      x++;
      x %= n;
    }
  }
  cout<<0<<endl;

	return 0;
}


// while (clock()<=69*CLOCKS_PER_SEC)
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("Ofast")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define pb push_back
#define SZ(x) ((int)(x).size())
#define ALL(x) x.begin(),x.end()
#define all(x) x.begin(),x.end()
#define fi first
#define se second
#define _upgrade ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define erase_duplicates(x) sort(all(x)); (x).resize(distance((x).begin(), unique(all(x))));

using namespace std;
using namespace __gnu_pbds;
template<typename T>
using ordered_set = tree<
T,
null_type,
less<T>,
rb_tree_tag,
tree_order_statistics_node_update>;

//X.find_by_order(k); - zwraca iterator na k-ty element (numeracja od zerowego)
//X.order_of_key(k); - zwraca liczbę elementów ostro mniejszych niż k

typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
typedef vector<PII> VPII;
typedef vector<PLL> VPLL;
typedef vector<LL> VLL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<char> VC;
typedef long double LD;
typedef pair<LD,LD> PLD;
typedef vector<LD> VLD;
typedef vector<PLD> VPLD;

template<class TH> void _dbg(const char *sdbg, TH h){ cerr<<sdbg<<" = "<<h<<endl; }
template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
  while(*sdbg!=',')cerr<<*sdbg++;
  cerr<<" = "<<h<<", "; _dbg(sdbg+1, a...);
}

#ifdef LOCAL
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define dbg(...)
#define cerr if(0)cout
#endif

const int maxn = (1e6)+7;
const int maxk = 20;
const int inf = (1e9)+7;
const LL LLinf = ((LL)1e18)+7LL;
const LD eps = 1e-9;
const LL mod = 1e9+7;

// ***************************** CODE ***************************** //

int tab[maxn];
int ile;

void ustaw(int pos, int val)
{
  if(tab[pos] == val)
    return;
  if(tab[pos] == 0)
    ile++;
  else
    ile--;
  tab[pos] = val;
}

int main()
{
	_upgrade
  int n;
  cin>>n;
  int k = 0;
  int maxi = 0;
  for(int j = 1;j <= n;j++)
    if(n - ((n + j - 1) / j) - (j - 1) > maxi)
    {
      maxi = n - ((n + j - 1) / j) - (j - 1);
      k = j;
    }
  while(ile < maxi)
  {
    VI V;
    for(int i = 0;i < n;i++)
      for(int j = 0;i + j * k < n - 1;j++)
        if(tab[i + j * k] == 0)
        {
          if(SZ(V) < k)
          {
            V.pb(i + j * k);
            ustaw(i + j * k, 1);
          }
        }
    if(SZ(V) < k)
    {
      for(int i = 0;i <= n;i++)
        if(tab[i] == 0 and SZ(V) < k)
        {
          V.pb(i);
          ustaw(i, 1);
        }
    }
    assert(SZ(V) == k);
    cout<<k<<" ";
    for(auto s : V)
      cout<<s + 1<<" ";
    cout<<endl;
    int x;
    cin>>x;
    assert(x != -1);
    x--;
    for(int i = 0;i < k;i++)
    {
      ustaw(x, 0);
      x++;
      x %= n;
    }
  }
  cout<<0<<endl;

	return 0;
}


// while (clock()<=69*CLOCKS_PER_SEC)
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("Ofast")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define pb push_back
#define SZ(x) ((int)(x).size())
#define ALL(x) x.begin(),x.end()
#define all(x) x.begin(),x.end()
#define fi first
#define se second
#define _upgrade ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define erase_duplicates(x) sort(all(x)); (x).resize(distance((x).begin(), unique(all(x))));

using namespace std;
using namespace __gnu_pbds;
template<typename T>
using ordered_set = tree<
T,
null_type,
less<T>,
rb_tree_tag,
tree_order_statistics_node_update>;

//X.find_by_order(k); - zwraca iterator na k-ty element (numeracja od zerowego)
//X.order_of_key(k); - zwraca liczbę elementów ostro mniejszych niż k

typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
typedef vector<PII> VPII;
typedef vector<PLL> VPLL;
typedef vector<LL> VLL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<char> VC;
typedef long double LD;
typedef pair<LD,LD> PLD;
typedef vector<LD> VLD;
typedef vector<PLD> VPLD;

template<class TH> void _dbg(const char *sdbg, TH h){ cerr<<sdbg<<" = "<<h<<endl; }
template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
  while(*sdbg!=',')cerr<<*sdbg++;
  cerr<<" = "<<h<<", "; _dbg(sdbg+1, a...);
}

#ifdef LOCAL
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define dbg(...)
#define cerr if(0)cout
#endif

const int maxn = (1e6)+7;
const int maxk = 20;
const int inf = (1e9)+7;
const LL LLinf = ((LL)1e18)+7LL;
const LD eps = 1e-9;
const LL mod = 1e9+7;

// ***************************** CODE ***************************** //

int tab[maxn];
int ile;

void ustaw(int pos, int val)
{
  if(tab[pos] == val)
    return;
  if(tab[pos] == 0)
    ile++;
  else
    ile--;
  tab[pos] = val;
}

int main()
{
	_upgrade
  int n;
  cin>>n;
  int k = 0;
  while(k * k <= n)
    k++;
  k--;
  int v = min(1, n - k * k - 2);
  while(ile < k * (k - 1) - k + 1 + max(0, v))
  {
    VI V;
    for(int i = 0;i < k;i++)
      for(int j = 0;i + j * k < n;j++)
        if(tab[i + j * k] == 0)
        {
          if(SZ(V) < k)
          {
            V.pb(i + j * k);
            ustaw(i + j * k, 1);
          }
        }
    if(SZ(V) < k)
    {
      for(int i = 0;i < n;i++)
        if(tab[i] == 0 and SZ(V) < k)
        {
          V.pb(i);
          ustaw(i, 1);
        }
    }
    assert(SZ(V) == k);
    cout<<k<<" ";
    for(auto s : V)
      cout<<s + 1<<" ";
    cout<<endl;
    int x;
    cin>>x;
    assert(x != -1);
    x--;
    for(int i = 0;i < k;i++)
    {
      ustaw(x, 0);
      x++;
      x %= n;
    }
  }
  cout<<0<<endl;

	return 0;
}


// while (clock()<=69*CLOCKS_PER_SEC)
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("Ofast")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define pb push_back
#define SZ(x) ((int)(x).size())
#define ALL(x) x.begin(),x.end()
#define all(x) x.begin(),x.end()
#define fi first
#define se second
#define _upgrade ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define erase_duplicates(x) sort(all(x)); (x).resize(distance((x).begin(), unique(all(x))));

using namespace std;
using namespace __gnu_pbds;
template<typename T>
using ordered_set = tree<
T,
null_type,
less<T>,
rb_tree_tag,
tree_order_statistics_node_update>;

//X.find_by_order(k); - zwraca iterator na k-ty element (numeracja od zerowego)
//X.order_of_key(k); - zwraca liczbę elementów ostro mniejszych niż k

typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
typedef vector<PII> VPII;
typedef vector<PLL> VPLL;
typedef vector<LL> VLL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<char> VC;
typedef long double LD;
typedef pair<LD,LD> PLD;
typedef vector<LD> VLD;
typedef vector<PLD> VPLD;

template<class TH> void _dbg(const char *sdbg, TH h){ cerr<<sdbg<<" = "<<h<<endl; }
template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
  while(*sdbg!=',')cerr<<*sdbg++;
  cerr<<" = "<<h<<", "; _dbg(sdbg+1, a...);
}

#ifdef LOCAL
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define dbg(...)
#define cerr if(0)cout
#endif

const int maxn = (1e6)+7;
const int maxk = 20;
const int inf = (1e9)+7;
const LL LLinf = ((LL)1e18)+7LL;
const LD eps = 1e-9;
const LL mod = 1e9+7;

// ***************************** CODE ***************************** //

int tab[maxn];
int ile;

void ustaw(int pos, int val)
{
  if(tab[pos] == val)
    return;
  if(tab[pos] == 0)
    ile++;
  else
    ile--;
  tab[pos] = val;
}

int main()
{
	_upgrade
  int n;
  cin>>n;
  int k = 0;
  int maxi = 0;
  for(int j = 1;j <= n;j++)
    if(n - (n / j) - (j - 1) > maxi)
    {
      maxi = n - (n / j) - (j - 1);
      k = j;
    }
  while(ile < maxi)
  {
    VI V;
    for(int i = 0;i <= n;i++)
      for(int j = 0;i + j * k < n;j++)
        if(tab[i + j * k] == 0)
        {
          if(SZ(V) < k)
          {
            V.pb(i + j * k);
            ustaw(i + j * k, 1);
          }
        }
    if(SZ(V) < k)
    {
      for(int i = 0;i <= n;i++)
        if(tab[i] == 0 and SZ(V) < k)
        {
          V.pb(i);
          ustaw(i, 1);
        }
    }
    assert(SZ(V) == k);
    cout<<k<<" ";
    for(auto s : V)
      cout<<s + 1<<" ";
    cout<<endl;
    int x;
    cin>>x;
    assert(x != -1);
    x--;
    for(int i = 0;i < k;i++)
    {
      ustaw(x, 0);
      x++;
      x %= n;
    }
  }
  cout<<0<<endl;

	return 0;
}


// while (clock()<=69*CLOCKS_PER_SEC)
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("Ofast")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define pb push_back
#define SZ(x) ((int)(x).size())
#define ALL(x) x.begin(),x.end()
#define all(x) x.begin(),x.end()
#define fi first
#define se second
#define _upgrade ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define erase_duplicates(x) sort(all(x)); (x).resize(distance((x).begin(), unique(all(x))));

using namespace std;
using namespace __gnu_pbds;
template<typename T>
using ordered_set = tree<
T,
null_type,
less<T>,
rb_tree_tag,
tree_order_statistics_node_update>;

//X.find_by_order(k); - zwraca iterator na k-ty element (numeracja od zerowego)
//X.order_of_key(k); - zwraca liczbę elementów ostro mniejszych niż k

typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
typedef vector<PII> VPII;
typedef vector<PLL> VPLL;
typedef vector<LL> VLL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<char> VC;
typedef long double LD;
typedef pair<LD,LD> PLD;
typedef vector<LD> VLD;
typedef vector<PLD> VPLD;

template<class TH> void _dbg(const char *sdbg, TH h){ cerr<<sdbg<<" = "<<h<<endl; }
template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
  while(*sdbg!=',')cerr<<*sdbg++;
  cerr<<" = "<<h<<", "; _dbg(sdbg+1, a...);
}

#ifdef LOCAL
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define dbg(...)
#define cerr if(0)cout
#endif

const int maxn = (1e6)+7;
const int maxk = 20;
const int inf = (1e9)+7;
const LL LLinf = ((LL)1e18)+7LL;
const LD eps = 1e-9;
const LL mod = 1e9+7;

// ***************************** CODE ***************************** //

int tab[maxn];
int ile;

void ustaw(int pos, int val)
{
  if(tab[pos] == val)
    return;
  if(tab[pos] == 0)
    ile++;
  else
    ile--;
  tab[pos] = val;
}

int main()
{
	_upgrade
  int n;
  cin>>n;
  int k = 0;
  while(k * k <= n)
    k++;
  k--;
  while(ile < k * (k - 1) - k + 1)
  {
    VI V;
    for(int i = 0;i < k;i++)
      for(int j = 0;j < n;j += k)
        if(tab[i + j] == 0)
        {
          if(SZ(V) < k)
          {
            V.pb(i + j);
            ustaw(i + j, 1);
          }
        }
    cout<<k<<" ";
    for(auto s : V)
      cout<<s + 1<<" ";
    cout<<endl;
    int x;
    cin>>x;
    x--;
    for(int i = 0;i < k;i++)
    {
      ustaw(x, 0);
      x++;
      x %= n;
    }
  }
  cout<<0<<endl;

	return 0;
}


// while (clock()<=69*CLOCKS_PER_SEC)
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("Ofast")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define pb push_back
#define SZ(x) ((int)(x).size())
#define ALL(x) x.begin(),x.end()
#define all(x) x.begin(),x.end()
#define fi first
#define se second
#define _upgrade ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define erase_duplicates(x) sort(all(x)); (x).resize(distance((x).begin(), unique(all(x))));

using namespace std;
using namespace __gnu_pbds;
template<typename T>
using ordered_set = tree<
T,
null_type,
less<T>,
rb_tree_tag,
tree_order_statistics_node_update>;

//X.find_by_order(k); - zwraca iterator na k-ty element (numeracja od zerowego)
//X.order_of_key(k); - zwraca liczbę elementów ostro mniejszych niż k

typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
typedef vector<PII> VPII;
typedef vector<PLL> VPLL;
typedef vector<LL> VLL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<char> VC;
typedef long double LD;
typedef pair<LD,LD> PLD;
typedef vector<LD> VLD;
typedef vector<PLD> VPLD;

template<class TH> void _dbg(const char *sdbg, TH h){ cerr<<sdbg<<" = "<<h<<endl; }
template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
  while(*sdbg!=',')cerr<<*sdbg++;
  cerr<<" = "<<h<<", "; _dbg(sdbg+1, a...);
}

#ifdef LOCAL
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define dbg(...)
#define cerr if(0)cout
#endif

const int maxn = (1e6)+7;
const int maxk = 20;
const int inf = (1e9)+7;
const LL LLinf = ((LL)1e18)+7LL;
const LD eps = 1e-9;
const LL mod = 1e9+7;

// ***************************** CODE ***************************** //

int tab[maxn];
int ile;

void ustaw(int pos, int val)
{
  if(tab[pos] == val)
    return;
  if(tab[pos] == 0)
    ile++;
  else
    ile--;
  tab[pos] = val;
}

int main()
{
	_upgrade
  int n;
  cin>>n;
  int k = 0;
  while(k * k <= n)
    k++;
  k--;
  while(ile < k * (k - 1) - k + 1)
  {
    VI V;
    for(int i = 0;i < k;i++)
      for(int j = 0;j < k;j++)
        if(tab[i + j * k] == 0)
        {
          if(SZ(V) < k)
          {
            V.pb(i + j * k);
            ustaw(i + j * k, 1);
          }
        }
    if(SZ(V) < k)
    {
      for(int i = 0;i < n;i++)
        if(tab[i] == 0 and SZ(V) < k)
        {
          V.pb(i);
          ustaw(i, 1);
        }
    }
    assert(SZ(V) == k);
    cout<<k<<" ";
    for(auto s : V)
      cout<<s + 1<<" ";
    cout<<endl;
    int x;
    cin>>x;
    assert(x != -1);
    x--;
    for(int i = 0;i < k;i++)
    {
      ustaw(x, 0);
      x++;
      x %= n;
    }
  }
  cout<<0<<endl;

	return 0;
}


// while (clock()<=69*CLOCKS_PER_SEC)
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("Ofast")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define pb push_back
#define SZ(x) ((int)(x).size())
#define ALL(x) x.begin(),x.end()
#define all(x) x.begin(),x.end()
#define fi first
#define se second
#define _upgrade ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define erase_duplicates(x) sort(all(x)); (x).resize(distance((x).begin(), unique(all(x))));

using namespace std;
using namespace __gnu_pbds;
template<typename T>
using ordered_set = tree<
T,
null_type,
less<T>,
rb_tree_tag,
tree_order_statistics_node_update>;

//X.find_by_order(k); - zwraca iterator na k-ty element (numeracja od zerowego)
//X.order_of_key(k); - zwraca liczbę elementów ostro mniejszych niż k

typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
typedef vector<PII> VPII;
typedef vector<PLL> VPLL;
typedef vector<LL> VLL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<char> VC;
typedef long double LD;
typedef pair<LD,LD> PLD;
typedef vector<LD> VLD;
typedef vector<PLD> VPLD;

template<class TH> void _dbg(const char *sdbg, TH h){ cerr<<sdbg<<" = "<<h<<endl; }
template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
  while(*sdbg!=',')cerr<<*sdbg++;
  cerr<<" = "<<h<<", "; _dbg(sdbg+1, a...);
}

#ifdef LOCAL
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define dbg(...)
#define cerr if(0)cout
#endif

const int maxn = (1e6)+7;
const int maxk = 20;
const int inf = (1e9)+7;
const LL LLinf = ((LL)1e18)+7LL;
const LD eps = 1e-9;
const LL mod = 1e9+7;

// ***************************** CODE ***************************** //

int tab[maxn];
int ile;

void ustaw(int pos, int val)
{
  if(tab[pos] == val)
    return;
  if(tab[pos] == 0)
    ile++;
  else
    ile--;
  tab[pos] = val;
}

int main()
{
	_upgrade
  int n;
  cin>>n;
  int k = 0;
  while(k * k <= n)
    k++;
  k--;
  while(ile < k * (k - 1) - k + 1)
  {
    VI V;
    for(int i = 0;i < k;i++)
      for(int j = 0;j < k;j++)
        if(tab[i + j * k] == 0)
        {
          if(SZ(V) < k)
          {
            V.pb(i + j * k);
            ustaw(i + j * k, 1);
          }
        }
    cout<<k<<" ";
    for(auto s : V)
      cout<<s + 1<<" ";
    cout<<endl;
    int x;
    cin>>x;
    assert(x != -1);
    x--;
    for(int i = 0;i < k;i++)
    {
      ustaw(x, 0);
      x++;
      x %= n;
    }
  }
  cout<<0<<endl;

	return 0;
}


// while (clock()<=69*CLOCKS_PER_SEC)
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("Ofast")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define pb push_back
#define SZ(x) ((int)(x).size())
#define ALL(x) x.begin(),x.end()
#define all(x) x.begin(),x.end()
#define fi first
#define se second
#define _upgrade ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define erase_duplicates(x) sort(all(x)); (x).resize(distance((x).begin(), unique(all(x))));

using namespace std;
using namespace __gnu_pbds;
template<typename T>
using ordered_set = tree<
T,
null_type,
less<T>,
rb_tree_tag,
tree_order_statistics_node_update>;

//X.find_by_order(k); - zwraca iterator na k-ty element (numeracja od zerowego)
//X.order_of_key(k); - zwraca liczbę elementów ostro mniejszych niż k

typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
typedef vector<PII> VPII;
typedef vector<PLL> VPLL;
typedef vector<LL> VLL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<char> VC;
typedef long double LD;
typedef pair<LD,LD> PLD;
typedef vector<LD> VLD;
typedef vector<PLD> VPLD;

template<class TH> void _dbg(const char *sdbg, TH h){ cerr<<sdbg<<" = "<<h<<endl; }
template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
  while(*sdbg!=',')cerr<<*sdbg++;
  cerr<<" = "<<h<<", "; _dbg(sdbg+1, a...);
}

#ifdef LOCAL
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define dbg(...)
#define cerr if(0)cout
#endif

const int maxn = (1e6)+7;
const int maxk = 20;
const int inf = (1e9)+7;
const LL LLinf = ((LL)1e18)+7LL;
const LD eps = 1e-9;
const LL mod = 1e9+7;

// ***************************** CODE ***************************** //

int tab[maxn];
int ile;

void ustaw(int pos, int val)
{
  if(tab[pos] == val)
    return;
  if(tab[pos] == 0)
    ile++;
  else
    ile--;
  tab[pos] = val;
}

int main()
{
	_upgrade
  int n;
  cin>>n;
  int k = 0;
  int maxi = 0;
  for(int j = 1;j <= n;j++)
    if(n - ((n + j - 1) / j) - (j - 1) > maxi)
    {
      maxi = n - ((n + j - 1) / j) - (j - 1);
      k = j;
    }
  while(ile < maxi)
  {
    VI V;
    for(int i = 0;i <= n;i++)
      for(int j = 0;i + j * k < n;j++)
        if(tab[i + j * k] == 0)
        {
          if(SZ(V) < k)
          {
            V.pb(i + j * k);
            ustaw(i + j * k, 1);
          }
        }
    if(SZ(V) < k)
    {
      for(int i = 0;i <= n;i++)
        if(tab[i] == 0 and SZ(V) < k)
        {
          V.pb(i);
          ustaw(i, 1);
        }
    }
    assert(SZ(V) == k);
    cout<<k<<" ";
    for(auto s : V)
      cout<<s + 1<<" ";
    cout<<endl;
    int x;
    cin>>x;
    assert(x != -1);
    x--;
    for(int i = 0;i < k;i++)
    {
      ustaw(x, 0);
      x++;
      x %= n;
    }
  }
  cout<<0<<endl;

	return 0;
}


// while (clock()<=69*CLOCKS_PER_SEC)
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("Ofast")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define pb push_back
#define SZ(x) ((int)(x).size())
#define ALL(x) x.begin(),x.end()
#define all(x) x.begin(),x.end()
#define fi first
#define se second
#define _upgrade ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define erase_duplicates(x) sort(all(x)); (x).resize(distance((x).begin(), unique(all(x))));

using namespace std;
using namespace __gnu_pbds;
template<typename T>
using ordered_set = tree<
T,
null_type,
less<T>,
rb_tree_tag,
tree_order_statistics_node_update>;

//X.find_by_order(k); - zwraca iterator na k-ty element (numeracja od zerowego)
//X.order_of_key(k); - zwraca liczbę elementów ostro mniejszych niż k

typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
typedef vector<PII> VPII;
typedef vector<PLL> VPLL;
typedef vector<LL> VLL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<char> VC;
typedef long double LD;
typedef pair<LD,LD> PLD;
typedef vector<LD> VLD;
typedef vector<PLD> VPLD;

template<class TH> void _dbg(const char *sdbg, TH h){ cerr<<sdbg<<" = "<<h<<endl; }
template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
  while(*sdbg!=',')cerr<<*sdbg++;
  cerr<<" = "<<h<<", "; _dbg(sdbg+1, a...);
}

#ifdef LOCAL
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define dbg(...)
#define cerr if(0)cout
#endif

const int maxn = (1e6)+7;
const int maxk = 20;
const int inf = (1e9)+7;
const LL LLinf = ((LL)1e18)+7LL;
const LD eps = 1e-9;
const LL mod = 1e9+7;

// ***************************** CODE ***************************** //

int tab[maxn];
int ile;

void ustaw(int pos, int val)
{
  if(tab[pos] == val)
    return;
  if(tab[pos] == 0)
    ile++;
  else
    ile--;
  tab[pos] = val;
}

int main()
{
	_upgrade
  int n;
  cin>>n;
  int k = 0;
  while(k * k <= n)
    k++;
  k--;
  assert(n <= 20);
  while(ile < k * (k - 1) - k + 1)
  {
    VI V;
    for(int i = 0;i < k;i++)
      for(int j = 0;j < k;j++)
        if(tab[i + j * k] == 0)
        {
          if(SZ(V) < k)
          {
            V.pb(i + j * k);
            ustaw(i + j * k, 1);
          }
        }
    cout<<k<<" ";
    for(auto s : V)
      cout<<s + 1<<" ";
    cout<<endl;
    int x;
    cin>>x;
    assert(x != -1);
    x--;
    for(int i = 0;i < k;i++)
    {
      ustaw(x, 0);
      x++;
      x %= n;
    }
  }
  cout<<0<<endl;

	return 0;
}


// while (clock()<=69*CLOCKS_PER_SEC)
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("Ofast")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define pb push_back
#define SZ(x) ((int)(x).size())
#define ALL(x) x.begin(),x.end()
#define all(x) x.begin(),x.end()
#define fi first
#define se second
#define _upgrade ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define erase_duplicates(x) sort(all(x)); (x).resize(distance((x).begin(), unique(all(x))));

using namespace std;
using namespace __gnu_pbds;
template<typename T>
using ordered_set = tree<
T,
null_type,
less<T>,
rb_tree_tag,
tree_order_statistics_node_update>;

//X.find_by_order(k); - zwraca iterator na k-ty element (numeracja od zerowego)
//X.order_of_key(k); - zwraca liczbę elementów ostro mniejszych niż k

typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
typedef vector<PII> VPII;
typedef vector<PLL> VPLL;
typedef vector<LL> VLL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<char> VC;
typedef long double LD;
typedef pair<LD,LD> PLD;
typedef vector<LD> VLD;
typedef vector<PLD> VPLD;

template<class TH> void _dbg(const char *sdbg, TH h){ cerr<<sdbg<<" = "<<h<<endl; }
template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
  while(*sdbg!=',')cerr<<*sdbg++;
  cerr<<" = "<<h<<", "; _dbg(sdbg+1, a...);
}

#ifdef LOCAL
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define dbg(...)
#define cerr if(0)cout
#endif

const int maxn = (1e6)+7;
const int maxk = 20;
const int inf = (1e9)+7;
const LL LLinf = ((LL)1e18)+7LL;
const LD eps = 1e-9;
const LL mod = 1e9+7;

// ***************************** CODE ***************************** //

int tab[maxn];
int ile;

void ustaw(int pos, int val)
{
  if(tab[pos] == val)
    return;
  if(tab[pos] == 0)
    ile++;
  else
    ile--;
  tab[pos] = val;
}

int main()
{
	_upgrade
  int n;
  cin>>n;
  int k = 0;
  while(k * k <= n)
    k++;
  k--;
  int v = n - k * k - 3;
  while(ile < k * (k - 1) - k + 1 + max(0, v))
  {
    VI V;
    for(int i = 0;i < k;i++)
      for(int j = 0;i + j * k < n;j++)
        if(tab[i + j * k] == 0)
        {
          if(SZ(V) < k)
          {
            V.pb(i + j * k);
            ustaw(i + j * k, 1);
          }
        }
    if(SZ(V) < k)
    {
      for(int i = 0;i < n;i++)
        if(tab[i] == 0 and SZ(V) < k)
        {
          V.pb(i);
          ustaw(i, 1);
        }
    }
    assert(SZ(V) == k);
    cout<<k<<" ";
    for(auto s : V)
      cout<<s + 1<<" ";
    cout<<endl;
    int x;
    cin>>x;
    assert(x != -1);
    x--;
    for(int i = 0;i < k;i++)
    {
      ustaw(x, 0);
      x++;
      x %= n;
    }
  }
  cout<<0<<endl;

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ff first
#define ss second
#define MP make_pair
#define PB push_back
#define ll long long
#define int long long
#define f(i,x,n) for(int i=x;i<n;i++)
#define ld long double
const int mod=1000000007;
const int INF=1e18;
int a[1005];
int vis[1005];
int vismax=0;
int32_t main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	int n;
	cin>>n;
	int a=1;
	int val=2;
	while(n>=9)
	{
		int val1=n-(n+val-1)/val-(val-1);
		int val2=n-(n+val-1)/(val+1)-(val);
		// cout<<val1<<" "<<val2<<endl;
		if(val2>val1)
			val++;
		else
			break;
	}
	int ans=n-(n+val-1)/val-(val-1);
	vector <int> in;
	while(1)
	{
		int sz=0;
		for(int i=0;i<n;i++)
		{
			if(i%val!=0 && vis[i]==0)
			{
				sz++;
				in.push_back(i+1);
				if(sz==val)
					break;
			}
		}
		if(sz==val)
		{
			cout<<sz;
			for(auto i: in)
			{
				vis[i-1]=1;
				cout<<" "<<i;
			}
			cout<<endl;
			in.clear();
			int inp;
			cin>>inp;
			for(int i=inp;i<inp+val;i++)
			{
				vis[i%n]=0;
			}
		}
		else
		{
			break;
		}
		int tmp=0;
		for(int i=1;i<=n;i++)
		{
			tmp+=vis[i];
		}
		if(tmp==ans)
			break;
	}
	cout<<"0"<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ff first
#define ss second
#define MP make_pair
#define PB push_back
#define ll long long
#define int long long
#define f(i,x,n) for(int i=x;i<n;i++)
#define ld long double
const int mod=1000000007;
const int INF=1e18;
int a[1005];
int vis[1005];
int vismax=0;
int32_t main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	int n;
	cin>>n;
	int a=1;
	int val=2;
	while((val+1)*(val+1)<=n)
		val++;
	vector <int> in;
	while(1)
	{
		int sz=0;
		for(int i=0;i<n;i++)
		{
			if(i%val!=0 && vis[i]==0)
			{
				sz++;
				in.push_back(i+1);
				if(sz==val)
					break;
			}
		}
		if(sz==val)
		{
			cout<<sz;
			for(auto i: in)
			{
				vis[i-1]=1;
				cout<<" "<<i;
			}
			cout<<endl;
			in.clear();
			int inp;
			cin>>inp;
			for(int i=inp;i<inp+val;i++)
			{
				vis[i%n]=0;
			}
		}
		else
		{
			break;
		}
		int tmp=0;
		for(int i=1;i<=n;i++)
		{
			tmp+=vis[i];
		}
		if(tmp>vismax)
		{
			vismax=tmp;
		}
		else
			break;
	}
	cout<<"0"<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ff first
#define ss second
#define MP make_pair
#define PB push_back
#define ll long long
#define int long long
#define f(i,x,n) for(int i=x;i<n;i++)
#define ld long double
const int mod=1000000007;
const int INF=1e18;

int32_t main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	int n;
	cin>>n;
	int a=1;
	for(int i=3;i<n;i+=2)
	{
		cout<<"2 "<<a<<" "<<i<<endl;
		int in;
		cin>>in;
		a=in;
		if(a%2==0)
			a++;
	}
	cout<<"0"<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ff first
#define ss second
#define MP make_pair
#define PB push_back
#define ll long long
#define int long long
#define f(i,x,n) for(int i=x;i<n;i++)
#define ld long double
const int mod=1000000007;
const int INF=1e18;
int a[1005];
int vis[1005];
int vismax=0;
int32_t main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	int n;
	cin>>n;
	int a=1;
	int val=2;
	f(i,3,n+1)
	{
		int val1=n-(n+val-1)/val-(val-1);
		int val2=n-(n+i-1)/(i)-(i-1);
		// cout<<i<<" "<<val1<<" "<<val2<<endl;
		if(val2>val1)
		{
			val=i;
		}
	}
	int ans=n-(n+val-1)/val-(val-1);
	vector <int> in;
	while(1)
	{
		int sz=0;
		for(int i=0;i<n;i++)
		{
			if(i%val!=0 && vis[i]==0)
			{
				sz++;
				in.push_back(i+1);
				if(sz==val)
					break;
			}
		}
		if(sz==val)
		{
			cout<<sz;
			for(auto i: in)
			{
				vis[i-1]=1;
				cout<<" "<<i;
			}
			cout<<endl;
			in.clear();
			int inp;
			cin>>inp;
			for(int i=inp;i<inp+val;i++)
			{
				vis[i%n]=0;
			}
		}
		else
		{
			break;
		}
		int tmp=0;
		for(int i=1;i<=n;i++)
		{
			tmp+=vis[i];
		}
		if(tmp==ans)
			break;
	}
	cout<<"0"<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ff first
#define ss second
#define MP make_pair
#define PB push_back
#define ll long long
#define int long long
#define f(i,x,n) for(int i=x;i<n;i++)
#define ld long double
const int mod=1000000007;
const int INF=1e18;
int a[1005];
int vis[1005];
int vismax=0;
int32_t main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	int n;
	cin>>n;
	int a=1;
	int val=2;
	f(i,3,n+1)
	{
		int val1=n-(n+val-1)/val-(val-1);
		int val2=n-(n+i-1)/(i)-(i-1);
		// cout<<i<<" "<<val1<<" "<<val2<<endl;
		if(val2>val1)
		{
			val=i;
		}
	}
	int ans=n-(n+val-1)/val-(val-1);
	vector <int> in;
	while(1)
	{
		int sz=0;
		for(int i=0;i<n;i++)
		{
			if(i%val!=0 && vis[i]==0)
			{
				sz++;
				in.push_back(i+1);
				if(sz==val)
					break;
			}
		}
		if(sz==val)
		{
			cout<<sz;
			for(auto i: in)
			{
				vis[i-1]=1;
				cout<<" "<<i;
			}
			cout<<endl;
			in.clear();
			int inp;
			cin>>inp;
			inp--;
			for(int i=inp;i<inp+val;i++)
			{
				vis[i%n]=0;
			}
		}
		else
		{
			break;
		}
		int tmp=0;
		for(int i=1;i<=n;i++)
		{
			tmp+=vis[i];
		}
		if(tmp==ans)
			break;
	}
	cout<<"0"<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ff first
#define ss second
#define MP make_pair
#define PB push_back
#define ll long long
#define int long long
#define f(i,x,n) for(int i=x;i<n;i++)
#define ld long double
const int mod=1000000007;
const int INF=1e18;

int32_t main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	int n;
	cin>>n;
	int a=1;
	for(int i=3;i<n;i+=2)
	{
		cout<<"2 "<<a<<" "<<i<<endl;
		int in;
		cin>>in;
		a=in;
		if(a%2==0)
			a++;
		if(a>n)
		{
			a=1;
		}
	}
	cout<<"0"<<endl;
	return 0;
}


#include<bits/stdc++.h>
#include <iomanip>
#include <random>
#include <cassert>
#define ll long long int
#define ld long double
#define f first
#define inf 100000000000000000
#define ii pair<ll,ll>
#define vi vector<ll>
#define vii vector<ii>
#define MS0(x) memset(x,0,sizeof(x))
#define MS1(x) memset(x,-1,sizeof(x))
#define s second
#define pb push_back
#define forn(i,n) for(int i=0;i<(int)n;i++)
#define Sort(a) sort(a.begin(),a.end());
using namespace std;
ll const mod=998244353;
std::mt19937 rng((int) std::chrono::steady_clock::now().time_since_epoch().count());
int rand_rng(int l, int r) {
	uniform_int_distribution<int> p(l, r);
	return p(rng);
}
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
// #define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
// ordered_set os.find_by_order os.order_of_key
// b/w l and r os.order_of_key(r+1)-order_of_key(l)

int arr1[100009];
int parent[100009];
vector<ll> sieve;
void sievefun(ll n){
    for(ll i=2;i<=n;i++){
        if(arr1[i]==0){
              parent[i]=i;
            for(ll j=i*i;j<=n;j+=i){
           		if(arr1[j]==0)parent[j]=i;
                arr1[j]=1;
            }
        }
    }
    // for(int i=2;i<=n;i++){
    // 	if(arr1[i]==0)sieve.pb(i);
    // }
}
ll power(ll x, ll y,ll m) {
	ll temp;
	if( y == 0||x==1)
		return 1;
	temp = power(x, y/2,m)%m;
	if (y%2 == 0)
		return ((temp)*(temp))%m;
	else
		return (((x)%m)*((temp*temp)%m))%m;
}

// ll fac[1000009];
// void factorial(){
// 	fac[0]=1;
// 	for(int i=1;i<=1000000;i++)fac[i]=(i*fac[i-1])%mod;
// }
// ll ncr(ll n,ll r){
// 	return (fac[n]*((power(fac[r],mod-2)*power(fac[n-r],mod-2))%mod))%mod;
// }
int const N=200009;

int main()
{	//sievefun(20000);
	// ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int n,x,y;
	cin>>n;
	set<ll> st,on,off;
	int ind=1;
	if(n<=3){
		cout<<0<<endl;
		return 0;
	}
	while(ind<=n-1){
		st.insert(ind);
		on.insert(ind);
		off.insert(ind);
		ind+=2;
	}
	while(st.size()>1){
		ll node=*(st.begin());
		st.erase(st.begin());
		ll node2=*(st.begin());
		st.erase(st.begin());
		cout<<"2 "<<node<<" "<<node2<<endl;
		on.insert(node);
		on.insert(node2);
		cin>>x;
		if(x==-1)return 0;
		y=x+1;
		if(x==n)y=1;
		if(on.find(x)!=on.end()){
			on.erase(x);
			st.insert(x);
		}
		if(on.find(y)!=on.end()){
			on.erase(y);
			st.insert(y);
		}
	}
	ll node=*(st.begin());
	vi vec;
	vec.pb(*st.begin());
	for(int i=2;i<=n;i+=4){
		if(*st.begin()==1&&i==n)continue;
		vec.pb(i);
	}
	// for(auto i:vec)cout<<i<<" ";
	// 	cout<<endl;
	if(vec.size()<4||n<=10)
		cout<<0<<endl;
	else{
		cout<<vec.size()<<" ";
		for(auto i:vec)cout<<i<<" ";
			cout<<endl;
		cin>>x;
		cout<<0<<endl;
	}

}


#include<bits/stdc++.h>
#include <iomanip>
#include <random>
#include <cassert>
#define ll long long int
#define ld long double
#define f first
#define inf 100000000000000000
#define ii pair<ll,ll>
#define vi vector<ll>
#define vii vector<ii>
#define MS0(x) memset(x,0,sizeof(x))
#define MS1(x) memset(x,-1,sizeof(x))
#define s second
#define pb push_back
#define forn(i,n) for(int i=0;i<(int)n;i++)
#define Sort(a) sort(a.begin(),a.end());
using namespace std;
ll const mod=998244353;
std::mt19937 rng((int) std::chrono::steady_clock::now().time_since_epoch().count());
int rand_rng(int l, int r) {
	uniform_int_distribution<int> p(l, r);
	return p(rng);
}
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
// #define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
// ordered_set os.find_by_order os.order_of_key
// b/w l and r os.order_of_key(r+1)-order_of_key(l)

int arr1[100009];
int parent[100009];
vector<ll> sieve;
void sievefun(ll n){
    for(ll i=2;i<=n;i++){
        if(arr1[i]==0){
              parent[i]=i;
            for(ll j=i*i;j<=n;j+=i){
           		if(arr1[j]==0)parent[j]=i;
                arr1[j]=1;
            }
        }
    }
    // for(int i=2;i<=n;i++){
    // 	if(arr1[i]==0)sieve.pb(i);
    // }
}
ll power(ll x, ll y,ll m) {
	ll temp;
	if( y == 0||x==1)
		return 1;
	temp = power(x, y/2,m)%m;
	if (y%2 == 0)
		return ((temp)*(temp))%m;
	else
		return (((x)%m)*((temp*temp)%m))%m;
}

// ll fac[1000009];
// void factorial(){
// 	fac[0]=1;
// 	for(int i=1;i<=1000000;i++)fac[i]=(i*fac[i-1])%mod;
// }
// ll ncr(ll n,ll r){
// 	return (fac[n]*((power(fac[r],mod-2)*power(fac[n-r],mod-2))%mod))%mod;
// }
int const N=200009;

int main()
{	//sievefun(20000);
	// ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int n,x,y;
	cin>>n;
	set<ll> st,on,off;
	int ind=1;
	if(n<=3){
		cout<<0<<endl;
		return 0;
	}
	while(ind<=n-1){
		st.insert(ind);
		on.insert(ind);
		off.insert(ind);
		ind+=2;
	}
	while(st.size()>1){
		ll node=*(st.begin());
		st.erase(st.begin());
		ll node2=*(st.begin());
		st.erase(st.begin());
		cout<<"2 "<<node<<" "<<node2<<endl;
		on.insert(node);
		on.insert(node2);
		cin>>x;
		if(x==-1)return 0;
		y=x+1;
		if(x==n)y=1;
		if(on.find(x)!=on.end()){
			on.erase(x);
			st.insert(x);
		}
		if(on.find(y)!=on.end()){
			on.erase(y);
			st.insert(y);
		}
	}
	cout<<0<<endl;

}