#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int a[ 1100 ];
int res[ 1100 ];
int sum[ 2100 ];

int main() {
	int n;
	int ma = 0, x;
	scanf( "%d", &n );
	if( n == 3 ) {
		bool fin = false;
		for( int i = 1; !fin && i < n; ++i ) {
			for( int j = i + 1; ! fin && j <= n; ++j ) {
				printf( "? %d %d\n", i, j );
				fflush( stdout );
				scanf( "%d", &x );
				if( x == 3 ) {
					for( int k = 1; k <= n; ++k ) {
						if( k != i && k != j ) {
							x = k;
							a[ x ] = 0;
							fin = true;
							break;
						}
					}
				}
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( i != x ) {
				printf( "? %d %d\n", x, i );
				fflush( stdout );
				scanf( "%d", &a[ i ] );
			}
		}
		printf( "!" );
		fflush( stdout );
		for( int i = 1; i <= n; ++i ) {
			printf( " %d", a[ i ] );
			fflush( stdout );
		}
		return 0;
	}
	for( int i = 2; i <= n; ++i ) {
		printf( "? %d %d\n", 1, i );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		++sum[ res[ i ] ];
	}
	for( int i = 0; i < 2100; ++i )
		ma = max( ma, sum[ i ] );
	if( ma == 1 ) {
		a[ 1 ] = 0;
		x = 1;
	} else {
		for( int i = 0; i <= 2100; ++i ) {
			if( sum[ i ] == ma - 1 && i < n ) {
				a[ 1 ] = i;
				break;
			}
		}
		for( int i = 2; i <= n; ++i ) {
			if( res[ i ] == a[ 1 ] ) {
				x = i;
				a[ i ] = 0;
				break;
			}
		}
	}
	for( int i = 1; i <= n; ++i ) {
		if( i != x ) {
			printf( "? %d %d\n", i, x );
			fflush( stdout );
			scanf( "%d", &a[ i ] );
		}
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", a[ i ] );
		fflush( stdout );
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int a[ 2100 ];
int res[ 2100 ];
int sum[ 4200 ];
vector< int > b;

int main() {
	int n;
	int ma = 0, x, y;
	int l, r, tmp;
	scanf( "%d", &n );
	if( n == 3 ) {
		bool fin = false;
		for( int i = 1; !fin && i < n; ++i ) {
			for( int j = i + 1; ! fin && j <= n; ++j ) {
				printf( "? %d %d\n", i, j );
				fflush( stdout );
				scanf( "%d", &x );
				if( x == 3 ) {
					for( int k = 1; k <= n; ++k ) {
						if( k != i && k != j ) {
							x = k;
							a[ x ] = 0;
							fin = true;
							break;
						}
					}
				}
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( i != x ) {
				printf( "? %d %d\n", x, i );
				fflush( stdout );
				scanf( "%d", &a[ i ] );
			}
		}
		printf( "!" );
		fflush( stdout );
		for( int i = 1; i <= n; ++i ) {
			printf( " %d", a[ i ] );
			fflush( stdout );
		}
		return 0;
	}
	srand( time( 0 ) );
	while( true ) {
		l = rand() % n + 1;
		r = l;
		while( r == l )
			r = rand() % n + 1;
		printf( "? %d %d\n", l, r );
		fflush( stdout );
		scanf( "%d", &x );
		if( __builtin_popcount( x ) <= ( ( int )log2( n ) + 2 ) / 2 )
			break;
	}
	for( int i = 1; i <= n; ++i ) {
		if( i == l ) {
			res[ i ] = -1;
			continue;
		}
		printf( "? %d %d\n", l, i );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		++sum[ res[ i ] ];
	}
	for( int i = 0; i < n; ++i )
		ma = max( ma, sum[ i ] );
	if( ma == 1 ) {
		a[ l ] = 0;
		x = l;
	} else {
		tmp = ma;
		while( tmp % 2 == 0 ) {
			tmp >>= 1;
		}
		if( tmp == 1 )
			--ma;
		for( int i = 0; i < n; ++i ) {
			if( sum[ i ] == ma ) {
				r = i;
				break;
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( res[ i ] == r )
				b.push_back( i );
		}
		b.push_back( l );
		sort( b.begin(), b.end() );
		while( true ) {
			x = rand() % n + 1;
			y = rand() % n + 1;
			if( x == y )
				continue;
			printf( "? %d %d\n", x, y );
			fflush( stdout );
			scanf( "%d", &tmp );
			if( ( tmp & r ) == 0 ) {
				tmp = x;
				break;
			}
		}
		for( int i = 0; i < b.size(); ++i ) {
			printf( "? %d %d\n", tmp, b[ i ] );
			fflush( stdout );
			scanf( "%d", &x );
			if( ( x & tmp ) == 0 ) {
				x = b[ i ];
				a[ x ] = 0;
				break;
			}
		}
	}
	for( int i = 1; i <= n; ++i ) {
		if( i != x ) {
			printf( "? %d %d\n", i, x );
			fflush( stdout );
			scanf( "%d", &a[ i ] );
		}
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", a[ i ] );
		fflush( stdout );
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int n, m;
int ans[ 2100 ];
int res[ 2100 ];
int id[ 2100 ];

void fuck();

int main() {
	int ma = 0, x, y;
	int tmp;
	scanf( "%d", &n );
	for( int i = 1; i <= n; ++i )
		id[ i ] = i;
	srand( time( 0 ) );
	m = n;
 	while( m > 2 ) {
		fuck();
	}
	while( true ) {
		tmp = id[ 1 ];
		while( tmp == id[ 1 ] || tmp == id[ 2 ] )
			tmp = rand() % n + 1;
		printf( "? %d %d\n", tmp, id[ 1 ] );
		fflush( stdout );
		scanf( "%d", &x );
		printf( "? %d %d\n", tmp, id[ 2 ] );
		fflush( stdout );
		scanf( "%d", &y );
		if( x < y )
			break;
		if( x > y ) {
			id[ 1 ] = id[ 2 ];
			break;
		}
	}
	ans[ id[ 1 ] ] = 0;
	for( int i = 1; i <= n; ++i ) {
		if( i == id[ 1 ] )
			continue;
		printf( "? %d %d\n", id[ 1 ], i );
		fflush( stdout );
		scanf( "%d", &ans[ i ] );
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", ans[ i ] );
		fflush( stdout );
	}
	return 0;
}

void fuck() {
	int mm = 0;
	int l, r, x;
	int val = 2047;
	int tmp[ 1100 ];
	while( true ) {
		l = rand() % m + 1;
		r = l;
		while( r == l )
			r = rand() % m + 1;
		printf( "? %d %d\n", id[ l ], id[ r ] );
		fflush( stdout );
		scanf( "%d", &x );
		if( __builtin_popcount( x ) <= ( ( int )log2( m ) + 2 ) / 2 )
			break;
	}
	for( int i = 1; i <= m; ++i ) {
		if( i == l ) {
			res[ i ] = -1;
			continue;
		}
		printf( "? %d %d\n", id[ l ], id[ i ] );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		val &= res[ i ];
	}
	for( int i = 1; i <= m; ++i ) {
		if( res[ i ] == val || res[ i ] == -1 )
			tmp[ ++mm ] = id[ i ];
	}
	for( int i = 1; i <= mm; ++i )
		id[ i ] = tmp[ i ];
	m = mm;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int a[ 2100 ];
int res[ 2100 ];
int sum[ 4200 ];
vector< int > b;

int main() {
	int n;
	int ma = 0, x, y;
	int l, r, tmp;
	scanf( "%d", &n );
	if( n == 3 ) {
		bool fin = false;
		for( int i = 1; !fin && i < n; ++i ) {
			for( int j = i + 1; ! fin && j <= n; ++j ) {
				printf( "? %d %d\n", i, j );
				fflush( stdout );
				scanf( "%d", &x );
				if( x == 3 ) {
					for( int k = 1; k <= n; ++k ) {
						if( k != i && k != j ) {
							x = k;
							a[ x ] = 0;
							fin = true;
							break;
						}
					}
				}
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( i != x ) {
				printf( "? %d %d\n", x, i );
				fflush( stdout );
				scanf( "%d", &a[ i ] );
			}
		}
		printf( "!" );
		fflush( stdout );
		for( int i = 1; i <= n; ++i ) {
			printf( " %d", a[ i ] );
			fflush( stdout );
		}
		return 0;
	}
	srand( time( 0 ) );
	while( true ) {
		l = rand() % n + 1;
		r = l;
		while( r == l )
			r = rand() % n + 1;
		printf( "? %d %d\n", l, r );
		fflush( stdout );
		scanf( "%d", &x );
		if( __builtin_popcount( x ) <= ( ( int )log2( n ) + 2 ) / 2 )
			break;
	}
	for( int i = 1; i <= n; ++i ) {
		if( i == l ) {
			res[ i ] = -1;
			continue;
		}
		printf( "? %d %d\n", l, i );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		++sum[ res[ i ] ];
	}
	for( int i = 0; i < n; ++i )
		ma = max( ma, sum[ i ] );
	if( ma == 1 ) {
		a[ l ] = 0;
		x = l;
	} else {
		tmp = ma;
		while( tmp % 2 == 0 ) {
			tmp >>= 1;
		}
		if( tmp == 1 )
			--ma;
		for( int i = 0; i < n; ++i ) {
			if( sum[ i ] == ma ) {
				r = i;
				break;
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( res[ i ] == r )
				b.push_back( i );
		}
		b.push_back( l );
		sort( b.begin(), b.end() );
		while( true ) {
			x = rand() % n + 1;
			y = rand() % n + 1;
			if( x == y )
				continue;
			tmp = lower_bound( b.begin(), b.end(), x ) - b.begin();
			if( tmp < b.size() && b[ tmp ] == x )
				continue;
			tmp = lower_bound( b.begin(), b.end(), y ) - b.begin();
			if( tmp < b.size() && b[ tmp ] == y )
				continue;
			printf( "? %d %d\n", x, y );
			fflush( stdout );
			scanf( "%d", &tmp );
			if( ( tmp & r ) == 0 ) {
				tmp = x;
				break;
			}
		}
		for( int i = 0; i < b.size(); ++i ) {
			printf( "? %d %d\n", tmp, b[ i ] );
			fflush( stdout );
			scanf( "%d", &x );
			if( ( x & tmp ) == 0 ) {
				x = b[ i ];
				a[ x ] = 0;
				break;
			}
		}
	}
	for( int i = 1; i <= n; ++i ) {
		if( i != x ) {
			printf( "? %d %d\n", i, x );
			fflush( stdout );
			scanf( "%d", &a[ i ] );
		}
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", a[ i ] );
		fflush( stdout );
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int n, m;
int ans[ 2100 ];
int res[ 2100 ];
int id[ 2100 ];

void fuck();

int main() {
	int ma = 0, x, y;
	int tmp;
	scanf( "%d", &n );
	for( int i = 1; i <= n; ++i )
		id[ i ] = i;
	srand( time( 0 ) );
	m = n;
 	while( m > 2 ) {
		fuck();
	}
	while( true ) {
		tmp = id[ 1 ];
		while( tmp == id[ 1 ] || tmp == id[ 2 ] )
			tmp = rand() % n + 1;
		printf( "? %d %d\n", tmp, id[ 1 ] );
		fflush( stdout );
		scanf( "%d", &x );
		printf( "? %d %d\n", tmp, id[ 2 ] );
		fflush( stdout );
		scanf( "%d", &y );
		if( x < y )
			break;
		if( x > y ) {
			id[ 1 ] = id[ 2 ];
			break;
		}
	}
	ans[ id[ 1 ] ] = 0;
	for( int i = 1; i <= n; ++i ) {
		if( i == id[ 1 ] )
			continue;
		printf( "? %d %d\n", id[ 1 ], i );
		fflush( stdout );
		scanf( "%d", &ans[ i ] );
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", ans[ i ] );
		fflush( stdout );
	}
	return 0;
}

void fuck() {
	int mm = 0;
	int l, r, x;
	int val = 2047;
	int tmp[ 1100 ];
	while( true ) {
		l = rand() % m + 1;
		r = l;
		while( r == l )
			r = rand() % m + 1;
		printf( "? %d %d\n", id[ l ], id[ r ] );
		fflush( stdout );
		scanf( "%d", &x );
		if( ( 1 << __builtin_popcount( x ) ) <= m  )
			break;
	}
	for( int i = 1; i <= m; ++i ) {
		if( i == l ) {
			res[ i ] = -1;
			continue;
		}
		printf( "? %d %d\n", id[ l ], id[ i ] );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		val &= res[ i ];
	}
	for( int i = 1; i <= m; ++i ) {
		if( res[ i ] == val || res[ i ] == -1 )
			tmp[ ++mm ] = id[ i ];
	}
	for( int i = 1; i <= mm; ++i )
		id[ i ] = tmp[ i ];
	m = mm;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int a[ 2100 ];
int res[ 2100 ];
int sum[ 4200 ];
vector< int > b;

int main() {
	int n;
	int ma = 0, x, y;
	int l, r, tmp;
	scanf( "%d", &n );
	if( n == 3 ) {
		bool fin = false;
		for( int i = 1; !fin && i < n; ++i ) {
			for( int j = i + 1; ! fin && j <= n; ++j ) {
				printf( "? %d %d\n", i, j );
				fflush( stdout );
				scanf( "%d", &x );
				if( x == 3 ) {
					for( int k = 1; k <= n; ++k ) {
						if( k != i && k != j ) {
							x = k;
							a[ x ] = 0;
							fin = true;
							break;
						}
					}
				}
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( i != x ) {
				printf( "? %d %d\n", x, i );
				fflush( stdout );
				scanf( "%d", &a[ i ] );
			}
		}
		printf( "!" );
		fflush( stdout );
		for( int i = 1; i <= n; ++i ) {
			printf( " %d", a[ i ] );
			fflush( stdout );
		}
		return 0;
	}
	srand( time( 0 ) );
	while( true ) {
		l = rand() % n + 1;
		r = l;
		while( r == l )
			r = rand() % n + 1;
		printf( "? %d %d\n", l, r );
		fflush( stdout );
		scanf( "%d", &x );
		if( __builtin_popcount( x ) <= ( ( int )log2( n ) + 2 ) / 2 )
			break;
	}
	for( int i = 1; i <= n; ++i ) {
		if( i == l ) {
			res[ i ] = -1;
			continue;
		}
		printf( "? %d %d\n", l, i );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		++sum[ res[ i ] ];
	}
	for( int i = 0; i < n; ++i )
		ma = max( ma, sum[ i ] );
	if( ma == 1 ) {
		a[ l ] = 0;
		x = l;
	} else {
		tmp = ma;
		while( tmp % 2 == 0 ) {
			tmp >>= 1;
		}
		if( tmp == 1 )
			--ma;
		for( int i = 0; i < n; ++i ) {
			if( sum[ i ] == ma ) {
				r = i;
				break;
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( res[ i ] == r )
				b.push_back( i );
		}
		b.push_back( l );
		sort( b.begin(), b.end() );
		while( true ) {
			x = rand() % n + 1;
			y = rand() % n + 1;
			if( x == y )
				continue;
			printf( "? %d %d\n", x, y );
			fflush( stdout );
			scanf( "%d", &tmp );
			if( ( tmp & r ) == 0 ) {
				tmp = x;
				break;
			}
		}
		for( int i = 0; i < b.size(); ++i ) {
			if( tmp == b[ i ] )
				continue;
			printf( "? %d %d\n", tmp, b[ i ] );
			fflush( stdout );
			scanf( "%d", &x );
			if( ( x & r ) == 0 ) {
				x = b[ i ];
				a[ x ] = 0;
				break;
			}
		}
	}
	for( int i = 1; i <= n; ++i ) {
		if( i != x ) {
			printf( "? %d %d\n", i, x );
			fflush( stdout );
			scanf( "%d", &a[ i ] );
		}
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", a[ i ] );
		fflush( stdout );
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int a[ 1100 ];
int res[ 1100 ];
int sum[ 2100 ];

int main() {
	int n;
	int ma = 0, x;
	scanf( "%d", &n );
	if( n == 3 ) {
		bool fin = false;
		for( int i = 1; !fin && i < n; ++i ) {
			for( int j = i + 1; ! fin && j <= n; ++j ) {
				printf( "? %d %d\n", i, j );
				fflush( stdout );
				scanf( "%d", &x );
				if( x == 3 ) {
					for( int k = 1; k <= n; ++k ) {
						if( k != i && k != j ) {
							x = k;
							a[ x ] = 0;
							fin = true;
							break;
						}
					}
				}
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( i != x ) {
				printf( "? %d %d\n", x, i );
				fflush( stdout );
				scanf( "%d", &a[ i ] );
			}
		}
		printf( "!" );
		fflush( stdout );
		for( int i = 1; i <= n; ++i ) {
			printf( " %d", a[ i ] );
			fflush( stdout );
		}
		return 0;
	}
	for( int i = 2; i <= n; ++i ) {
		printf( "? %d %d\n", 1, i );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		++sum[ res[ i ] ];
	}
	for( int i = 0; i <= 2100; ++i )
		ma = max( ma, sum[ i ] );
	if( ma == 1 ) {
		a[ 1 ] = 0;
		x = 1;
	} else {
		for( int i = 0; i <= 2100; ++i ) {
			if( sum[ i ] == ma - 1 && i < n ) {
				a[ 1 ] = i;
				break;
			}
		}
		for( int i = 2; i <= n; ++i ) {
			if( res[ i ] == a[ 1 ] ) {
				x = i;
				a[ i ] = 0;
				break;
			}
		}
	}
	for( int i = 1; i <= n; ++i ) {
		if( i != x ) {
			printf( "? %d %d\n", i, x );
			fflush( stdout );
			scanf( "%d", &a[ i ] );
		}
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", a[ i ] );
		fflush( stdout );
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int a[ 2100 ];
int res[ 2100 ];
int sum[ 4200 ];
vector< int > b;

int main() {
	int n;
	int ma = 0, x;
	int l, r, tmp;
	scanf( "%d", &n );
	if( n == 3 ) {
		bool fin = false;
		for( int i = 1; !fin && i < n; ++i ) {
			for( int j = i + 1; ! fin && j <= n; ++j ) {
				printf( "? %d %d\n", i, j );
				fflush( stdout );
				scanf( "%d", &x );
				if( x == 3 ) {
					for( int k = 1; k <= n; ++k ) {
						if( k != i && k != j ) {
							x = k;
							a[ x ] = 0;
							fin = true;
							break;
						}
					}
				}
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( i != x ) {
				printf( "? %d %d\n", x, i );
				fflush( stdout );
				scanf( "%d", &a[ i ] );
			}
		}
		printf( "!" );
		fflush( stdout );
		for( int i = 1; i <= n; ++i ) {
			printf( " %d", a[ i ] );
			fflush( stdout );
		}
		return 0;
	}
	srand( time( 0 ) );
	while( true ) {
		l = rand() % n + 1;
		r = l;
		while( r == l )
			r = rand() % n + 1;
		printf( "? %d %d\n", l, r );
		fflush( stdout );
		scanf( "%d", &x );
		if( __builtin_popcount( x ) <= 7 )
			break;
	}
	for( int i = 1; i <= n; ++i ) {
		if( i == l ) {
			res[ i ] = -1;
			continue;
		}
		printf( "? %d %d\n", l, i );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		++sum[ res[ i ] ];
	}
	for( int i = 0; i < n; ++i )
		ma = max( ma, sum[ i ] );
	if( ma == 1 ) {
		a[ l ] = 0;
		x = l;
	} else {
		tmp = ma;
		while( tmp % 2 == 0 ) {
			tmp >>= 1;
		}
		if( tmp == 1 )
			--ma;
		for( int i = 0; i < n; ++i ) {
			if( sum[ i ] == ma ) {
				r = i;
				break;
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( res[ i ] == r )
				b.push_back( i );
		}
		b.push_back( l );
		sort( b.begin(), b.end() );
		tmp = 1;
		x = 0;
		while( x < b.size() && tmp == b[ x ] ) {
			++x;
			++tmp;
		}
		for( int i = 0; i < b.size(); ++i ) {
			printf( "? %d %d\n", tmp, b[ i ] );
			fflush( stdout );
			scanf( "%d", &x );
			if( ( x & r ) == 0 ) {
				x = b[ i ];
				a[ x ] = 0;
				break;
			}
		}
	}
	for( int i = 1; i <= n; ++i ) {
		if( i != x ) {
			printf( "? %d %d\n", i, x );
			fflush( stdout );
			scanf( "%d", &a[ i ] );
		}
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", a[ i ] );
		fflush( stdout );
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int a[ 1100 ];
int res[ 1100 ];
int sum[ 2100 ];

int main() {
	int n;
	int ma = 0, x;
	scanf( "%d", &n );
	if( n == 3 ) {
		for( int i = 1; i < n; ++i ) {
			for( int j = i + 1; j <= n; ++j ) {
				printf( "? %d %d\n", i, j );
				fflush( stdout );
				scanf( "%d", &x );
				if( x == 3 ) {
					for( int k = 1; k <= 3; ++k ) {
						if( k != i && k != j ) {
							x = k;
							a[ x ] = 0;
							break;
						}
					}
					break;
				}
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( i != x ) {
				printf( "? %d %d", x, i );
				fflush( stdout );
				scanf( "%d", &a[ i ] );
			}
		}
		printf( "!" );
		for( int i = 1; i <= n; ++i )
			printf( " %d", a[ i ] );
		return 0;
	}
	for( int i = 2; i <= n; ++i ) {
		printf( "? %d %d\n", 1, i );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		++sum[ res[ i ] ];
	}
	for( int i = 0; i <= 2100; ++i )
		ma = max( ma, sum[ i ] );
	if( ma == 1 ) {
		a[ 1 ] = 0;
		x = 1;
	} else {
		for( int i = 0; i <= 2100; ++i ) {
			if( sum[ i ] == ma - 1 && i < n ) {
				a[ 1 ] = i;
				break;
			}
		}
		for( int i = 2; i <= n; ++i ) {
			if( res[ i ] == a[ 1 ] ) {
				x = i;
				a[ i ] = 0;
				break;
			}
		}
	}
	for( int i = 1; i <= n; ++i ) {
		if( i != x ) {
			printf( "? %d %d\n", i, x );
			fflush( stdout );
			scanf( "%d", &a[ i ] );
		}
	}
	printf( "!" );
	for( int i = 1; i <= n; ++i )
		printf( " %d", a[ i ] );
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int a[ 1100 ];
int res[ 1100 ];
int sum[ 2100 ];

int main() {
	int n;
	int ma = 0, x;
	scanf( "%d", &n );
	if( n == 3 ) {
		bool fin = false;
		for( int i = 1; !fin && i < n; ++i ) {
			for( int j = i + 1; ! fin && j <= n; ++j ) {
				printf( "? %d %d\n", i, j );
				fflush( stdout );
				scanf( "%d", &x );
				if( x == 3 ) {
					for( int k = 1; k <= n; ++k ) {
						if( k != i && k != j ) {
							x = k;
							a[ x ] = 0;
							fin = true;
							break;
						}
					}
				}
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( i != x ) {
				printf( "? %d %d\n", x, i );
				fflush( stdout );
				scanf( "%d", &a[ i ] );
			}
		}
		printf( "!" );
		fflush( stdout );
		for( int i = 1; i <= n; ++i ) {
			printf( " %d", a[ i ] );
			fflush( stdout );
		}
		return 0;
	}
	for( int i = 2; i <= n; ++i ) {
		printf( "? %d %d\n", 1, i );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		++sum[ res[ i ] ];
	}
	for( int i = 0; i < 2100; ++i )
		ma = max( ma, sum[ i ] );
	if( ma == 1 ) {
		a[ 1 ] = 0;
		x = 1;
	} else {
		int tmp = ma;
		while( tmp % 2 == 0 ) {
			tmp >>= 1;
		}
		if( tmp == 1 )
			--ma;
		for( int i = 0; i < n; ++i ) {
			if( sum[ i ] == ma ) {
				a[ 1 ] = i;
				break;
			}
		}
		for( int i = 2; i <= n; ++i ) {
			if( res[ i ] == a[ 1 ] ) {
				x = i;
				a[ i ] = 0;
				break;
			}
		}
	}
	for( int i = 1; i <= n; ++i ) {
		if( i != x ) {
			printf( "? %d %d\n", i, x );
			fflush( stdout );
			scanf( "%d", &a[ i ] );
		}
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", a[ i ] );
		fflush( stdout );
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int a[ 2100 ];
int res[ 2100 ];
int sum[ 4200 ];
vector< int > b;

int main() {
	int n;
	int ma = 0, x;
	int l, r, tmp;
	scanf( "%d", &n );
	if( n == 3 ) {
		bool fin = false;
		for( int i = 1; !fin && i < n; ++i ) {
			for( int j = i + 1; ! fin && j <= n; ++j ) {
				printf( "? %d %d\n", i, j );
				fflush( stdout );
				scanf( "%d", &x );
				if( x == 3 ) {
					for( int k = 1; k <= n; ++k ) {
						if( k != i && k != j ) {
							x = k;
							a[ x ] = 0;
							fin = true;
							break;
						}
					}
				}
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( i != x ) {
				printf( "? %d %d\n", x, i );
				fflush( stdout );
				scanf( "%d", &a[ i ] );
			}
		}
		printf( "!" );
		fflush( stdout );
		for( int i = 1; i <= n; ++i ) {
			printf( " %d", a[ i ] );
			fflush( stdout );
		}
		return 0;
	}
	srand( time( 0 ) );
	while( true ) {
		l = rand() % n + 1;
		r = l;
		while( r == l )
			r = rand() % n + 1;
		printf( "? %d %d\n", l, r );
		fflush( stdout );
		scanf( "%d", &x );
		if( __builtin_popcount( x ) <= ( int )log2( n ) / 2 )
			break;
	}
	for( int i = 1; i <= n; ++i ) {
		if( i == l ) {
			res[ i ] = -1;
			continue;
		}
		printf( "? %d %d\n", l, i );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		++sum[ res[ i ] ];
	}
	for( int i = 0; i < n; ++i )
		ma = max( ma, sum[ i ] );
	if( ma == 1 ) {
		a[ l ] = 0;
		x = l;
	} else {
		tmp = ma;
		while( tmp % 2 == 0 ) {
			tmp >>= 1;
		}
		if( tmp == 1 )
			--ma;
		for( int i = 0; i < n; ++i ) {
			if( sum[ i ] == ma ) {
				r = i;
				break;
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( res[ i ] == r )
				b.push_back( i );
		}
		b.push_back( l );
		sort( b.begin(), b.end() );
		while( true ) {
			x = rand() % n + 1;
			y = rand() % n + 1;
			if( x == y )
				continue;
			if( *lower_bound( b.begin(), b.end(), x ) == x )
				continue;
			if( *lower_bound( b.begin(), b.end(), y ) == y )
				continue;
			printf( "? %d %d\n", x, y );
			fflush( stdout );
			scanf( "%d", &tmp );
			if( ( tmp & r ) == 0 ) {
				tmp = x;
				break;
			}
		}
		for( int i = 0; i < b.size(); ++i ) {
			printf( "? %d %d\n", tmp, b[ i ] );
			fflush( stdout );
			scanf( "%d", &x );
			if( x == tmp ) {
				x = b[ i ];
				a[ x ] = 0;
				break;
			}
		}
	}
	for( int i = 1; i <= n; ++i ) {
		if( i != x ) {
			printf( "? %d %d\n", i, x );
			fflush( stdout );
			scanf( "%d", &a[ i ] );
		}
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", a[ i ] );
		fflush( stdout );
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int a[ 2100 ];
int res[ 2100 ];
int sum[ 4200 ];
vector< int > b;

int main() {
	int n;
	int ma = 0, x, y;
	int l, r, tmp;
	scanf( "%d", &n );
	if( n == 3 ) {
		bool fin = false;
		for( int i = 1; !fin && i < n; ++i ) {
			for( int j = i + 1; ! fin && j <= n; ++j ) {
				printf( "? %d %d\n", i, j );
				fflush( stdout );
				scanf( "%d", &x );
				if( x == 3 ) {
					for( int k = 1; k <= n; ++k ) {
						if( k != i && k != j ) {
							x = k;
							a[ x ] = 0;
							fin = true;
							break;
						}
					}
				}
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( i != x ) {
				printf( "? %d %d\n", x, i );
				fflush( stdout );
				scanf( "%d", &a[ i ] );
			}
		}
		printf( "!" );
		fflush( stdout );
		for( int i = 1; i <= n; ++i ) {
			printf( " %d", a[ i ] );
			fflush( stdout );
		}
		return 0;
	}
	srand( time( 0 ) );
	while( true ) {
		l = rand() % n + 1;
		r = l;
		while( r == l )
			r = rand() % n + 1;
		printf( "? %d %d\n", l, r );
		fflush( stdout );
		scanf( "%d", &x );
		if( __builtin_popcount( x ) <= ( ( int )log2( n ) + 2 ) / 2 )
			break;
	}
	for( int i = 1; i <= n; ++i ) {
		if( i == l ) {
			res[ i ] = -1;
			continue;
		}
		printf( "? %d %d\n", l, i );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		++sum[ res[ i ] ];
	}
	for( int i = 0; i < n; ++i )
		ma = max( ma, sum[ i ] );
	if( ma == 1 ) {
		a[ l ] = 0;
		x = l;
	} else {
		tmp = ma;
		while( tmp % 2 == 0 ) {
			tmp >>= 1;
		}
		if( tmp == 1 )
			--ma;
		for( int i = 0; i < n; ++i ) {
			if( sum[ i ] == ma ) {
				r = i;
				break;
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( res[ i ] == r )
				b.push_back( i );
		}
		b.push_back( l );
		sort( b.begin(), b.end() );
		while( true ) {
			x = rand() % n + 1;
			y = rand() % n + 1;
			if( x == y )
				continue;
			int t1, t2;
			t1 = lower_bound( b.begin(), b.end(), x ) - b;
			t2 = lower_bound( b.begin(), b.end(), y ) - b;
			if( t1 < b.size() && b[ t1 ] == x && t2 < b.size() && b[ t2 ] == y )
				continue;
			printf( "? %d %d\n", x, y );
			fflush( stdout );
			scanf( "%d", &tmp );
			if( ( tmp & r ) == 0 ) {
				if( t1 < b.size() && b[ t1 ] == x )
					tmp = y;
				else
					tmp = x;
				break;
			}
		}
		for( int i = 0; i < b.size(); ++i ) {
			if( tmp == b[ i ] )
				continue;
			printf( "? %d %d\n", tmp, b[ i ] );
			fflush( stdout );
			scanf( "%d", &x );
			if( ( x & r ) == 0 ) {
				x = b[ i ];
				a[ x ] = 0;
				break;
			}
		}
	}
	for( int i = 1; i <= n; ++i ) {
		if( i != x ) {
			printf( "? %d %d\n", i, x );
			fflush( stdout );
			scanf( "%d", &a[ i ] );
		}
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", a[ i ] );
		fflush( stdout );
	}
	return 0;
}


/*
 * Author: RainAir
 * Time: 2020-06-14 15:14:11
 */
#include <bits/stdc++.h>

#define fi first
#define se second
#define db double
#define U unsigned
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 2050;
int a[MAXN];
int w[233];
int N,len;
std::vector<P> S;
std::mt19937 g(time(NULL));
int n;
int __[MAXN*MAXN+MAXN];
bool can[MAXN*MAXN+MAXN];
int bb[MAXN];

inline int query(int x,int y){
    //return bb[x]|bb[y];
    if(x > y) std::swap(x,y);
    int id = x*n+y;
    if(can[id]) return __[id];
    can[id] = 1;
    printf("? %d %d\n",x,y);
    std::fflush(stdout);
    int res;scanf("%d",&res);return __[id] = res;
}

int ans[MAXN];

inline int calc(int x,int p){
    if(x == w[p]) return 0;
    int t = query(x,w[p]);
    return (t>>p)&1;
}

inline int get(int x){
    int res = 0;
    FOR(i,0,10){
        res |= calc(x,i)<<i;
    }
    return res;
}

int main(){
    scanf("%d",&n);
  //  FOR(i,1,n) bb[i] = n-i;
    while(true){
        int x = 1+g()%n,y = 1+g()%n;
        while(y == x) y = 1+g()%n;
        int t = query(x,y);
        FOR(i,0,10){
            if((t>>i)&1) continue;
            w[i] = x;
        }
        bool flag = 1;
        int cnt = 0;
        FOR(i,0,10){
//            DEBUG(w[i]);DEBUG(flag);
            flag &= (bool)w[i];
        }
        if(flag) break;
    }
    std::vector<int> S;
    std::shuffle(all(S),g);
    int ps = 1,val = get(1);
    FOR(i,2,n){
        if(query(ps,i) == val){
            ps = i;
            val = get(i);
        }
    }
    FOR(i,1,n){
        if(ps == i) a[i] = 0;
        else a[i] = query(ps,i);
    }
    printf("! ");
    FOR(i,1,n) printf("%d ",a[i]);
    puts("");std::fflush(stdout);
    return 0;
}


/*
 * Author: RainAir
 * Time: 2020-06-14 15:14:11
 */
#include <bits/stdc++.h>

#define fi first
#define se second
#define db double
#define U unsigned
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 1e5 + 5;
int a[MAXN];
int w[233];
int N,len;
std::vector<P> S;
std::mt19937 g(time(NULL));
std::map<P,int> __;
int tot = 0;
inline int query(int x,int y){
  //  assert(x!=y);++tot;
  //  return a[x]|a[y];
    if(x > y) std::swap(x,y);
    if(__.count(MP(x,y))) return __[MP(x,y)];
    printf("? %d %d\n",x,y);
    std::fflush(stdout);
    int res;scanf("%d",&res);
    assert(res!=-1);
    return __[MP(x,y)] = res;
}

int ans[MAXN];

inline int calc(int x,int p){
    if(x == w[p]) return 0;
    int t = query(x,w[p]);
    return (t>>p)&1;
}

inline int get(int x){
    int res = 0;
    FOR(i,0,10){
        res |= calc(x,i)<<i;
    }
    return res;
}

int main(){
    int n;scanf("%d",&n);
//    FOR(i,1,n)  scanf("%d",a+i);
    while(true){
        int x = 1+g()%n,y = 1+g()%n;
        while(y == x) y = 1+g()%n;
        int t = query(x,y);
        FOR(i,0,10){
            if((t>>i)&1) continue;
            w[i] = x;
        }
        bool flag = 1;
        FOR(i,0,10) flag &= w[i];
        if(flag) break;
    }
    std::vector<int> S;
    std::shuffle(all(S),g);
    int ps = 1,val = get(1);
    FOR(i,2,n){
        if(query(ps,i) == val){
            ps = i;
            val = get(i);
        }
    }
    printf("! ");
    FOR(i,1,n){
        if(ps == i) printf("%d ",0);
        else printf("%d ",query(ps,i));
    }
    puts("");std::fflush(stdout);
//    DEBUG(tot);
    return 0;
}


/*
 * Author: RainAir
 * Time: 2020-06-14 15:14:11
 */
#include <bits/stdc++.h>

#define fi first
#define se second
#define db double
#define U unsigned
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 1e5 + 5;
int a[MAXN];
int w[233];
int N,len;
std::vector<P> S;
std::mt19937 g(time(NULL));
std::map<P,int> __;
inline int query(int x,int y){
    if(x > y) std::swap(x,y);
    if(__.count(MP(x,y))) return __[MP(x,y)];
    printf("? %d %d\n",x,y);
    std::fflush(stdout);
    int res;scanf("%d",&res);return __[MP(x,y)] = res;
}

int ans[MAXN];

inline int calc(int x,int p){
    if(x == w[p]) return 0;
    int t = query(x,w[p]);
    return (t>>p)&1;
}

inline int get(int x){
    int res = 0;
    FOR(i,0,10){
        res |= calc(x,i)<<i;
    }
    return res;
}

int main(){
    int n;scanf("%d",&n);
    while(true){
        int x = 1+g()%n,y = 1+g()%n;
        while(y == x) y = 1+g()%n;
        int t = query(x,y);
        FOR(i,0,10){
            if((t>>i)&1) continue;
            w[i] = x;
        }
        bool flag = 1;
        FOR(i,0,10) flag &= w[i];
        if(flag) break;
    }
    std::vector<int> S;
    std::shuffle(all(S),g);
    int ps = 1,val = get(1);
    FOR(i,2,n){
        if(query(ps,i) == val){
            ps = i;
            val = get(i);
        }
    }
    printf("! ");
    FOR(i,1,n){
        if(ps == i) printf("%d ",0);
        else printf("%d ",query(ps,i));
    }
    puts("");std::fflush(stdout);
    return 0;
}


/*
 * Author: RainAir
 * Time: 2020-06-14 15:14:11
 */
#include <bits/stdc++.h>

#define fi first
#define se second
#define db double
#define U unsigned
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 2050;
int a[MAXN];
int w[233];
int N,len;
std::vector<P> S;
std::mt19937 g(time(NULL));
int n;
int __[MAXN*MAXN+MAXN];

inline int query(int x,int y){
    if(x > y) std::swap(x,y);
    int id = x*n+y;
    if(__[id]) return __[id];
    printf("? %d %d\n",x,y);
    std::fflush(stdout);
    int res;scanf("%d",&res);return __[id] = res;
}

int ans[MAXN];

inline int calc(int x,int p){
    if(x == w[p]) return 0;
    int t = query(x,w[p]);
    return (t>>p)&1;
}

inline int get(int x){
    int res = 0;
    FOR(i,0,10){
        res |= calc(x,i)<<i;
    }
    return res;
}

int main(){
    scanf("%d",&n);
    while(true){
        int x = 1+g()%n,y = 1+g()%n;
        while(y == x) y = 1+g()%n;
        int t = query(x,y);
        FOR(i,0,10){
            if((t>>i)&1) continue;
            w[i] = x;
        }
        bool flag = 1;
        FOR(i,0,10) flag &= w[i];
        if(flag) break;
    }
    std::vector<int> S;
    std::shuffle(all(S),g);
    int ps = 1,val = get(1);
    FOR(i,2,n){
        if(query(ps,i) == val){
            ps = i;
            val = get(i);
        }
    }
    FOR(i,1,n){
        if(ps == i) a[i] = 0;
        else a[i] = query(ps,i);
    }
    printf("! ");
    FOR(i,1,n) printf("%d ",a[i]);
    puts("");std::fflush(stdout);
    return 0;
}


/*
 * Author: RainAir
 * Time: 2020-06-14 15:14:11
 */
#include <bits/stdc++.h>

#define fi first
#define se second
#define db double
#define U unsigned
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 1e5 + 5;
int a[MAXN];
int w[233];
int N,len;
std::vector<P> S;
std::mt19937 g(time(NULL));
std::map<P,int> __;
int tot = 0;
inline int query(int x,int y){
  //  assert(x!=y);++tot;
  //  return a[x]|a[y];
//    if(x > y) std::swap(x,y);
//    if(__.count(MP(x,y))) return __[MP(x,y)];
    printf("? %d %d\n",x,y);
    std::fflush(stdout);
    int res;scanf("%d",&res);
//    assert(res!=-1);
    return res;
}

int ans[MAXN];

inline int calc(int x,int p){
    if(x == w[p]) return 0;
    int t = query(x,w[p]);
    return (t>>p)&1;
}

inline int get(int x){
    int res = 0;
    FOR(i,0,10){
        res |= calc(x,i)<<i;
    }
    return res;
}

int main(){
    int n;scanf("%d",&n);
//    FOR(i,1,n)  scanf("%d",a+i);
    while(true){
        int x = 1+g()%n,y = 1+g()%n;
        while(y == x) y = 1+g()%n;
        int t = query(x,y);
        FOR(i,0,10){
            if((t>>i)&1) continue;
            w[i] = x;
        }
        bool flag = 1;
        FOR(i,0,10) flag &= (bool)w[i];
        if(flag) break;
    }
    int ps = 1,val = get(1);
    FOR(i,2,n){
        if(query(ps,i) == val){
            ps = i;
            val = get(i);
        }
    }
    printf("! ");
    FOR(i,1,n){
        if(ps == i) printf("%d ",0);
        else printf("%d ",query(ps,i));
    }
    puts("");std::fflush(stdout);
//    DEBUG(tot);
    return 0;
}


/*
 * Author: RainAir
 * Time: 2020-06-14 15:14:11
 */
#include <bits/stdc++.h>

#define fi first
#define se second
#define db double
#define U unsigned
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 2050;
int a[MAXN];
int w[233];
int N,len;
std::vector<P> S;
std::mt19937 g(time(NULL));
int n;
int __[MAXN*MAXN+MAXN];
bool can[MAXN*MAXN+MAXN];

inline int query(int x,int y){
    if(x > y) std::swap(x,y);
    int id = x*n+y;
    if(can[id]) return __[id];
    can[id] = 1;
    printf("? %d %d\n",x,y);
    std::fflush(stdout);
    int res;scanf("%d",&res);return __[id] = res;
}

int ans[MAXN];

inline int calc(int x,int p){
    if(x == w[p]) return 0;
    int t = query(x,w[p]);
    return (t>>p)&1;
}

inline int get(int x){
    int res = 0;
    FOR(i,0,10){
        res |= calc(x,i)<<i;
    }
    return res;
}

int main(){
    scanf("%d",&n);
    while(true){
        int x = 1+g()%n,y = 1+g()%n;
        while(y == x) y = 1+g()%n;
        int t = query(x,y);
        FOR(i,0,10){
            if((t>>i)&1) continue;
            w[i] = x;
        }
        bool flag = 1;
        FOR(i,0,10) flag &= w[i];
        if(flag) break;
    }
    std::vector<int> S;
    std::shuffle(all(S),g);
    int ps = 1,val = get(1);
    FOR(i,2,n){
        if(query(ps,i) == val){
            ps = i;
            val = get(i);
        }
    }
    FOR(i,1,n){
        if(ps == i) a[i] = 0;
        else a[i] = query(ps,i);
    }
    printf("! ");
    FOR(i,1,n) printf("%d ",a[i]);
    puts("");std::fflush(stdout);
    return 0;
}


/*
 * Author: RainAir
 * Time: 2020-06-14 15:14:11
 */
#include <bits/stdc++.h>

#define fi first
#define se second
#define db double
#define U unsigned
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 1e5 + 5;
int a[MAXN];
int w[233];
int N,len;
std::vector<P> S;
std::mt19937 g(time(NULL));
std::map<P,int> __;
inline int query(int x,int y){
    if(x > y) std::swap(x,y);
    if(__.count(MP(x,y))) return __[MP(x,y)];
    printf("? %d %d\n",x,y);
    std::fflush(stdout);
    int res;scanf("%d",&res);return __[MP(x,y)] = res;
}

int ans[MAXN];

inline int calc(int x,int p){
    if(x == w[p]) return 0;
    int t = query(x,w[p]);
    return (t>>p)&1;
}

inline int get(int x){
    int res = 0;
    FOR(i,0,10){
        res |= calc(x,i)<<i;
    }
    return res;
}

int main(){
    int n;scanf("%d",&n);
    while(true){
        int x = 1+g()%n,y = 1+g()%n;
        while(y == x) y = 1+g()%n;
        int t = query(x,y);
        FOR(i,0,10){
            if((t>>i)&1) continue;
            w[i] = x;
        }
        bool flag = 1;
        FOR(i,0,10) flag &= w[i];
        if(flag) break;
    }
    std::vector<int> S;
    std::shuffle(all(S),g);
    int ps = 1,val = get(1);
    FOR(i,2,n){
        if(query(ps,i) == val){
            ps = i;
            val = get(i);
        }
    }
    FOR(i,1,n){
        if(ps == i) a[i] = 0;
        else a[i] = query(ps,i);
    }
    printf("! ");
    FOR(i,1,n) printf("%d ",a[i]);
    puts("");std::fflush(stdout);
    return 0;
}


/*
 * Author: RainAir
 * Time: 2020-06-14 15:14:11
 */
#include <bits/stdc++.h>

#define fi first
#define se second
#define db double
#define U unsigned
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 2050;
int a[MAXN];
int w[233];
int N,len;
std::vector<P> S;
std::mt19937 g(time(NULL));
std::unordered_map<int,int> __;
int n;
//int a[MAXN][MAXN];

inline int query(int x,int y){
    if(x > y) std::swap(x,y);
    int id = x*n+y;
    if(__.count(id)) return __[id];
    printf("? %d %d\n",x,y);
    std::fflush(stdout);
    int res;scanf("%d",&res);return __[id] = res;
}

int ans[MAXN];

inline int calc(int x,int p){
    if(x == w[p]) return 0;
    int t = query(x,w[p]);
    return (t>>p)&1;
}

inline int get(int x){
    int res = 0;
    FOR(i,0,10){
        res |= calc(x,i)<<i;
    }
    return res;
}

int main(){
    scanf("%d",&n);
    while(true){
        int x = 1+g()%n,y = 1+g()%n;
        while(y == x) y = 1+g()%n;
        int t = query(x,y);
        FOR(i,0,10){
            if((t>>i)&1) continue;
            w[i] = x;
        }
        bool flag = 1;
        FOR(i,0,10) flag &= w[i];
        if(flag) break;
    }
    std::vector<int> S;
    std::shuffle(all(S),g);
    int ps = 1,val = get(1);
    FOR(i,2,n){
        if(query(ps,i) == val){
            ps = i;
            val = get(i);
        }
    }
    FOR(i,1,n){
        if(ps == i) a[i] = 0;
        else a[i] = query(ps,i);
    }
    printf("! ");
    FOR(i,1,n) printf("%d ",a[i]);
    puts("");std::fflush(stdout);
    return 0;
}


/*
 * Author: RainAir
 * Time: 2020-06-14 15:14:11
 */
#include <bits/stdc++.h>

#define fi first
#define se second
#define db double
#define U unsigned
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 2050;
int a[MAXN];
int w[233];
int N,len;
std::vector<P> S;
std::mt19937 g(time(NULL));
//int a[MAXN][MAXN];

inline int query(int x,int y){
    if(x > y) std::swap(x,y);
//    if() return __[MP(x,y)];
    printf("? %d %d\n",x,y);
    std::fflush(stdout);
    int res;scanf("%d",&res);return res;
}

int ans[MAXN];

inline int calc(int x,int p){
    if(x == w[p]) return 0;
    int t = query(x,w[p]);
    return (t>>p)&1;
}

inline int get(int x){
    int res = 0;
    FOR(i,0,10){
        res |= calc(x,i)<<i;
    }
    return res;
}

int main(){
    int n;scanf("%d",&n);
    while(true){
        int x = 1+g()%n,y = 1+g()%n;
        while(y == x) y = 1+g()%n;
        int t = query(x,y);
        FOR(i,0,10){
            if((t>>i)&1) continue;
            w[i] = x;
        }
        bool flag = 1;
        FOR(i,0,10) flag &= w[i];
        if(flag) break;
    }
    std::vector<int> S;
    std::shuffle(all(S),g);
    int ps = 1,val = get(1);
    FOR(i,2,n){
        if(query(ps,i) == val){
            ps = i;
            val = get(i);
        }
    }
    FOR(i,1,n){
        if(ps == i) a[i] = 0;
        else a[i] = query(ps,i);
    }
    printf("! ");
    FOR(i,1,n) printf("%d ",a[i]);
    puts("");std::fflush(stdout);
    return 0;
}


/*
 * Author: RainAir
 * Time: 2020-06-14 15:14:11
 */
#include <bits/stdc++.h>

#define fi first
#define se second
#define db double
#define U unsigned
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 1e5 + 5;
int a[MAXN];
int w[233];
int N,len;
std::vector<P> S;
std::mt19937 g(time(NULL));
std::map<P,int> __;
int tot = 0;
inline int query(int x,int y){
  //  assert(x!=y);++tot;
  //  return a[x]|a[y];
    if(x > y) std::swap(x,y);
    if(__.count(MP(x,y))) return __[MP(x,y)];
    printf("? %d %d\n",x,y);
    std::fflush(stdout);
    int res;scanf("%d",&res);return __[MP(x,y)] = res;
}

int ans[MAXN];

inline int calc(int x,int p){
    if(x == w[p]) return 0;
    int t = query(x,w[p]);
    return (t>>p)&1;
}

inline int get(int x){
    int res = 0;
    FOR(i,0,10){
        res |= calc(x,i)<<i;
    }
    return res;
}

int main(){
    int n;scanf("%d",&n);
//    FOR(i,1,n)  scanf("%d",a+i);
    while(true){
        int x = 1+g()%n,y = 1+g()%n;
        while(y == x) y = 1+g()%n;
        int t = query(x,y);
        FOR(i,0,10){
            if((t>>i)&1) continue;
            w[i] = x;
        }
        bool flag = 1;
        FOR(i,0,10) flag &= w[i];
        if(flag) break;
    }
    std::vector<int> S;
    std::shuffle(all(S),g);
    int ps = 1,val = get(1);
    FOR(i,2,n){
        if(query(ps,i) == val){
            ps = i;
            val = get(i);
        }
    }
    printf("! ");
    FOR(i,1,n){
        if(ps == i) printf("%d ",0);
        else printf("%d ",query(ps,i));
    }
    puts("");std::fflush(stdout);
//    DEBUG(tot);
    return 0;
}


//      ——By DD_BOND

#include<bits/stdc++.h>

using namespace std;

#define fi first
#define se second
#define MP make_pair
#define pb push_back
#define eb emplace_back
#define rl register ll
#define ri register int
#define rs register short
#define pi 3.1415926535898
#define lowbit(a)  (a&(-a))
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2+1,r,rt<<1|1
#define INF   0x3f3f3f3f
#define Min(a,b,c)  min(a,min(b,c))
#define Max(a,b,c)  max(a,max(b,c))
#define debug(x)    cerr<<#x<<"="<<x<<"\n";
#define mst(a,b,c) std::memset(a,b,(c)*sizeof(int))
#define cpy(a,b,c) std::memcpy(a,b,(c)*sizeof(int))

//#pragma GCC optimize(3)
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

typedef double db;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> P;
typedef pair<ll,ll> Pll;
typedef unsigned long long ull;

constexpr int seed=131;
constexpr ll LLMAX=2e18;
constexpr int MOD=1e9+7;
constexpr double eps=1e-8;
constexpr int MAXN=1e6+10;
constexpr int hmod1=0x48E2DCE7;
constexpr int hmod2=0x60000005;

inline ll sqr(ll x){ return x*x; }
inline int sqr(int x){ return x*x; }
inline double sqr(double x){ return x*x; }
inline int mul(int x,int y){ return 1ll*x*y%MOD; }
inline int sub(int x,int y){ return x>=y?x-y:MOD+x-y; }
inline int add(int x,int y){ return x+y>=MOD?x+y-MOD:x+y; }
inline int dcmp(double x){  if(fabs(x)<eps) return 0;   return (x>0? 1: -1); }
inline ll qpow(ll a,ll n){ll sum=1;while(n){if(n&1)sum=sum*a%MOD;a=a*a%MOD;n>>=1;}return sum;}

ll gcd(ll a,ll b){ return b==0? a: gcd(b,a%b); }
ll exgcd(ll a,ll b,ll &x,ll &y){ ll d; (b==0? (x=1,y=0,d=a): (d=exgcd(b,a%b,y,x),y-=a/b*x)); return d; }

int query(int a,int b){
	cout<<"? "<<a<<' '<<b<<endl;	cout.flush();
	int x;	cin>>x;
	return x;
}

int ans[MAXN],n;

int search(int mid){
	ans[mid]=0;
	for(int i=1;i<=n;i++){
		if(i==mid)	continue;
		ans[i]=query(i,mid);
	}
	cout<<"! ";
	for(int i=1;i<=n;i++)	cout<<ans[i]<<' ';
	cout.flush();
	exit(0);
}

mt19937 Rand(chrono::steady_clock::now().time_since_epoch().count());

int main(void)
{
    ios::sync_with_stdio(false);    cin.tie(0);   cout.tie(0);
    // freopen("/Users/dd_bond/My_Mac/Resource/Project__C++/testdata.in","r",stdin);
    //freopen("/Users/dd_bond/My_Mac/Resource/Project__C++/testdata.out","w",stdout);
    int cur=11;	cin>>n;
    vector<int>a;
    for(int i=1;i<=n;i++)	a.pb(i);
    while(1){
    	int x,y,bit;
    	while(1){
    		x=a[Rand()%a.size()];
    		while((y=a[Rand()%a.size()])==x);
    		bit=query(x,y);
    		if(__builtin_popcount(bit)*2<=cur)	break;
    	}
    	vector<int>tmp;
    	tmp.pb(x);
    	for(int i=0;i<a.size();i++){
    		if(x==a[i])	continue;
    		int now=query(x,a[i]);
    		if((now|bit)==bit)	tmp.pb(a[i]);
    	}
    	a=tmp;
    	if(a.size()<=5){
	    	// cout<<"tmp=";
	    	// for(auto i:tmp)	cout<<i<<' ';
	    	// cout<<endl;
			if(a.size()!=2){
				int mn=INF;	P p;
				for(int i=0;i<a.size();i++){
					for(int j=i+1;j<a.size();j++){
						int val=query(a[i],a[j]);
						if(val<mn){
							mn=val;
							p={a[i],a[j]};
						}
					}
				}
				a.resize(2);
				a[0]=p.fi;
				a[1]=p.se;
    		}
    		while(1){
    			int val;
    			while(1){
    				val=Rand()%n+1;
    				if(val==a[0]||val==a[1])	continue;
    				else	break;
    			}
    			int l=query(a[0],val);
    			int r=query(a[1],val);
    			if(l==r)	continue;
    			if(l>r)		search(a[1]);
    			else		search(a[0]);
    		}
    	}
    	cur=__builtin_popcount(bit);
    }
    return 0;
}


//      ——By DD_BOND

#include<bits/stdc++.h>

using namespace std;

#define fi first
#define se second
#define MP make_pair
#define pb push_back
#define eb emplace_back
#define rl register ll
#define ri register int
#define rs register short
#define pi 3.1415926535898
#define lowbit(a)  (a&(-a))
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2+1,r,rt<<1|1
#define INF   0x3f3f3f3f
#define Min(a,b,c)  min(a,min(b,c))
#define Max(a,b,c)  max(a,max(b,c))
#define debug(x)    cerr<<#x<<"="<<x<<"\n";
#define mst(a,b,c) std::memset(a,b,(c)*sizeof(int))
#define cpy(a,b,c) std::memcpy(a,b,(c)*sizeof(int))

//#pragma GCC optimize(3)
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

typedef double db;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> P;
typedef pair<ll,ll> Pll;
typedef unsigned long long ull;

constexpr int seed=131;
constexpr ll LLMAX=2e18;
constexpr int MOD=1e9+7;
constexpr double eps=1e-8;
constexpr int MAXN=1e6+10;
constexpr int hmod1=0x48E2DCE7;
constexpr int hmod2=0x60000005;

inline ll sqr(ll x){ return x*x; }
inline int sqr(int x){ return x*x; }
inline double sqr(double x){ return x*x; }
inline int mul(int x,int y){ return 1ll*x*y%MOD; }
inline int sub(int x,int y){ return x>=y?x-y:MOD+x-y; }
inline int add(int x,int y){ return x+y>=MOD?x+y-MOD:x+y; }
inline int dcmp(double x){  if(fabs(x)<eps) return 0;   return (x>0? 1: -1); }
inline ll qpow(ll a,ll n){ll sum=1;while(n){if(n&1)sum=sum*a%MOD;a=a*a%MOD;n>>=1;}return sum;}

ll gcd(ll a,ll b){ return b==0? a: gcd(b,a%b); }
ll exgcd(ll a,ll b,ll &x,ll &y){ ll d; (b==0? (x=1,y=0,d=a): (d=exgcd(b,a%b,y,x),y-=a/b*x)); return d; }

int query(int a,int b){
	cout<<"? "<<a<<' '<<b<<endl;	cout.flush();
	int x;	cin>>x;
	return x;
}

int ans[MAXN],n;

int search(int mid){
	ans[mid]=0;
	for(int i=1;i<=n;i++){
		if(i==mid)	continue;
		ans[i]=query(i,mid);
	}
	cout<<"! ";
	for(int i=1;i<=n;i++)	cout<<ans[i]<<' ';
	cout.flush();
	exit(0);
}

int main(void)
{
    ios::sync_with_stdio(false);    cin.tie(0);   cout.tie(0);
    // freopen("/Users/dd_bond/My_Mac/Resource/Project__C++/testdata.in","r",stdin);
    //freopen("/Users/dd_bond/My_Mac/Resource/Project__C++/testdata.out","w",stdout);
    srand(time(0));
    int cur=11;	cin>>n;
    vector<int>a;
    for(int i=1;i<=n;i++)	a.pb(i);
    while(1){
    	int x,y,bit;
    	while(1){
    		x=a[rand()%a.size()];
    		while((y=a[rand()%a.size()])==x);
    		bit=query(x,y);
    		if(__builtin_popcount(bit)*2<=cur)	break;
    	}
    	vector<int>tmp;
    	tmp.pb(x);
    	for(int i=0;i<a.size();i++){
    		if(x==a[i])	continue;
    		int now=query(x,a[i]);
    		if((now|bit)==bit)	tmp.pb(a[i]);
    	}
    	a=tmp;
    	if(a.size()<=9){
	    	// cout<<"tmp=";
	    	// for(auto i:tmp)	cout<<i<<' ';
	    	// cout<<endl;
			if(a.size()!=2){
				int mn=INF;	P p;
				for(int i=0;i<a.size();i++){
					for(int j=i+1;j<a.size();j++){
						int val=query(a[i],a[j]);
						if(val>mn){
							mn=val;
							p={a[i],a[j]};
						}
					}
				}
				a.resize(2);
				a[0]=p.fi;
				a[1]=p.se;
    		}
    		while(1){
    			int val;
    			while(1){
    				val=rand()%n+1;
    				if(val==x||val==y)	continue;
    				else	break;
    			}
    			int l=query(a[0],val);
    			int r=query(a[1],val);
    			if(l==r)	continue;
    			if(l>r)		search(a[1]);
    			else		search(a[0]);
    		}
    	}
    	cur=__builtin_popcount(bit);
    }
    return 0;
}


//      ——By DD_BOND

#include<bits/stdc++.h>

using namespace std;

#define fi first
#define se second
#define MP make_pair
#define pb push_back
#define eb emplace_back
#define rl register ll
#define ri register int
#define rs register short
#define pi 3.1415926535898
#define lowbit(a)  (a&(-a))
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2+1,r,rt<<1|1
#define INF   0x3f3f3f3f3f3f3f3f
#define Min(a,b,c)  min(a,min(b,c))
#define Max(a,b,c)  max(a,max(b,c))
#define debug(x)    cerr<<#x<<"="<<x<<"\n";
#define mst(a,b,c) std::memset(a,b,(c)*sizeof(int))
#define cpy(a,b,c) std::memcpy(a,b,(c)*sizeof(int))

//#pragma GCC optimize(3)
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

typedef double db;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> P;
typedef pair<ll,ll> Pll;
typedef unsigned long long ull;

constexpr int seed=131;
constexpr ll LLMAX=2e18;
constexpr int MOD=1e9+7;
constexpr double eps=1e-8;
constexpr int MAXN=1e6+10;
constexpr int hmod1=0x48E2DCE7;
constexpr int hmod2=0x60000005;

inline ll sqr(ll x){ return x*x; }
inline int sqr(int x){ return x*x; }
inline double sqr(double x){ return x*x; }
inline int mul(int x,int y){ return 1ll*x*y%MOD; }
inline int sub(int x,int y){ return x>=y?x-y:MOD+x-y; }
inline int add(int x,int y){ return x+y>=MOD?x+y-MOD:x+y; }
inline int dcmp(double x){  if(fabs(x)<eps) return 0;   return (x>0? 1: -1); }
inline ll qpow(ll a,ll n){ll sum=1;while(n){if(n&1)sum=sum*a%MOD;a=a*a%MOD;n>>=1;}return sum;}

ll gcd(ll a,ll b){ return b==0? a: gcd(b,a%b); }
ll exgcd(ll a,ll b,ll &x,ll &y){ ll d; (b==0? (x=1,y=0,d=a): (d=exgcd(b,a%b,y,x),y-=a/b*x)); return d; }

int query(int a,int b){
	cout<<"? "<<a<<' '<<b<<endl;	cout.flush();
	int x;	cin>>x;
	return x;
}

int ans[MAXN],n;

int search(int mid){
	ans[mid]=0;
	for(int i=1;i<=n;i++){
		if(i==mid)	continue;
		ans[i]=query(i,mid);
	}
	cout<<"! ";
	for(int i=1;i<=n;i++)	cout<<ans[i]<<' ';
	cout.flush();
	exit(0);
}

int main(void)
{
    ios::sync_with_stdio(false);    cin.tie(0);   cout.tie(0);
    // freopen("/Users/dd_bond/My_Mac/Resource/Project__C++/testdata.in","r",stdin);
    //freopen("/Users/dd_bond/My_Mac/Resource/Project__C++/testdata.out","w",stdout);
    srand(time(0));
    int cur=11;	cin>>n;
    vector<int>a;
    for(int i=1;i<=n;i++)	a.pb(i);
    while(1){
    	int x,y,bit;
    	while(1){
    		x=a[rand()%a.size()];
    		while((y=a[rand()%a.size()])==x);
    		bit=query(x,y);
    		if(__builtin_popcount(bit)*2<=cur)	break;
    	}
    	vector<int>tmp;
    	tmp.pb(x);
    	for(int i=0;i<a.size();i++){
    		if(x==a[i])	continue;
    		int now=query(x,a[i]);
    		if((now|bit)==bit)	tmp.pb(a[i]);
    	}
    	a=tmp;
    	// cout<<"tmp=";
    	// for(auto i:tmp)	cout<<i<<' ';
    	// cout<<endl;

    	if(a.size()<=9){
    		while(1){
    			if(a.size()==2)	break;
    			int mn=INF;	P p;
    			for(int i=0;i<a.size();i++){
    				for(int j=i+1;j<a.size();j++){
    					int val=query(a[i],a[j]);
    					if(val>mn){
    						mn=val;
    						p={a[i],a[j]};
    					}
    				}
    			}
    		}
    		while(1){
    			int val;
    			while(1){
    				val=rand()%n+1;
    				if(val==x||val==y)	continue;
    				else	break;
    			}
    			int l=query(a[0],val);
    			int r=query(a[1],val);
    			if(l==r)	continue;
    			if(l>r)		search(a[1]);
    			else		search(a[0]);
    		}
    	}
    	cur=__builtin_popcount(bit);
    }
    return 0;
}


//      ——By DD_BOND

#include<bits/stdc++.h>

using namespace std;

#define fi first
#define se second
#define MP make_pair
#define pb push_back
#define eb emplace_back
#define rl register ll
#define ri register int
#define rs register short
#define pi 3.1415926535898
#define lowbit(a)  (a&(-a))
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2+1,r,rt<<1|1
#define INF   0x3f3f3f3f
#define Min(a,b,c)  min(a,min(b,c))
#define Max(a,b,c)  max(a,max(b,c))
#define debug(x)    cerr<<#x<<"="<<x<<"\n";
#define mst(a,b,c) std::memset(a,b,(c)*sizeof(int))
#define cpy(a,b,c) std::memcpy(a,b,(c)*sizeof(int))

//#pragma GCC optimize(3)
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

typedef double db;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> P;
typedef pair<ll,ll> Pll;
typedef unsigned long long ull;

constexpr int seed=131;
constexpr ll LLMAX=2e18;
constexpr int MOD=1e9+7;
constexpr double eps=1e-8;
constexpr int MAXN=1e6+10;
constexpr int hmod1=0x48E2DCE7;
constexpr int hmod2=0x60000005;

inline ll sqr(ll x){ return x*x; }
inline int sqr(int x){ return x*x; }
inline double sqr(double x){ return x*x; }
inline int mul(int x,int y){ return 1ll*x*y%MOD; }
inline int sub(int x,int y){ return x>=y?x-y:MOD+x-y; }
inline int add(int x,int y){ return x+y>=MOD?x+y-MOD:x+y; }
inline int dcmp(double x){  if(fabs(x)<eps) return 0;   return (x>0? 1: -1); }
inline ll qpow(ll a,ll n){ll sum=1;while(n){if(n&1)sum=sum*a%MOD;a=a*a%MOD;n>>=1;}return sum;}

ll gcd(ll a,ll b){ return b==0? a: gcd(b,a%b); }
ll exgcd(ll a,ll b,ll &x,ll &y){ ll d; (b==0? (x=1,y=0,d=a): (d=exgcd(b,a%b,y,x),y-=a/b*x)); return d; }

int query(int a,int b){
	cout<<"? "<<a<<' '<<b<<endl;	cout.flush();
	int x;	cin>>x;
	return x;
}

int ans[MAXN],n;

int search(int mid){
	ans[mid]=0;
	for(int i=1;i<=n;i++){
		if(i==mid)	continue;
		ans[i]=query(i,mid);
	}
	cout<<"! ";
	for(int i=1;i<=n;i++)	cout<<ans[i]<<' ';
	cout.flush();
	exit(0);
}

mt19937 Rand(chrono::steady_clock::now().time_since_epoch().count());

int main(void)
{
    ios::sync_with_stdio(false);    cin.tie(0);   cout.tie(0);
    // freopen("/Users/dd_bond/My_Mac/Resource/Project__C++/testdata.in","r",stdin);
    //freopen("/Users/dd_bond/My_Mac/Resource/Project__C++/testdata.out","w",stdout);
    int cur=11;	cin>>n;
    vector<int>a;
    for(int i=1;i<=n;i++)	a.pb(i);
    while(1){
    	int x,y,bit;
    	while(1){
    		x=a[Rand()%a.size()];
    		while((y=a[Rand()%a.size()])==x);
    		bit=query(x,y);
    		if(__builtin_popcount(bit)*2<=cur)	break;
    	}
    	vector<int>tmp;
    	tmp.pb(x);
    	for(int i=0;i<a.size();i++){
    		if(x==a[i])	continue;
    		int now=query(x,a[i]);
    		if((now|bit)==bit)	tmp.pb(a[i]);
    	}
    	a=tmp;
    	if(a.size()<=9){
	    	// cout<<"tmp=";
	    	// for(auto i:tmp)	cout<<i<<' ';
	    	// cout<<endl;
			if(a.size()!=2){
				int mn=INF;	P p;
				for(int i=0;i<a.size();i++){
					for(int j=i+1;j<a.size();j++){
						int val=query(a[i],a[j]);
						if(val>mn){
							mn=val;
							p={a[i],a[j]};
						}
					}
				}
				a.resize(2);
				a[0]=p.fi;
				a[1]=p.se;
    		}
    		while(1){
    			int val;
    			while(1){
    				val=Rand()%n+1;
    				if(val==a[0]||val==a[1])	continue;
    				else	break;
    			}
    			int l=query(a[0],val);
    			int r=query(a[1],val);
    			if(l==r)	continue;
    			if(l>r)		search(a[1]);
    			else		search(a[0]);
    		}
    	}
    	cur=__builtin_popcount(bit);
    }
    return 0;
}


//      ——By DD_BOND

#include<bits/stdc++.h>

using namespace std;

#define fi first
#define se second
#define MP make_pair
#define pb push_back
#define eb emplace_back
#define rl register ll
#define ri register int
#define rs register short
#define pi 3.1415926535898
#define lowbit(a)  (a&(-a))
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2+1,r,rt<<1|1
#define INF   0x3f3f3f3f
#define Min(a,b,c)  min(a,min(b,c))
#define Max(a,b,c)  max(a,max(b,c))
#define debug(x)    cerr<<#x<<"="<<x<<"\n";
#define mst(a,b,c) std::memset(a,b,(c)*sizeof(int))
#define cpy(a,b,c) std::memcpy(a,b,(c)*sizeof(int))

//#pragma GCC optimize(3)
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

typedef double db;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> P;
typedef pair<ll,ll> Pll;
typedef unsigned long long ull;

constexpr int seed=131;
constexpr ll LLMAX=2e18;
constexpr int MOD=1e9+7;
constexpr double eps=1e-8;
constexpr int MAXN=1e6+10;
constexpr int hmod1=0x48E2DCE7;
constexpr int hmod2=0x60000005;

inline ll sqr(ll x){ return x*x; }
inline int sqr(int x){ return x*x; }
inline double sqr(double x){ return x*x; }
inline int mul(int x,int y){ return 1ll*x*y%MOD; }
inline int sub(int x,int y){ return x>=y?x-y:MOD+x-y; }
inline int add(int x,int y){ return x+y>=MOD?x+y-MOD:x+y; }
inline int dcmp(double x){  if(fabs(x)<eps) return 0;   return (x>0? 1: -1); }
inline ll qpow(ll a,ll n){ll sum=1;while(n){if(n&1)sum=sum*a%MOD;a=a*a%MOD;n>>=1;}return sum;}

ll gcd(ll a,ll b){ return b==0? a: gcd(b,a%b); }
ll exgcd(ll a,ll b,ll &x,ll &y){ ll d; (b==0? (x=1,y=0,d=a): (d=exgcd(b,a%b,y,x),y-=a/b*x)); return d; }

int query(int a,int b){
	cout<<"? "<<a<<' '<<b<<endl;	cout.flush();
	int x;	cin>>x;
	return x;
}

int ans[MAXN],n;

int search(int mid){
	ans[mid]=0;
	for(int i=1;i<=n;i++){
		if(i==mid)	continue;
		ans[i]=query(i,mid);
	}
	cout<<"! ";
	for(int i=1;i<=n;i++)	cout<<ans[i]<<' ';
	cout.flush();
	exit(0);
}

mt19937 Rand(chrono::steady_clock::now().time_since_epoch().count());

int main(void)
{
    ios::sync_with_stdio(false);    cin.tie(0);   cout.tie(0);
    // freopen("/Users/dd_bond/My_Mac/Resource/Project__C++/testdata.in","r",stdin);
    //freopen("/Users/dd_bond/My_Mac/Resource/Project__C++/testdata.out","w",stdout);
    int cur=11;	cin>>n;
    vector<int>a;
    for(int i=1;i<=n;i++)	a.pb(i);
    while(1){
    	int x,y,bit;
    	while(1){
    		x=a[Rand()%a.size()];
    		while((y=a[Rand()%a.size()])==x);
    		bit=query(x,y);
    		if(__builtin_popcount(bit)*2<=cur)	break;
    	}
    	vector<int>tmp;
    	tmp.pb(x);
    	for(int i=0;i<a.size();i++){
    		if(x==a[i])	continue;
    		int now=query(x,a[i]);
    		if((now|bit)==bit)	tmp.pb(a[i]);
    	}
    	a=tmp;
    	if(a.size()<=3){
	    	// cout<<"tmp=";
	    	// for(auto i:tmp)	cout<<i<<' ';
	    	// cout<<endl;
			if(a.size()!=2){
				int mn=INF;	P p;
				for(int i=0;i<a.size();i++){
					for(int j=i+1;j<a.size();j++){
						int val=query(a[i],a[j]);
						if(val<mn){
							mn=val;
							p={a[i],a[j]};
						}
					}
				}
				a.resize(2);
				a[0]=p.fi;
				a[1]=p.se;
    		}
    		while(1){
    			int val;
    			while(1){
    				val=Rand()%n+1;
    				if(val==a[0]||val==a[1])	continue;
    				else	break;
    			}
    			int l=query(a[0],val);
    			int r=query(a[1],val);
    			if(l==r)	continue;
    			if(l>r)		search(a[1]);
    			else		search(a[0]);
    		}
    	}
    	cur=__builtin_popcount(bit);
    }
    return 0;
}


//      ——By DD_BOND

#include<bits/stdc++.h>

using namespace std;

#define fi first
#define se second
#define MP make_pair
#define pb push_back
#define eb emplace_back
#define rl register ll
#define ri register int
#define rs register short
#define pi 3.1415926535898
#define lowbit(a)  (a&(-a))
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2+1,r,rt<<1|1
#define INF   0x3f3f3f3f3f3f3f3f
#define Min(a,b,c)  min(a,min(b,c))
#define Max(a,b,c)  max(a,max(b,c))
#define debug(x)    cerr<<#x<<"="<<x<<"\n";
#define mst(a,b,c) std::memset(a,b,(c)*sizeof(int))
#define cpy(a,b,c) std::memcpy(a,b,(c)*sizeof(int))

//#pragma GCC optimize(3)
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

typedef double db;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> P;
typedef pair<ll,ll> Pll;
typedef unsigned long long ull;

constexpr int seed=131;
constexpr ll LLMAX=2e18;
constexpr int MOD=1e9+7;
constexpr double eps=1e-8;
constexpr int MAXN=1e6+10;
constexpr int hmod1=0x48E2DCE7;
constexpr int hmod2=0x60000005;

inline ll sqr(ll x){ return x*x; }
inline int sqr(int x){ return x*x; }
inline double sqr(double x){ return x*x; }
inline int mul(int x,int y){ return 1ll*x*y%MOD; }
inline int sub(int x,int y){ return x>=y?x-y:MOD+x-y; }
inline int add(int x,int y){ return x+y>=MOD?x+y-MOD:x+y; }
inline int dcmp(double x){  if(fabs(x)<eps) return 0;   return (x>0? 1: -1); }
inline ll qpow(ll a,ll n){ll sum=1;while(n){if(n&1)sum=sum*a%MOD;a=a*a%MOD;n>>=1;}return sum;}

ll gcd(ll a,ll b){ return b==0? a: gcd(b,a%b); }
ll exgcd(ll a,ll b,ll &x,ll &y){ ll d; (b==0? (x=1,y=0,d=a): (d=exgcd(b,a%b,y,x),y-=a/b*x)); return d; }

int query(int a,int b){
	cout<<"? "<<a<<' '<<b<<endl;	cout.flush();
	int x;	cin>>x;
	return x;
}

int ans[MAXN],n;

int search(int mid){
	ans[mid]=0;
	for(int i=1;i<=n;i++){
		if(i==mid)	continue;
		ans[i]=query(i,mid);
	}
	cout<<"! ";
	for(int i=1;i<=n;i++)	cout<<ans[i]<<' ';
	exit(0);
}

int main(void)
{
    ios::sync_with_stdio(false);    cin.tie(0);   cout.tie(0);
    // freopen("/Users/dd_bond/My_Mac/Resource/Project__C++/testdata.in","r",stdin);
    //freopen("/Users/dd_bond/My_Mac/Resource/Project__C++/testdata.out","w",stdout);
    int cur=11;	cin>>n;
    vector<int>a;
    for(int i=1;i<=n;i++)	a.pb(i);
    while(1){
    	int x,y,bit;
    	while(1){
    		x=a[rand()%a.size()];
    		while((y=a[rand()%a.size()])==x);
    		bit=query(x,y);
    		if(__builtin_popcount(bit)*2<=cur)	break;
    	}
    	vector<int>tmp;
    	tmp.pb(x);
    	for(int i=0;i<a.size();i++){
    		if(x==a[i])	continue;
    		int now=query(x,a[i]);
    		if((now|bit)==bit)	tmp.pb(a[i]);
    	}
    	a=tmp;
    	if(a.size()<=9){
    		while(1){
    			if(a.size()==2)	break;
    			int mn=INF;	P p;
    			for(int i=0;i<a.size();i++){
    				for(int j=i+1;j<a.size();j++){
    					int val=query(a[i],a[j]);
    					if(val>mn){
    						mn=val;
    						p={a[i],a[j]};
    					}
    				}
    			}
    		}
    		while(1){
    			int val;
    			while(1){
    				val=rand()%n+1;
    				if(val==x||val==y)	continue;
    				else	break;
    			}
    			int l=query(a[0],val);
    			int r=query(a[1],val);
    			if(l==r)	continue;
    			if(l>r)		search(a[1]);
    			else		search(a[0]);
    		}
    	}
    	cur=__builtin_popcount(bit);
    }
    return 0;
}


//      ——By DD_BOND

#include<bits/stdc++.h>

using namespace std;

#define fi first
#define se second
#define MP make_pair
#define pb push_back
#define eb emplace_back
#define rl register ll
#define ri register int
#define rs register short
#define pi 3.1415926535898
#define lowbit(a)  (a&(-a))
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2+1,r,rt<<1|1
#define INF   0x3f3f3f3f3f3f3f3f
#define Min(a,b,c)  min(a,min(b,c))
#define Max(a,b,c)  max(a,max(b,c))
#define debug(x)    cerr<<#x<<"="<<x<<"\n";
#define mst(a,b,c) std::memset(a,b,(c)*sizeof(int))
#define cpy(a,b,c) std::memcpy(a,b,(c)*sizeof(int))

//#pragma GCC optimize(3)
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

typedef double db;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> P;
typedef pair<ll,ll> Pll;
typedef unsigned long long ull;

constexpr int seed=131;
constexpr ll LLMAX=2e18;
constexpr int MOD=1e9+7;
constexpr double eps=1e-8;
constexpr int MAXN=1e6+10;
constexpr int hmod1=0x48E2DCE7;
constexpr int hmod2=0x60000005;

inline ll sqr(ll x){ return x*x; }
inline int sqr(int x){ return x*x; }
inline double sqr(double x){ return x*x; }
inline int mul(int x,int y){ return 1ll*x*y%MOD; }
inline int sub(int x,int y){ return x>=y?x-y:MOD+x-y; }
inline int add(int x,int y){ return x+y>=MOD?x+y-MOD:x+y; }
inline int dcmp(double x){  if(fabs(x)<eps) return 0;   return (x>0? 1: -1); }
inline ll qpow(ll a,ll n){ll sum=1;while(n){if(n&1)sum=sum*a%MOD;a=a*a%MOD;n>>=1;}return sum;}

ll gcd(ll a,ll b){ return b==0? a: gcd(b,a%b); }
ll exgcd(ll a,ll b,ll &x,ll &y){ ll d; (b==0? (x=1,y=0,d=a): (d=exgcd(b,a%b,y,x),y-=a/b*x)); return d; }

int query(int a,int b){
	cout<<"? "<<a<<' '<<b<<endl;	cout.flush();
	int x;	cin>>x;
	return x;
}

int ans[MAXN],n;

int search(int mid){
	ans[mid]=0;
	for(int i=1;i<=n;i++){
		if(i==mid)	continue;
		ans[i]=query(i,mid);
	}
	cout<<"! ";
	for(int i=1;i<=n;i++)	cout<<ans[i]<<' ';
	exit(0);
}

int main(void)
{
    ios::sync_with_stdio(false);    cin.tie(0);   cout.tie(0);
    // freopen("/Users/dd_bond/My_Mac/Resource/Project__C++/testdata.in","r",stdin);
    //freopen("/Users/dd_bond/My_Mac/Resource/Project__C++/testdata.out","w",stdout);
    int cur=11;	cin>>n;
    vector<int>a;
    for(int i=1;i<=n;i++)	a.pb(i);
    while(1){
    	int x,y,bit;
    	while(1){
    		x=a[rand()%a.size()];
    		while((y=a[rand()%a.size()])==x);
    		bit=query(x,y);
    		if(__builtin_popcount(bit)*2<=cur)	break;
    	}
    	vector<int>tmp;
    	tmp.pb(x);
    	for(int i=0;i<a.size();i++){
    		if(x==a[i])	continue;
    		int now=query(x,a[i]);
    		if((now|bit)==bit)	tmp.pb(a[i]);
    	}
    	a=tmp;
    	if(a.size()<=9){
    		while(1){
    			if(a.size()==2)	break;
    			int mn=INF;	P p;
    			for(int i=0;i<a.size();i++){
    				for(int j=i+1;j<a.size();j++){
    					int val=query(a[i],a[j]);
    					if(val>mn){
    						mn=val;
    						p={a[i],a[j]};
    					}
    				}
    			}
    		}
    		cout<<a.size()<<endl;
    		while(1){
    			int val;
    			while(1){
    				val=rand()%n+1;
    				if(val==x||val==y)	continue;
    				else	break;
    			}
    			int l=query(a[0],val);
    			int r=query(a[1],val);
    			if(l==r)	continue;
    			if(l>r)		search(a[1]);
    			else		search(a[0]);
    		}
    	}
    	cur=__builtin_popcount(bit);
    }
    return 0;
}


//      ——By DD_BOND

#include<bits/stdc++.h>

using namespace std;

#define fi first
#define se second
#define MP make_pair
#define pb push_back
#define eb emplace_back
#define rl register ll
#define ri register int
#define rs register short
#define pi 3.1415926535898
#define lowbit(a)  (a&(-a))
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2+1,r,rt<<1|1
#define INF   0x3f3f3f3f
#define Min(a,b,c)  min(a,min(b,c))
#define Max(a,b,c)  max(a,max(b,c))
#define debug(x)    cerr<<#x<<"="<<x<<"\n";
#define mst(a,b,c) std::memset(a,b,(c)*sizeof(int))
#define cpy(a,b,c) std::memcpy(a,b,(c)*sizeof(int))

//#pragma GCC optimize(3)
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

typedef double db;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> P;
typedef pair<ll,ll> Pll;
typedef unsigned long long ull;

constexpr int seed=131;
constexpr ll LLMAX=2e18;
constexpr int MOD=1e9+7;
constexpr double eps=1e-8;
constexpr int MAXN=1e6+10;
constexpr int hmod1=0x48E2DCE7;
constexpr int hmod2=0x60000005;

inline ll sqr(ll x){ return x*x; }
inline int sqr(int x){ return x*x; }
inline double sqr(double x){ return x*x; }
inline int mul(int x,int y){ return 1ll*x*y%MOD; }
inline int sub(int x,int y){ return x>=y?x-y:MOD+x-y; }
inline int add(int x,int y){ return x+y>=MOD?x+y-MOD:x+y; }
inline int dcmp(double x){  if(fabs(x)<eps) return 0;   return (x>0? 1: -1); }
inline ll qpow(ll a,ll n){ll sum=1;while(n){if(n&1)sum=sum*a%MOD;a=a*a%MOD;n>>=1;}return sum;}

ll gcd(ll a,ll b){ return b==0? a: gcd(b,a%b); }
ll exgcd(ll a,ll b,ll &x,ll &y){ ll d; (b==0? (x=1,y=0,d=a): (d=exgcd(b,a%b,y,x),y-=a/b*x)); return d; }

int query(int a,int b){
	cout<<"? "<<a<<' '<<b<<endl;	cout.flush();
	int x;	cin>>x;
	return x;
}

int ans[MAXN],n;

int search(int mid){
	ans[mid]=0;
	for(int i=1;i<=n;i++){
		if(i==mid)	continue;
		ans[i]=query(i,mid);
	}
	cout<<"! ";
	for(int i=1;i<=n;i++)	cout<<ans[i]<<' ';
	cout.flush();
	exit(0);
}

mt19937 Rand(chrono::steady_clock::now().time_since_epoch().count());

int main(void)
{
    ios::sync_with_stdio(false);    cin.tie(0);   cout.tie(0);
    // freopen("/Users/dd_bond/My_Mac/Resource/Project__C++/testdata.in","r",stdin);
    //freopen("/Users/dd_bond/My_Mac/Resource/Project__C++/testdata.out","w",stdout);
    int cur=11;	cin>>n;
    vector<int>a;
    for(int i=1;i<=n;i++)	a.pb(i);
    while(1){
    	int x,y,bit;
    	while(1){
    		x=a[Rand()%a.size()];
    		while((y=a[Rand()%a.size()])==x);
    		bit=query(x,y);
    		if(__builtin_popcount(bit)*2<=cur)	break;
    	}
    	vector<int>tmp;
    	tmp.pb(x);
    	for(int i=0;i<a.size();i++){
    		if(x==a[i])	continue;
    		int now=query(x,a[i]);
    		if((now|bit)==bit)	tmp.pb(a[i]);
    	}
    	a=tmp;
    	if(a.size()<=9){
	    	// cout<<"tmp=";
	    	// for(auto i:tmp)	cout<<i<<' ';
	    	// cout<<endl;
			if(a.size()!=2){
				int mn=INF;	P p;
				for(int i=0;i<a.size();i++){
					for(int j=i+1;j<a.size();j++){
						int val=query(a[i],a[j]);
						if(val<mn){
							mn=val;
							p={a[i],a[j]};
						}
					}
				}
				a.resize(2);
				a[0]=p.fi;
				a[1]=p.se;
    		}
    		while(1){
    			int val;
    			while(1){
    				val=Rand()%n+1;
    				if(val==a[0]||val==a[1])	continue;
    				else	break;
    			}
    			int l=query(a[0],val);
    			int r=query(a[1],val);
    			if(l==r)	continue;
    			if(l>r)		search(a[1]);
    			else		search(a[0]);
    		}
    	}
    	cur=__builtin_popcount(bit);
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 2e5 + 5;

int bound[5];
struct Train{
    int id;
    int h,m;
    bool operator <(const Train &b){
        return m<b.m;
    }
}tra[MAXN];
int main(){
//    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);
    int n,h,m,k;
    scanf("%d%d%d%d",&n,&h,&m,&k);
    for(int i=0;i<n;i++){
        scanf("%d%d",&tra[i].h,&tra[i].m);
        if(tra[i].m>=m/2)   tra[i].m-=m/2;
        tra[i].id=i+1;
    }
    if(k==1){
        printf("0 0\n\n");
        return 0;
    }

    sort(tra,tra+n);
    int tn=n;
    for(int i=0;i<n;i++){
        tra[tn]=tra[i];
        tra[tn].m+=m/2;
        tn++;
    }

    int ans1,ans2,l,r;
    int now=k;              //右边界
    bound[0]=bound[1]=-1;
    for(int i=0;i<n;i++){
        if(tra[i].m>0&&tra[i].m<k){
            if(bound[0]==-1)
                bound[0]=i;
            bound[1]=i;
        }
    }
    if(bound[0]==-1){
        printf("0 %d\n\n",now);
        return 0;
    }
    ans1=bound[1]-bound[0]+1;
    ans2=now;
    l=bound[0],r=bound[1];

    while(1){
        int d1=tra[bound[0]].m-(now-k);
        int d2=d1;
//        if(bound[1]+1<tn)
//            d2=tra[bound[1]+1].m-now+1;

        now+=min(d1,d2);
        if(now-k>=m/2)  break;

        bool flag=0;
        for(int i=bound[0];i<tn&&tra[i].m<now;i++){
            if(tra[i].m>now-k){
                bound[0]=i;
                flag=1;
                break;
            }
        }
        if(!flag){
            if(now>=m/2)    now-=m/2;
            printf("0 %d\n\n",now);
            return 0;
        }
        if(bound[0]>=n) break;
        bound[1]=max(bound[1],bound[0]);
        for(int i=bound[1];i<tn;i++){
            if(tra[i].m>=now)    break;
            bound[1]=i;
        }

        if(bound[1]-bound[0]+1<ans1){
            ans1=bound[1]-bound[0]+1;
            ans2=now;
            l=bound[0],r=bound[1];
        }
    }

    if(ans2>=m/2)   ans2-=m/2;
    printf("%d %d\n",ans1,ans2);
    for(int i=l;i<=r;i++)
        printf("%d ",tra[i].id);
    puts("");

    return 0;
}


#include <bits/stdc++.h>

typedef long long ll;
using namespace std;

int main()
{
    ll n, h, m, k;
    cin >> n >> h >> m >> k;
    vector<pair<ll, int> > trains(n);
    for (int i = 0; i < n; ++i)
    {
        ll h1, m1;
        cin >> h1 >> m1;
        trains[i] = { (h1 * m + m1) % (m / 2), i};
    }
    sort(trains.begin(), trains.end());
    for (int i = 0; i < n; ++i)
        trains.push_back({ trains[i].first + (m / 2), trains[i].second });
    ll ans = n + 1, anst = 0;
    for (int i = 0; i < n; ++i)
    {
        ll nt = trains[i].first + k;
        ll l = 0, r = n+1;
        while (r-l > 1)
        {
            ll mid = l + (r - l) / 2;
            if (trains[i + mid - 1].first < nt)
                l = mid;
            else r = mid;
        }
        if (l-1 < ans)
            ans = l-1, anst = trains[i].first;
    }
    cout << ans << ' ' << (anst + k) % (m/2) << '\n';
    for (int i = 0; i < n; ++i)
    {
        if (anst < trains[i].first && trains[i].first < anst + k)
            cout << trains[i].second + 1 << '\n';
    }
    //system("pause");
    return 0;
}


#include <bits/stdc++.h>

typedef long long ll;
using namespace std;

int main()
{
    ll n, h, m, k;
    cin >> n >> h >> m >> k;
    vector<pair<ll, int> > trains(n);
    for (int i = 0; i < n; ++i)
    {
        ll h1, m1;
        cin >> h1 >> m1;
        trains[i] = { (h1 * m + m1) % (m / 2), i};
    }
    sort(trains.begin(), trains.end());
    for (int i = 0; i < n; ++i)
        trains.push_back({ trains[i].first + (m / 2), trains[i].second });
    ll ans = n + 1, anst = 0, ansi = 0;
    for (int i = 0; i < n; ++i)
    {
        ll nt = trains[i].first + k;
        ll l = 0, r = n+1;
        while (r-l > 1)
        {
            ll mid = l + (r - l) / 2;
            if (trains[i + mid - 1].first < nt)
                l = mid;
            else r = mid;
        }
        if (l-1 < ans)
            ans = l-1, ansi = i+1, anst = trains[i].first;
    }
    cout << ans << ' ' << (anst + k) % (m/2) << '\n';
    for (int i = ansi; i < ansi + ans; ++i)
        cout << trains[i].second+1 << ' ';
    //system("pause");
    return 0;
}


#include <bits/stdc++.h>

typedef long long ll;
using namespace std;

int main()
{
    ll n, h, m, k;
    cin >> n >> h >> m >> k;
    vector<pair<ll, int> > trains(n);
    for (int i = 0; i < n; ++i)
    {
        ll h1 = rand() % 100000, m1 = 69503268;
        //cin >> h1 >> m1;
        trains[i] = { (h1 * m + m1) % (m / 2), i};
    }
    sort(trains.begin(), trains.end());
    for (int i = 0; i < n; ++i)
        trains.push_back({ trains[i].first + (m / 2), trains[i].second });
    ll ans = n + 1, anst = 0;
    for (int i = 0; i < n; ++i)
    {
        ll nt = trains[i].first + k;
        ll l = 0, r = n+1;
        while (r-l > 1)
        {
            ll mid = l + (r - l) / 2;
            if (trains[i + mid - 1].first < nt)
                l = mid;
            else r = mid;
        }
        if (l-1 < ans)
            ans = l-1, anst = trains[i].first;
    }
    cout << ans << ' ' << (anst + k) % (m/2) << '\n';
    for (int i = 0; i < n; ++i)
    {
        if (anst < trains[i].first && trains[i].first < anst + k)
            cout << trains[i].second + 1 << ' ';
    }
    //system("pause");
    return 0;
}


#include <bits/stdc++.h>

typedef long long ll;
using namespace std;

int main()
{
    ll n, h, m, k;
    cin >> n >> h >> m >> k;
    map<ll, int> ord;
    vector<pair<ll, int> > trains, nums(n);
    for (int i = 0; i < n; ++i)
    {
        ll h1, m1;
        cin >> h1 >> m1;
        ord[(h1 * m + m1) % (m / 2)]++;
        nums[i] = { (h1 * m + m1) % (m / 2), i};
    }
    vector<ll> sums(n + k + 1);
    for (auto u : ord)
        trains.push_back(u);
    for (int i = 0; i < k; ++i)
        trains.push_back({ trains[i].first + (m / 2), trains[i].second });
    for (int i = 0; i < n + k; ++i)
        sums[i + 1] = sums[i] + trains[i].second;
    ll ans = n + 1, anst = 0;
    for (int i = 0; i < n; ++i)
    {
        ll nt = trains[i].first + k;
        ll l = 0, r = k+1;
        while (r-l > 1)
        {
            ll mid = l + (r - l) / 2;
            if (trains[i + mid - 1].first < nt)
                l = mid;
            else r = mid;
        }
        ll cost = sums[i + l - 1] - sums[i];
        if (cost < ans)
            ans = cost, anst = i;
    }
    cout << ans << ' ' << anst << '\n';
    for (int i = 0; i < n; ++i)
    {
        if (anst < nums[i].first && nums[i].first < anst + k)
            cout << nums[i].second + 1 << '\n';
    }
    //system("pause");
    return 0;
}


#include <bits/stdc++.h>

typedef long long ll;
using namespace std;

int main()
{
    ll n, h, m, k;
    cin >> n >> h >> m >> k;
    map<ll, int> ord;
    vector<pair<ll, int> > trains, nums(n);
    for (int i = 0; i < n; ++i)
    {
        ll h1, m1;
        cin >> h1 >> m1;
        ord[(h1 * m + m1) % (m / 2)]++;
        nums[i] = { (h1 * m + m1) % (m / 2), i};
    }
    vector<ll> sums(n + k + 1);
    for (auto u : ord)
        trains.push_back(u);
    for (int i = 0; i < k; ++i)
        trains.push_back({ trains[i].first + (m / 2), trains[i].second });
    for (int i = 0; i < n + k; ++i)
        sums[i + 1] = sums[i] + trains[i].second;
    ll ans = n + 1, anst = 0;
    for (int i = 0; i < n; ++i)
    {
        ll nt = trains[i].first + k;
        ll l = 0, r = k+1;
        while (r-l > 1)
        {
            ll mid = l + (r - l) / 2;
            if (trains[i + mid - 1].first < nt)
                l = mid;
            else r = mid;
        }
        ll cost = sums[i + l - 1] - sums[i];
        if (cost < ans)
            ans = cost, anst = trains[i].first;
    }
    cout << ans << ' ' << (anst + k) % (m/2) << '\n';
    for (int i = 0; i < n; ++i)
    {
        if (anst < nums[i].first && nums[i].first < anst + k)
            cout << nums[i].second + 1 << '\n';
    }
    //system("pause");
    return 0;
}


#include <bits/stdc++.h>

typedef long long ll;
using namespace std;

int main()
{
    ll n, h, m, k;
    cin >> n >> h >> m >> k;
    vector<pair<ll, int> > trains(n);
    for (int i = 0; i < n; ++i)
    {
        ll h1, m1;
        cin >> h1 >> m1;
        trains[i] = { (h1 * m + m1) % (m / 2), i};
    }
    sort(trains.begin(), trains.end());
    for (int i = 0; i < n; ++i)
        trains.push_back({ trains[i].first + (m / 2), trains[i].second });
    ll ans = n + 1, anst = 0;
    for (int i = 0; i < n; ++i)
    {
        ll nt = trains[i].first + k;
        ll l = 0, r = n+1;
        while (r-l > 1)
        {
            ll mid = l + (r - l) / 2;
            if (trains[i + mid - 1].first < nt)
                l = mid;
            else r = mid;
        }
        if (l-1 < ans)
            ans = l-1, anst = trains[i].first;
    }
    cout << ans << ' ' << (anst + k) % (m/2) << '\n';
    for (int i = 0; i < n; ++i)
    {
        if (anst < trains[i].first && trains[i].first < anst + k)
            cout << trains[i].second + 1 << ' ';
    }
    //system("pause");
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define N 100000
typedef long long ll;

int n,h,m,k;
vector<int> nh,nm;
map<int,vector<int>> mp;

int main(){
	scanf("%d%d%d%d",&n,&h,&m,&k);
	nh=vector<int> (n);
	nm=vector<int> (n);
	for(int i=0;i<n;i++){
		scanf("%d%d",&nh[i],&nm[i]);
		mp[nm[i]%(m/2)].push_back(i+1);
	}
	if(n==1) {printf("0 0\n\n");return 0;}

	int ans=INT_MAX;
	int all=0;
	int st=0;
	auto it2=mp.begin();
	bool flag=false;
	for(auto it=mp.begin();it!=mp.end();it++){
		//cout<<"here "<<it->first<<" "<<it2->first<<endl;
		if(it2==it&&!flag) { it2++;}
		else { all-=it->second.size();}

		int end=it->first+k-1;
		if(end>=m/2){
			if(!flag){
				flag=true;
				while(it2!=mp.end()){
					all+=it2->second.size();
					it2++;
				}
				it2=mp.begin();
			}
		}
		if(it2==mp.end()) { flag=true;it2=mp.begin();}
		while(it2!=mp.end()&&(it2->first>it->first&&it2->first<=end||end>=(m/2)&&it2->first<=end%(m/2))){
			all+=it2->second.size();
			it2++;
		}

		if(all<ans) {ans=all;st=it->first;}
	}
	printf("%d %d\n",ans,(st+k)%(m/2));
	for(auto it=mp.begin();it!=mp.end();it++){
		int he=it->first;
		int end=st+k-1;
		if(he>st&&he<=end||end>m/2&&he<=end)
			for(int j=0;j<it->second.size();j++){
				printf("%d ",it->second[j]);
			}
	}
	printf("\n");
	return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define N 100000
typedef long long ll;

int n,h,m,k;
vector<int> nh,nm;
map<int,vector<int>> mp;

int main(){
	scanf("%d%d%d%d",&n,&h,&m,&k);
	nh=vector<int> (n);
	nm=vector<int> (n);
	for(int i=0;i<n;i++){
		scanf("%d%d",&nh[i],&nm[i]);
		mp[nm[i]%(m/2)].push_back(i+1);
	}
	if(n==1) {printf("0 0\n\n");return 0;}

	int ans=INT_MAX;
	int all=0;
	int st=0;
	auto it2=mp.begin();
	bool flag=false;
	for(auto it=mp.begin();it!=mp.end();it++){
		cout<<"here "<<it->first<<" "<<it2->first<<endl;
		if(it2!=it) all-=it->second.size();
		int end=it->first+k-1;
		if(end>m/2){
			if(!flag){
				while(it2!=mp.end()){
					all+=it2->second.size();
					it2++;
				}
				it2=mp.begin();
			}
		}
		while(it2!=mp.end()&&it2->first>it->first&&it2->first<=end||end>(m/2)&&it2->first<=end%(m/2)){
			all+=it2->second.size();
			it2++;
		}
		if(all<ans) {ans=all;st=it->first;}
	}
	printf("%d %d\n",ans,(st+k)%(m/2));
	for(auto it=mp.begin();it!=mp.end();it++){
		int he=it->first;
		int end=st+k-1;
		if(he>st&&he<=end||end>m/2&&he<=end)
			for(int j=0;j<it->second.size();j++){
				printf("%d ",it->second[j]);
			}
	}
	printf("\n");
	return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
#define N 100000

int n,h,m,k;
vector<int> nh,nm;

int main(){
	scanf("%d%d%d%d",&n,&h,&m,&k);
	nh=vector<int>(n);
	nm=vector<int>(n);
	for(int i=0;i<n;i++){
		scanf("%d",nh[i],nm[i]);
	}
	map<int,vector<int>> mp;
	for(int i=0;i<n;i++){
		mp[nm[i]%(m/2)].push_back(i+1);
	}
	if(k==1) {printf("0 0\n");printf("\n");return 0;}
	int mi=INT_MAX;
	int st=0;
	int all=0;
	auto it2=mp.begin();
	bool f=false;
	for(auto it=mp.begin();it!=mp.end();it++){
		int end=it->first+k-2;
		if(end>=m/2){
			if(!f) {
				f=true;
				while(it2!=mp.end()){
					all+=it2->second.size();
					it2++;
				}
				it2=mp.begin();
			}
			end=end%(m/2);
		}
		while(it2!=mp.end()&&it2->first<=end){
			all+=it2->second.size();
			it2++;
		}
		if(all<mi) {mi=all;st=it->first;}
		all-=it->second.size();
	}
	printf("%d %d\n",mi,st+k-1);
	/*
	for(auto it=mp.begin();it!=mp.end();it++){
		int end=st+k-2;
		if(it->first>=st&&it->first<=end||end>=m/2&&it->first<=end%(m/2)){
			for(int j=0;j<it->second.size();j++){
				printf("%d ",it->second[j]);
			}
		}
	}
	*/
	printf("\n");

	return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
#define N 100000

int n,h,m,k;
vector<int> nh,nm;

int main(){
	scanf("%d%d%d%d",&n,&h,&m,&k);
	nh=vector<int>(n);
	nm=vector<int>(n);
	for(int i=0;i<n;i++){
		scanf("%d",nh[i],nm[i]);
	}
	map<int,vector<int>> mp;
	for(int i=0;i<n;i++){
		mp[nm[i]%(m/2)].push_back(i+1);
	}
	if(k==1) {printf("0 0\n");printf(" ");}
	int mi=INT;
	int st=0;
	all=0;
	auto it2=mp.begin();
	bool f=false;
	for(auto it=mp.begin();it!=mp.end();it++){
		int end=it->first+k-2;
		if(end>m/2){
			if(!f) {
				f=true;
				while(it2!=mp.end()){
					all+=it2->second.size();
				}
				it2=mp.begin();
			}
			end=end%(m/2);
		}
		while(it2->first<=end){
			all+=it2->second.size();
			it2++;
		}
		if(all<mi) {mi=all;st=it->first;}
		all-=it->second.size();
	}
	printf("%d %d\n",mi,st+k-1);
	for(auto it=mp.begin();it!=mp.end();it++){
		int end=st+k-2;
		if((it->first>=st&&it->first<=end||end>m/2&&it->first<=end%(m/2)){
			for(int j=0;j<it->second.size();j++){
				printf("%d ",it->second[j]);
			}
		}
	}
	printf("\n");

	return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define N 100000
typedef long long ll;

int n,h,m,k;
vector<int> nh,nm;
map<int,vector<int>> mp;

int main(){
	scanf("%d%d%d%d",&n,&h,&m,&k);
	nh=vector<int> (n);
	nm=vector<int> (n);
	for(int i=0;i<n;i++){
		scanf("%d%d",&nh[i],&nm[i]);
		mp[nm[i]%(m/2)].push_back(i+1);
	}
	if(n==1) {printf("0 0\n\n");return 0;}

	int ans=INT_MAX;
	int all=0;
	int st=0;
	auto it2=mp.begin();
	bool flag=false;
	for(auto it=mp.begin();it!=mp.end();it++){
		//cout<<"here "<<it->first<<" "<<it2->first<<endl;
		if(it2==it&&!flag) { it2++;}
		else { all-=it->second.size();}

		int end=it->first+k-1;
		if(end>=m/2){
			if(!flag){
				flag=true;
				while(it2!=mp.end()){
					all+=it2->second.size();
					it2++;
				}
				it2=mp.begin();
			}
		}
		if(it2==mp.end()) { flag=true;it2=mp.begin();}
		while(it2!=mp.end()&&(it2->first>it->first&&it2->first<=end||end>=(m/2)&&it2->first<=end%(m/2))){
			all+=it2->second.size();
			it2++;
		}

		if(all<ans) {ans=all;st=it->first;}
	}
	printf("%d %d\n",ans,(st+k)%(m/2));
	for(auto it=mp.begin();it!=mp.end();it++){
		int he=it->first;
		int end=st+k-1;
		if(he>st&&he<=end||end>=m/2&&he<=end%(m/2))
			for(int j=0;j<it->second.size();j++){
				printf("%d ",it->second[j]);
			}
	}
	printf("\n");
	return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
#define N 100000

int n,h,m,k;
vector<int> nh,nm;

int main(){
	scanf("%d%d%d%d",&n,&h,&m,&k);
	nn=vector<int>(n);
	for(int i=0;i<n;i++){
		scanf("%d",nh[i],nm[i]);
	}
	map<int,vector<int>> mp;
	for(int i=0;i<n;i++){
		mp[nm[i]%(m/2)].push_back(i+1);
	}
	if(k==1) {printf("0 0\n");printf(" ");}
	int mi=INT;
	int st=0;
	all=0;
	auto it2=mp.begin();
	bool f=false;
	for(auto it=mp.begin();it!=mp.end();it++){
		int end=it->first+k-2;
		if(end>m/2){
			if(!f) {
				f=true;
				while(it2!=mp.end()){
					all+=it2->second.size();
				}
				it2=mp.begin();
			}
			end=end%(m/2);
		}
		while(it2->first<=end){
			all+=it2->second.size();
			it2++;
		}
		if(all<mi) {mi=all;st=it->first;}
		all-=it->second.size();
	}
	printf("%d %d\n",mi,st+k-1);
	for(auto it=mp.begin();it!=mp.end();it++){
		int end=st+k-2;
		if((it->first>=st&&it->first<=end||end>m/2&&it->first<=end%(m/2)){
			for(int j=0;j<it->second.size();j++){
				printf("%d ",it->second[j]);
			}
		}
	}
	printf("\n");

	return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define N 100000
typedef long long ll;

int n,h,m,k;
vector<int> nh,nm;
map<int,vector<int>> mp;

int main(){
	scanf("%d%d%d%d",&n,&h,&m,&k);
	nh=vector<int> (n);
	nm=vector<int> (n);
	for(int i=0;i<n;i++){
		scanf("%d%d",&nh[i],&nm[i]);
		mp[nm[i]%(m/2)].push_back(i+1);
	}
	if(n==1) {printf("0 0\n\n");return 0;}

	int ans=INT_MAX;
	int all=0;
	int st=0;
	auto it2=mp.begin();
	bool flag=false;
	for(auto it=mp.begin();it!=mp.end();it++){
		//cout<<"here "<<it->first<<" "<<it2->first<<endl;
		if(it2==it) { it2++;}
		else { all-=it->second.size();}

		int end=it->first+k-1;
		if(end>m/2){
			if(!flag){
				flag=true;
				while(it2!=mp.end()){
					all+=it2->second.size();
					it2++;
				}
				it2=mp.begin();
			}
		}
		if(it2==mp.end()) { flag=true;it2=mp.begin();}
		while(it2!=mp.end()&&(it2->first>it->first&&it2->first<=end||end>(m/2)&&it2->first<=end%(m/2))){
			all+=it2->second.size();
			it2++;
		}

		if(all<ans) {ans=all;st=it->first;}
	}
	printf("%d %d\n",ans,(st+k)%(m/2));
	for(auto it=mp.begin();it!=mp.end();it++){
		int he=it->first;
		int end=st+k-1;
		if(he>st&&he<=end||end>m/2&&he<=end)
			for(int j=0;j<it->second.size();j++){
				printf("%d ",it->second[j]);
			}
	}
	printf("\n");
	return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define N 100000
typedef long long ll;

int n,h,m,k;
vector<int> nh,nm;
map<int,vector<int>> mp;

int main(){
	scanf("%d%d%d%d",&n,&,h,&m,&k);
	nh=vector<int> (n);
	nm=vector<int> (n);
	for(int i=0;i<n;i++){
		scanf("%d%d",&nh[i],&nm[i]);
		mp[nm[i]%(m/2)].push_back(i+1);
	}
	if(n==1) {printf("0 0\n\n");return 0;}

	int ans=INT_MAX;
	int all=0;
	int st=0;
	auto it2=mp.begin();
	bool flag=false;
	for(auto it=mp.begin();it!=mp.end();it++){
		if(it2!=it) all-=it->second.size();
		int end=it->first+k-1;
		if(end>m/2){
			if(!flag){
				while(it2!=mp.end()){
					all+=it2.second.size();
					it2++;
				}
				it2=mp.begin();
			}
		}
		while(it2!=mp.end()&&it2->first>it->first&&it2->first<=end||end>(m/2)&&it2->first<=end%(m/2)){
			all+=it2.second.size();
			it2++;
		}
		if(all<ans) {ans=all;st=it->first;}
	}
	printf("%d %d\n",ans,(st+k)%(m/2));
	for(auto it=mp.begin();it!=mp.end();it++){
		int he=it->first;
		int end=st+k-1;
		if(he>st&&he<=end||end>m/2&&he<=end)
			for(int j=0;j<it->second.size();j++){
				printf("%d ",it->second[j]);
			}
	}
	printf("\n");
	return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define N 100000
typedef long long ll;

int n,h,m,k;
vector<int> nh,nm;
map<int,vector<int>> mp;

int main(){
	scanf("%d%d%d%d",&n,&h,&m,&k);
	nh=vector<int> (n);
	nm=vector<int> (n);
	for(int i=0;i<n;i++){
		scanf("%d%d",&nh[i],&nm[i]);
		mp[nm[i]%(m/2)].push_back(i+1);
	}
	if(n==1) {printf("0 0\n\n");return 0;}

	int ans=INT_MAX;
	int all=0;
	int st=0;
	auto it2=mp.begin();
	bool flag=false;
	for(auto it=mp.begin();it!=mp.end();it++){
		//cout<<"here "<<it->first<<" "<<it2->first<<endl;
		if(it2!=it) all-=it->second.size();
		else it2++;
		int end=it->first+k-1;
		if(end>m/2){
			if(!flag){
				while(it2!=mp.end()){
					all+=it2->second.size();
					it2++;
				}
				it2=mp.begin();
			}
		}
		while(it2!=mp.end()&&it2->first>it->first&&it2->first<=end||end>(m/2)&&it2->first<=end%(m/2)){
			all+=it2->second.size();
			it2++;
		}

		if(all<ans) {ans=all;st=it->first;}
	}
	printf("%d %d\n",ans,(st+k)%(m/2));
	for(auto it=mp.begin();it!=mp.end();it++){
		int he=it->first;
		int end=st+k-1;
		if(he>st&&he<=end||end>m/2&&he<=end)
			for(int j=0;j<it->second.size();j++){
				printf("%d ",it->second[j]);
			}
	}
	printf("\n");
	return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
#define N 100000

int n,h,m,k;
vector<int> nh,nm;

int main(){
	scanf("%d%d%d%d",&n,&h,&m,&k);
	nh=vector<int>(n);
	nm=vector<int>(n);
	for(int i=0;i<n;i++){
		scanf("%d",nh[i],nm[i]);
	}
	map<int,vector<int>> mp;
	for(int i=0;i<n;i++){
		mp[nm[i]%(m/2)].push_back(i+1);
	}
	if(k==1) {printf("0 0\n");printf(" ");}
	int mi=INT_MAX;
	int st=0;
	int all=0;
	auto it2=mp.begin();
	bool f=false;
	for(auto it=mp.begin();it!=mp.end();it++){
		int end=it->first+k-2;
		if(end>m/2){
			if(!f) {
				f=true;
				while(it2!=mp.end()){
					all+=it2->second.size();
				}
				it2=mp.begin();
			}
			end=end%(m/2);
		}
		while(it2!=mp.end()&&it2->first<=end){
			all+=it2->second.size();
			it2++;
		}
		if(all<mi) {mi=all;st=it->first;}
		all-=it->second.size();
	}
	printf("%d %d\n",mi,st+k-1);
	for(auto it=mp.begin();it!=mp.end();it++){
		int end=st+k-2;
		if(it->first>=st&&it->first<=end||end>m/2&&it->first<=end%(m/2)){
			for(int j=0;j<it->second.size();j++){
				printf("%d ",it->second[j]);
			}
		}
	}
	printf("\n");

	return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define N 100000
typedef long long ll;

int n,h,m,k;
vector<int> nh,nm;
map<int,vector<int>> mp;

int main(){
	scanf("%d%d%d%d",&n,&h,&m,&k);
	nh=vector<int> (n);
	nm=vector<int> (n);
	for(int i=0;i<n;i++){
		scanf("%d%d",&nh[i],&nm[i]);
		mp[nm[i]%(m/2)].push_back(i+1);
	}
	if(n==1) {printf("0 0\n\n");return 0;}

	int ans=INT_MAX;
	int all=0;
	int st=0;
	auto it2=mp.begin();
	bool flag=false;
	for(auto it=mp.begin();it!=mp.end();it++){
		//cout<<"here "<<it->first<<" "<<it2->first<<endl;
		if(it2==it&&!flag) { it2++;}
		else { all-=it->second.size();}

		int end=it->first+k-1;
		if(end>=m/2){
			if(!flag){
				flag=true;
				while(it2!=mp.end()){
					all+=it2->second.size();
					it2++;
				}
				it2=mp.begin();
			}
		}
		//if(it2==mp.end()) { flag=true;it2=mp.begin();}
		while(it2!=mp.end()&&(it2->first>it->first&&it2->first<=end||end>=(m/2)&&it2->first<=end%(m/2))){
			all+=it2->second.size();
			it2++;
		}

		if(all<ans) {ans=all;st=it->first;}
	}
	printf("%d %d\n",ans,(st+k)%(m/2));
	for(auto it=mp.begin();it!=mp.end();it++){
		int he=it->first;
		int end=st+k-1;
		if(he>st&&he<=end||end>=m/2&&he<=end%(m/2))
			for(int j=0;j<it->second.size();j++){
				printf("%d ",it->second[j]);
			}
	}
	printf("\n");
	return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define N 100000
typedef long long ll;

int n,h,m,k;
vector<int> nh,nm;
map<int,vector<int>> mp;

int main(){
	scanf("%d%d%d%d",&n,&h,&m,&k);
	nh=vector<int> (n);
	nm=vector<int> (n);
	for(int i=0;i<n;i++){
		scanf("%d%d",&nh[i],&nm[i]);
		mp[nm[i]%(m/2)].push_back(i+1);
	}
	if(n==1) {printf("0 0\n\n");return 0;}

	int ans=INT_MAX;
	int all=0;
	int st=0;
	auto it2=mp.begin();
	bool flag=false;
	for(auto it=mp.begin();it!=mp.end();it++){
		cout<<"here "<<it->first<<" "<<it2->first<<endl;
		if(it2!=it) all-=it->second.size();
		else it2++;
		int end=it->first+k-1;
		if(end>m/2){
			if(!flag){
				while(it2!=mp.end()){
					all+=it2->second.size();
					it2++;
				}
				it2=mp.begin();
			}
		}
		while(it2!=mp.end()&&it2->first>it->first&&it2->first<=end||end>(m/2)&&it2->first<=end%(m/2)){
			all+=it2->second.size();
			it2++;
		}

		if(all<ans) {ans=all;st=it->first;}
	}
	printf("%d %d\n",ans,(st+k)%(m/2));
	for(auto it=mp.begin();it!=mp.end();it++){
		int he=it->first;
		int end=st+k-1;
		if(he>st&&he<=end||end>m/2&&he<=end)
			for(int j=0;j<it->second.size();j++){
				printf("%d ",it->second[j]);
			}
	}
	printf("\n");
	return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define N 100000
typedef long long ll;

int n,h,m,k;
vector<int> nh,nm;
map<int,vector<int>> mp;

int main(){
	scanf("%d%d%d%d",&n,&h,&m,&k);
	nh=vector<int> (n);
	nm=vector<int> (n);
	for(int i=0;i<n;i++){
		scanf("%d%d",&nh[i],&nm[i]);
		mp[nm[i]%(m/2)].push_back(i+1);
	}
	if(n==1) {printf("0 0\n\n");return 0;}

	int ans=INT_MAX;
	int all=0;
	int st=0;
	auto it2=mp.begin();
	bool flag=false;
	for(auto it=mp.begin();it!=mp.end();it++){
		if(it2!=it) all-=it->second.size();
		int end=it->first+k-1;
		if(end>m/2){
			if(!flag){
				while(it2!=mp.end()){
					all+=it2->second.size();
					it2++;
				}
				it2=mp.begin();
			}
		}
		while(it2!=mp.end()&&it2->first>it->first&&it2->first<=end||end>(m/2)&&it2->first<=end%(m/2)){
			all+=it2->second.size();
			it2++;
		}
		if(all<ans) {ans=all;st=it->first;}
	}
	printf("%d %d\n",ans,(st+k)%(m/2));
	for(auto it=mp.begin();it!=mp.end();it++){
		int he=it->first;
		int end=st+k-1;
		if(he>st&&he<=end||end>m/2&&he<=end)
			for(int j=0;j<it->second.size();j++){
				printf("%d ",it->second[j]);
			}
	}
	printf("\n");
	return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define N 100000
typedef long long ll;

int n,h,m,k;
vector<int> nh,nm;
map<int,vector<int>> mp;

int main(){
	scanf("%d%d%d%d",&n,&h,&m,&k);
	nh=vector<int> (n);
	nm=vector<int> (n);
	for(int i=0;i<n;i++){
		scanf("%d%d",&nh[i],&nm[i]);
		mp[nm[i]%(m/2)].push_back(i+1);
	}
	if(n==1) {printf("0 0\n\n");return 0;}

	int ans=INT_MAX;
	int all=0;
	int st=0;
	auto it2=mp.begin();
	bool flag=false;
	for(auto it=mp.begin();it!=mp.end();it++){
		//cout<<"here "<<it->first<<" "<<it2->first<<endl;
		if(it2!=it) all-=it->second.size();
		else if(it==mp.end()) it2=mp.begin();
		else it2++;
		int end=it->first+k-1;
		if(end>m/2){
			if(!flag){
				while(it2!=mp.end()){
					all+=it2->second.size();
					it2++;
				}
				it2=mp.begin();
			}
		}
		while(it2!=mp.end()&&it2->first>it->first&&it2->first<=end||end>(m/2)&&it2->first<=end%(m/2)){
			all+=it2->second.size();
			it2++;
		}

		if(all<ans) {ans=all;st=it->first;}
	}
	printf("%d %d\n",ans,(st+k)%(m/2));
	for(auto it=mp.begin();it!=mp.end();it++){
		int he=it->first;
		int end=st+k-1;
		if(he>st&&he<=end||end>m/2&&he<=end)
			for(int j=0;j<it->second.size();j++){
				printf("%d ",it->second[j]);
			}
	}
	printf("\n");
	return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define N 100000
typedef long long ll;

int n,h,m,k;
vector<int> nh,nm;
map<int,vector<int>> mp;

int main(){
	scanf("%d%d%d%d",&n,&h,&m,&k);
	nh=vector<int> (n);
	nm=vector<int> (n);
	for(int i=0;i<n;i++){
		scanf("%d%d",&nh[i],&nm[i]);
		mp[nm[i]%(m/2)].push_back(i+1);
	}
	if(n==1) {printf("0 0\n\n");return 0;}

	int ans=INT_MAX;
	int all=0;
	int st=0;
	auto it2=mp.begin();
	bool flag=false;
	for(auto it=mp.begin();it!=mp.end();it++){
		//cout<<"here "<<it->first<<" "<<it2->first<<endl;
		if(it2==it) { it2++;}
		else { all-=it->second.size();}
		if(it2==mp.end()) it2=mp.begin();
		int end=it->first+k-1;
		if(end>m/2){
			if(!flag){
				while(it2!=mp.end()){
					all+=it2->second.size();
					it2++;
				}
				it2=mp.begin();
			}
		}
		while(it2!=mp.end()&&it2->first>it->first&&it2->first<=end||end>(m/2)&&it2->first<=end%(m/2)){
			all+=it2->second.size();
			it2++;
		}

		if(all<ans) {ans=all;st=it->first;}
	}
	printf("%d %d\n",ans,(st+k)%(m/2));
	for(auto it=mp.begin();it!=mp.end();it++){
		int he=it->first;
		int end=st+k-1;
		if(he>st&&he<=end||end>m/2&&he<=end)
			for(int j=0;j<it->second.size();j++){
				printf("%d ",it->second[j]);
			}
	}
	printf("\n");
	return 0;
}