#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 1e2;

queue<int> qs[maxn];
int n, qcnt;

class Graph {
private:
    int s[maxn], t[maxn << 1], nxt[maxn << 1], dfn[maxn], low[maxn], bel[maxn], deg[maxn], dd, cnt, bcnt;
    bool ins[maxn];
    stack<int> stk;
    queue<int> bs[maxn];

    inline void dfs(int pos) {
        stk.push(pos), ins[pos] = 1, low[pos] = dfn[pos] = ++dd;
        for(int at = s[pos]; at; at = nxt[at]) {
            if(!dfn[t[at]]) dfs(t[at]), low[pos] = min(low[pos], low[t[at]]);
            else if(ins[t[at]]) low[pos] = min(low[pos], dfn[t[at]]);
        }
        if(low[pos] == dfn[pos]) {
            ++bcnt;
            do bs[bel[stk.top()] = bcnt].push(stk.top()), ins[stk.top()] = 0, stk.pop(); while(ins[pos]);
        }
    }
public:
    inline void addedge(int from, int to) {
        t[++cnt] = to, nxt[cnt] = s[from], s[from] = cnt;
    }
    inline void tarjan() {
        for(int i = 1; i <= n; i++) if(!dfn[i]) dfs(i);
        for(int pos = 1; pos <= n; pos++) for(int at = s[pos]; at; at = nxt[at]) if(bel[pos] != bel[t[at]]) ++deg[bel[t[at]]];
        for(int i = 1; i <= bcnt; i++) if(!deg[i]) qs[++qcnt] = bs[i];
    }
}gra;

inline bool ask(int x, int y) {
    printf("? %d %d\n", x, y), fflush(stdout);
    int ret; scanf("%d", &ret);
    if(!~ret) exit(0);
    return ret;
}
inline pair<int, queue<int>* > merge(int rt, queue<int>* bel, queue<int>* oth) {
    while(oth->size()) {
        int tp = oth->front(); oth->pop();
        int p = ask(rt, tp);
        if(p == 0) swap(rt, tp), swap(bel, oth);
    }
    return make_pair(rt, bel);
}

int main() {
    static int m;
    scanf("%d%d", &n, &m);
    for(int i = 1, u, v; i <= m; i++) scanf("%d%d", &u, &v), gra.addedge(u, v);
    gra.tarjan();
    pair<int, queue<int>* > cur = make_pair(qs[1].front(), qs + 1); qs[1].pop();
    for(int i = 2; i <= qcnt; i++) cur = merge(cur.first, cur.second, qs + i);
    printf("%d\n", cur.first);
    return 0;
}


import java.util.*;
import java.io.*;
public class Main {
	static int n,m,comp,tot,cnt;
	static int[] dfn=new int[112345];
	static int[] low=new int[112345];
	static int[] stk=new int[112345];
	static int[] cmp=new int[112345];
	static int[] u=new int[112345];
	static int[] v=new int[112345];
	static int[] deg=new int[112345];
	static int[] id=new int[112345];
	static ArrayList<Integer>[] G=new ArrayList[112345];
	static void dfs(int u) {
		dfn[u]=low[u]=++cnt;
		stk[++tot]=u;
		for (int i=0;i<G[u].size();++i) {
			int v=G[u].get(i);
			if (dfn[v]>0) low[u]=Math.min(low[u],dfn[v]);
			else {
				dfs(v);
				low[u]=Math.min(low[u],low[v]);
			}
		}
		if (low[u]==dfn[u]) {
			++comp;
			while (true) {
				cmp[stk[tot--]]=comp;
				if (stk[tot+1]==u) break;
			}
			id[comp]=u;
		}
	}
	public static void main(String[] args) throws IOException {
		BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out=new PrintWriter(System.out);
		StringTokenizer sa=new StringTokenizer(in.readLine());
		n=Integer.parseInt(sa.nextToken());
		m=Integer.parseInt(sa.nextToken());
		for (int i=1;i<=n;++i) G[i]=new ArrayList<Integer>();
		for (int i=0;i<m;++i) {
			sa=new StringTokenizer(in.readLine());
			u[i]=Integer.parseInt(sa.nextToken());
			v[i]=Integer.parseInt(sa.nextToken());
			G[u[i]].add(v[i]);
		}
		for (int i=1;i<=n;++i) if (dfn[i]==0) dfs(i);
		for (int i=1;i<=n;++i) G[i]=new ArrayList<Integer>();
		for (int i=0;i<m;++i)
			if (cmp[u[i]]!=cmp[v[i]]) {
				G[cmp[u[i]]].add(cmp[v[i]]);
				++deg[cmp[v[i]]];
			}
		Queue<Integer> q=new LinkedList<Integer>();
		for (int i=1;i<=comp;++i) if (deg[i]==0)
			q.add(i);
		int top=q.poll();
		while (!q.isEmpty()) {
			int u=q.poll();
			out.printf("? %d %d\n",id[top],id[u]);
			out.flush();
			sa=new StringTokenizer(in.readLine());
			int x=Integer.parseInt(sa.nextToken());
			if (x==0) {
				int tmp=u;
				u=top;
				top=tmp;
			}
			for (int i=0;i<G[u].size();++i) {
				int v=G[u].get(i);
				if (--deg[v]==0) q.add(v);
			}
		}
		out.println("! "+id[top]);
		out.flush();
	}
}


import java.util.*;
import java.io.*;
public class Main {
	static boolean[] vis=new boolean[112345];
	static int[] deg=new int[112345];
	static ArrayList<Integer>[] G=new ArrayList[112345];
	static ArrayList<Integer>[] tree=new ArrayList[112345];
	static void dfs(int u) {
		vis[u]=true;
		for (int i=0;i<G[u].size();++i) {
			int v=G[u].get(i);
			if (vis[v]) continue;
			dfs(v);
			++deg[v];
			tree[u].add(v);
		}
	}
	public static void main(String[] args) throws IOException {
		BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out=new PrintWriter(System.out);
		StringTokenizer sa=new StringTokenizer(in.readLine());
		int n=Integer.parseInt(sa.nextToken());
		int m=Integer.parseInt(sa.nextToken());
		for (int i=1;i<=n;++i) {
			G[i]=new ArrayList<Integer>();
			tree[i]=new ArrayList<Integer>();
		}
		while (m-->0) {
			sa=new StringTokenizer(in.readLine());
			int u=Integer.parseInt(sa.nextToken());
			int v=Integer.parseInt(sa.nextToken());
			G[u].add(v);
		}
		for (int i=1;i<=n;++i) if (!vis[i])
			dfs(i);
		Queue<Integer> que=new LinkedList<Integer>();
		for (int i=1;i<=n;++i) if (deg[i]==0)
			que.add(i);
		int u=que.poll();
		while (!que.isEmpty()) {
			int v=que.poll();
			out.printf("? %d %d\n",u,v);
			out.flush();
			int x=Integer.parseInt(in.readLine());
			if (x==0) {int o=u;u=v;v=o;}
			for (int i=0;i<tree[v].size();++i) {
				int o=tree[v].get(i);
				if (--deg[o]==0) que.add(o);
			}
		}
		out.printf("! %d\n",u);
		out.close();
	}
}


import java.util.*;
import java.io.*;
public class Main {
	static int n,m,comp,tot,cnt;
	static int[] dfn=new int[112345];
	static int[] low=new int[112345];
	static int[] stk=new int[112345];
	static int[] cmp=new int[112345];
	static int[] u=new int[112345];
	static int[] v=new int[112345];
	static int[] deg=new int[112345];
	static int[] ptr=new int[112345];
	static int[] vis=new int[112345];
	static ArrayList<Integer>[] arr=new ArrayList[112345];
	static ArrayList<Integer>[] G=new ArrayList[112345];
	static void dfs(int u) {
		dfn[u]=low[u]=++cnt;
		stk[++tot]=u;
		vis[u]=1;
		for (int i=0;i<G[u].size();++i) {
			int v=G[u].get(i);
			if (vis[v]>0) low[u]=Math.min(low[u],low[v]);
			else if (dfn[v]==0) {
				dfs(v);
				low[u]=Math.min(low[u],low[v]);
			}
		}
		if (low[u]==dfn[u]) {
			++comp;
			while (true) {
				cmp[stk[tot]]=comp;
				arr[comp].add(stk[tot]);
				vis[stk[tot]]=0;
				if (stk[tot--]==u) break;
			}
		}
		//System.out.printf("low[%d]=%d dfn[%d]=%d\n",u,low[u],u,dfn[u]);
	}
	public static void main(String[] args) throws IOException {
		BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out=new PrintWriter(System.out);
		StringTokenizer sa=new StringTokenizer(in.readLine());
		n=Integer.parseInt(sa.nextToken());
		m=Integer.parseInt(sa.nextToken());
		for (int i=1;i<=n;++i) {
			G[i]=new ArrayList<Integer>();
			arr[i]=new ArrayList<Integer>();
		}
		for (int i=0;i<m;++i) {
			sa=new StringTokenizer(in.readLine());
			u[i]=Integer.parseInt(sa.nextToken());
			v[i]=Integer.parseInt(sa.nextToken());
			G[u[i]].add(v[i]);
		}
		for (int i=1;i<=n;++i) if (dfn[i]==0) dfs(i);
		for (int i=1;i<=n;++i) G[i]=new ArrayList<Integer>();
		for (int i=0;i<m;++i)
			if (cmp[u[i]]!=cmp[v[i]]) {
				//System.out.printf("u=%d v=%d cmpu=%d cmpv=%d\n",u[i],v[i],cmp[u[i]],cmp[v[i]]);
				G[cmp[u[i]]].add(cmp[v[i]]);
				++deg[cmp[v[i]]];
			}
		Queue<Integer> q=new LinkedList<Integer>();
		for (int i=1;i<=n;++i) if (deg[i]==0)
			q.add(i);
		int u=q.poll();
		while (q.size()>0) {
			int v=q.poll();
			out.printf("? %d %d\n",arr[u].get(ptr[u]),arr[v].get(ptr[v]));
			out.flush();
			int x=Integer.parseInt(in.readLine());
			if (x==0) {int k=u;u=v;v=k;}
			++ptr[v];
			if (ptr[v]==arr[v].size()) for (int i=0;i<G[v].size();++i) {
				int o=G[v].get(i);
				if (--deg[o]==0) q.add(o);
			} else q.add(v);
		}
		out.println("! "+arr[u].get(ptr[u]));
		out.flush();
	}
}


import java.util.*;
import java.io.*;
public class Main {
	static int n,m,comp,tot,cnt;
	static int[] dfn=new int[112345];
	static int[] low=new int[112345];
	static int[] stk=new int[112345];
	static int[] cmp=new int[112345];
	static int[] u=new int[112345];
	static int[] v=new int[112345];
	static int[] deg=new int[112345];
	static int[] id=new int[112345];
	static int[] vis=new int[112345];
	static ArrayList<Integer>[] G=new ArrayList[112345];
	static void dfs(int u) {
		//System.out.printf("u=%d\n",u);
		dfn[u]=low[u]=++cnt;
		stk[++tot]=u;
		vis[u]=1;
		for (int i=0;i<G[u].size();++i) {
			int v=G[u].get(i);
			if (vis[v]>0) low[u]=Math.min(low[u],low[v]);
			else if (dfn[v]==0) {
				dfs(v);
				low[u]=Math.min(low[u],low[v]);
			}
		}
		if (low[u]==dfn[u]) {
			++comp;
			while (true) {
				vis[stk[tot]]=0;
				cmp[stk[tot]]=comp;
				if (stk[tot--]==u) break;
			}
			id[comp]=u;
		}
	}
	public static void main(String[] args) throws IOException {
		BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out=new PrintWriter(System.out);
		StringTokenizer sa=new StringTokenizer(in.readLine());
		n=Integer.parseInt(sa.nextToken());
		m=Integer.parseInt(sa.nextToken());
		for (int i=1;i<=n;++i) G[i]=new ArrayList<Integer>();
		for (int i=0;i<m;++i) {
			sa=new StringTokenizer(in.readLine());
			u[i]=Integer.parseInt(sa.nextToken());
			v[i]=Integer.parseInt(sa.nextToken());
			G[u[i]].add(v[i]);
		}
		for (int i=1;i<=n;++i) if (dfn[i]==0) dfs(i);
		//for (int i=1;i<=n;++i)
		//	System.out.printf("i=%d cmp=%d dfn=%d low=%d\n",i,cmp[i],dfn[i],low[i]);
		for (int i=1;i<=n;++i) G[i]=new ArrayList<Integer>();
		for (int i=0;i<m;++i)
			if (cmp[u[i]]!=cmp[v[i]]) {
				G[cmp[u[i]]].add(cmp[v[i]]);
				++deg[cmp[v[i]]];
			}
		Queue<Integer> q=new LinkedList<Integer>();
		for (int i=1;i<=comp;++i) if (deg[i]==0)
			q.add(id[i]);
		int top=q.poll();
		while (!q.isEmpty()) {
			int u=q.poll();
			out.printf("? %d %d\n",id[top],id[u]);
			out.flush();
			sa=new StringTokenizer(in.readLine());
			int x=Integer.parseInt(sa.nextToken());
			if (x==0) {
				int tmp=u;
				u=top;
				top=tmp;
			}
			for (int i=0;i<G[u].size();++i) {
				int v=G[u].get(i);
				if (--deg[v]==0) q.add(v);
			}
		}
		out.println("! "+id[top]);
		out.flush();
	}
}


import java.util.*;
import java.io.*;
public class Main {
	static int n,m,comp,tot,cnt;
	static int[] dfn=new int[112345];
	static int[] low=new int[112345];
	static int[] stk=new int[112345];
	static int[] cmp=new int[112345];
	static int[] u=new int[112345];
	static int[] v=new int[112345];
	static int[] deg=new int[112345];
	static int[] ptr=new int[112345];
	static int[] vis=new int[112345];
	static ArrayList<Integer>[] arr=new ArrayList[112345];
	static ArrayList<Integer>[] G=new ArrayList[112345];
	static void dfs(int u) {
		dfn[u]=low[u]=++cnt;
		stk[++tot]=u;
		vis[u]=1;
		for (int i=0;i<G[u].size();++i) {
			int v=G[u].get(i);
			if (vis[v]>0) low[u]=Math.min(low[u],low[v]);
			else if (dfn[v]==0) {
				dfs(v);
				low[u]=Math.min(low[u],low[v]);
			}
		}
		if (low[u]==dfn[u]) {
			++comp;
			while (true) {
				cmp[stk[tot]]=comp;
				arr[comp].add(stk[tot]);
				vis[stk[tot]]=0;
				if (stk[tot--]==u) break;
			}
		}
		//System.out.printf("low[%d]=%d dfn[%d]=%d\n",u,low[u],u,dfn[u]);
	}
	public static void main(String[] args) throws IOException {
		BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out=new PrintWriter(System.out);
		StringTokenizer sa=new StringTokenizer(in.readLine());
		n=Integer.parseInt(sa.nextToken());
		m=Integer.parseInt(sa.nextToken());
		for (int i=1;i<=n;++i) {
			G[i]=new ArrayList<Integer>();
			arr[i]=new ArrayList<Integer>();
		}
		for (int i=0;i<m;++i) {
			sa=new StringTokenizer(in.readLine());
			u[i]=Integer.parseInt(sa.nextToken());
			v[i]=Integer.parseInt(sa.nextToken());
			G[u[i]].add(v[i]);
		}
		for (int i=1;i<=n;++i) if (dfn[i]==0) dfs(i);
		for (int i=1;i<=n;++i) G[i]=new ArrayList<Integer>();
		for (int i=0;i<m;++i)
			if (cmp[u[i]]!=cmp[v[i]]) {
				//System.out.printf("u=%d v=%d cmpu=%d cmpv=%d\n",u[i],v[i],cmp[u[i]],cmp[v[i]]);
				G[cmp[u[i]]].add(cmp[v[i]]);
				++deg[cmp[v[i]]];
			}
		Queue<Integer> q=new LinkedList<Integer>();
		for (int i=1;i<=comp;++i) if (deg[i]==0)
			q.add(i);
		int u=q.poll();
		while (q.size()>0) {
			int v=q.peek();
			//System.out.printf("u=%d v=%d\n",u,v);
			out.printf("? %d %d\n",arr[u].get(ptr[u]),arr[v].get(ptr[v]));
			out.flush();
			int x=Integer.parseInt(in.readLine());
			if (x==0) {int k=u;u=v;v=k;}
			++ptr[v];
			if (ptr[v]==arr[v].size()) {
				q.poll();
				for (int i=0;i<G[v].size();++i) {
					int o=G[v].get(i);
					if (--deg[o]==0) q.add(o);
				}
			} else if (x==0) {
				q.poll();
				q.add(v);
			}
			//System.out.println(u);
		}
		out.println("! "+arr[u].get(ptr[u]));
		out.flush();
	}
}


import java.util.*;
import java.io.*;
public class Main {
	static boolean[] vis=new boolean[112345];
	static int[] deg=new int[112345];
	static ArrayList<Integer>[] G=new ArrayList[112345];
	static ArrayList<Integer>[] tree=new ArrayList[112345];
	static void dfs(int u) {
		vis[u]=true;
		for (int i=0;i<G[u].size();++i) {
			int v=G[u].get(i);
			if (vis[v]) continue;
			dfs(v);
			++deg[v];
			tree[u].add(v);
		}
	}
	public static void main(String[] args) throws IOException {
		BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out=new PrintWriter(System.out);
		StringTokenizer sa=new StringTokenizer(in.readLine());
		int n=Integer.parseInt(sa.nextToken());
		int m=Integer.parseInt(sa.nextToken());
		for (int i=1;i<=n;++i) {
			G[i]=new ArrayList<Integer>();
			tree[i]=new ArrayList<Integer>();
		}
		while (m-->0) {
			sa=new StringTokenizer(in.readLine());
			int u=Integer.parseInt(sa.nextToken());
			int v=Integer.parseInt(sa.nextToken());
			G[u].add(v);
		}
		for (int i=1;i<=n;++i) if (!vis[i])
			dfs(i);
		Queue<Integer> que=new LinkedList<Integer>();
		for (int i=1;i<=n;++i) if (deg[i]==0)
			que.add(i);
		while (que.size()>1) {
			int u=que.poll();
			int v=que.poll();
			out.printf("? %d %d\n",u,v);
			out.flush();
			int x=Integer.parseInt(in.readLine());
			if (x==0) {int o=u;u=v;v=o;}
			for (int i=0;i<tree[v].size();++i) {
				int o=tree[v].get(i);
				if (--deg[o]==0) que.add(o);
			}
			que.add(u);
		}
		out.printf("! %d\n",que.poll());
		out.close();
	}
}


import java.util.*;
import java.io.*;
public class Main {
	static int n,m,comp,tot,cnt;
	static int[] dfn=new int[112345];
	static int[] low=new int[112345];
	static int[] stk=new int[112345];
	static int[] cmp=new int[112345];
	static int[] u=new int[112345];
	static int[] v=new int[112345];
	static int[] deg=new int[112345];
	static int[] ptr=new int[112345];
	static int[] vis=new int[112345];
	static ArrayList<Integer>[] arr=new ArrayList[112345];
	static ArrayList<Integer>[] G=new ArrayList[112345];
	static void dfs(int u) {
		dfn[u]=low[u]=++cnt;
		stk[++tot]=u;
		vis[u]=1;
		for (int i=0;i<G[u].size();++i) {
			int v=G[u].get(i);
			if (vis[v]>0) low[u]=Math.min(low[u],low[v]);
			else if (dfn[v]==0) {
				dfs(v);
				low[u]=Math.min(low[u],low[v]);
			}
		}
		if (low[u]==dfn[u]) {
			++comp;
			while (true) {
				cmp[stk[tot]]=comp;
				arr[comp].add(stk[tot]);
				vis[stk[tot]]=0;
				if (stk[tot--]==u) break;
			}
		}
		//System.out.printf("low[%d]=%d dfn[%d]=%d\n",u,low[u],u,dfn[u]);
	}
	public static void main(String[] args) throws IOException {
		BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out=new PrintWriter(System.out);
		StringTokenizer sa=new StringTokenizer(in.readLine());
		n=Integer.parseInt(sa.nextToken());
		m=Integer.parseInt(sa.nextToken());
		for (int i=1;i<=n;++i) {
			G[i]=new ArrayList<Integer>();
			arr[i]=new ArrayList<Integer>();
		}
		for (int i=0;i<m;++i) {
			sa=new StringTokenizer(in.readLine());
			u[i]=Integer.parseInt(sa.nextToken());
			v[i]=Integer.parseInt(sa.nextToken());
			G[u[i]].add(v[i]);
		}
		for (int i=1;i<=n;++i) if (dfn[i]==0) dfs(i);
		for (int i=1;i<=n;++i) G[i]=new ArrayList<Integer>();
		for (int i=0;i<m;++i)
			if (cmp[u[i]]!=cmp[v[i]]) {
				//System.out.printf("u=%d v=%d cmpu=%d cmpv=%d\n",u[i],v[i],cmp[u[i]],cmp[v[i]]);
				G[cmp[u[i]]].add(cmp[v[i]]);
				++deg[cmp[v[i]]];
			}
		Queue<Integer> q=new LinkedList<Integer>();
		for (int i=1;i<=n;++i) if (deg[i]==0)
			q.add(i);
		int u=q.poll();
		while (q.size()>0) {
			int v=q.poll();
			out.printf("? %d %d\n",arr[u].get(ptr[u]),arr[v].get(ptr[v]));
			out.flush();
			int x=Integer.parseInt(in.readLine());
			if (x==0) {int k=u;u=v;v=k;}
			++ptr[v];
			if (ptr[v]==arr[v].size()) for (int i=0;i<G[v].size();++i) {
				int o=G[v].get(i);
				if (--deg[o]==0) q.add(o);
			}
		}
		out.println("! "+arr[u].get(ptr[u]));
		out.flush();
	}
}


import java.util.*;
import java.io.*;
public class Main {
	static int n,m,comp,tot,cnt;
	static int[] dfn=new int[112345];
	static int[] low=new int[112345];
	static int[] stk=new int[112345];
	static int[] cmp=new int[112345];
	static int[] u=new int[112345];
	static int[] v=new int[112345];
	static int[] deg=new int[112345];
	static int[] ptr=new int[112345];
	static int[] vis=new int[112345];
	static ArrayList<Integer>[] arr=new ArrayList[112345];
	static ArrayList<Integer>[] G=new ArrayList[112345];
	static void dfs(int u) {
		dfn[u]=low[u]=++cnt;
		stk[++tot]=u;
		vis[u]=1;
		for (int i=0;i<G[u].size();++i) {
			int v=G[u].get(i);
			if (vis[v]>0) low[u]=Math.min(low[u],low[v]);
			else if (dfn[v]==0) {
				dfs(v);
				low[u]=Math.min(low[u],low[v]);
			}
		}
		if (low[u]==dfn[u]) {
			++comp;
			while (true) {
				cmp[stk[tot]]=comp;
				arr[comp].add(stk[tot]);
				vis[stk[tot]]=0;
				if (stk[tot--]==u) break;
			}
		}
		//System.out.printf("low[%d]=%d dfn[%d]=%d\n",u,low[u],u,dfn[u]);
	}
	public static void main(String[] args) throws IOException {
		BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out=new PrintWriter(System.out);
		StringTokenizer sa=new StringTokenizer(in.readLine());
		n=Integer.parseInt(sa.nextToken());
		m=Integer.parseInt(sa.nextToken());
		for (int i=1;i<=n;++i) {
			G[i]=new ArrayList<Integer>();
			arr[i]=new ArrayList<Integer>();
		}
		for (int i=0;i<m;++i) {
			sa=new StringTokenizer(in.readLine());
			u[i]=Integer.parseInt(sa.nextToken());
			v[i]=Integer.parseInt(sa.nextToken());
			G[u[i]].add(v[i]);
		}
		for (int i=1;i<=n;++i) if (dfn[i]==0) dfs(i);
		for (int i=1;i<=n;++i) G[i]=new ArrayList<Integer>();
		for (int i=0;i<m;++i)
			if (cmp[u[i]]!=cmp[v[i]]) {
				//System.out.printf("u=%d v=%d cmpu=%d cmpv=%d\n",u[i],v[i],cmp[u[i]],cmp[v[i]]);
				G[cmp[u[i]]].add(cmp[v[i]]);
				++deg[cmp[v[i]]];
			}
		Queue<Integer> q=new LinkedList<Integer>();
		for (int i=1;i<=n;++i) if (deg[i]==0)
			q.add(i);
		int u=q.poll();
		while (q.size()>0) {
			int v=q.peek();
			out.printf("? %d %d\n",arr[u].get(ptr[u]),arr[v].get(ptr[v]));
			out.flush();
			int x=Integer.parseInt(in.readLine());
			if (x==0) {int k=u;u=v;v=k;}
			++ptr[v];
			if (ptr[v]==arr[v].size()) {
				q.poll();
				for (int i=0;i<G[v].size();++i) {
					int o=G[v].get(i);
					if (--deg[o]==0) q.add(o);
				}
			}
		}
		out.println("! "+arr[u].get(ptr[u]));
		out.flush();
	}
}


import java.util.*;
import java.io.*;
public class Main {
	static int n,m,comp,tot,cnt;
	static int[] dfn=new int[112345];
	static int[] low=new int[112345];
	static int[] stk=new int[112345];
	static int[] cmp=new int[112345];
	static int[] u=new int[112345];
	static int[] v=new int[112345];
	static int[] deg=new int[112345];
	static int[] id=new int[112345];
	static int[] vis=new int[112345];
	static ArrayList<Integer>[] G=new ArrayList[112345];
	static void dfs(int u) {
		//System.out.printf("u=%d\n",u);
		dfn[u]=low[u]=++cnt;
		stk[++tot]=u;
		vis[u]=1;
		for (int i=0;i<G[u].size();++i) {
			int v=G[u].get(i);
			if (vis[v]>0) low[u]=Math.min(low[u],low[v]);
			else if (dfn[v]==0) {
				dfs(v);
				low[u]=Math.min(low[u],low[v]);
			}
		}
		if (low[u]==dfn[u]) {
			++comp;
			while (true) {
				vis[stk[tot]]=0;
				cmp[stk[tot]]=comp;
				if (stk[tot--]==u) break;
			}
			id[comp]=u;
		}
	}
	public static void main(String[] args) throws IOException {
		BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out=new PrintWriter(System.out);
		StringTokenizer sa=new StringTokenizer(in.readLine());
		n=Integer.parseInt(sa.nextToken());
		m=Integer.parseInt(sa.nextToken());
		for (int i=1;i<=n;++i) G[i]=new ArrayList<Integer>();
		for (int i=0;i<m;++i) {
			sa=new StringTokenizer(in.readLine());
			u[i]=Integer.parseInt(sa.nextToken());
			v[i]=Integer.parseInt(sa.nextToken());
			G[u[i]].add(v[i]);
		}
		for (int i=1;i<=n;++i) if (dfn[i]==0) dfs(i);
		//for (int i=1;i<=n;++i)
		//	System.out.printf("i=%d cmp=%d dfn=%d low=%d\n",i,cmp[i],dfn[i],low[i]);
		for (int i=1;i<=n;++i) G[i]=new ArrayList<Integer>();
		for (int i=0;i<m;++i)
			if (cmp[u[i]]!=cmp[v[i]]) {
				G[cmp[u[i]]].add(cmp[v[i]]);
				//System.out.printf("ui=%d vi=%d\n",u[i],v[i]);
				++deg[cmp[v[i]]];
			}
		Queue<Integer> q=new LinkedList<Integer>();
		for (int i=1;i<=comp;++i) if (deg[i]==0)
			q.add(i);
		while (q.size()>1) {
			int u=q.poll();
			int v=q.poll();
			out.printf("? %d %d\n",id[u],id[v]);
			out.flush();
			sa=new StringTokenizer(in.readLine());
			int x=Integer.parseInt(sa.nextToken());
			if (x==1) {
				int tmp=u;
				u=v;
				v=tmp;
			}
			for (int i=0;i<G[u].size();++i) {
				int o=G[u].get(i);
				//System.out.printf("u=%d o=%d dego=%d\n",id[u],id[o],deg[o]);
				--deg[o];
				if (deg[o]==0) {
					q.add(o);
					//System.out.printf("PUSH %d\n",o);
				}
			}
			q.add(v);
		}
		out.println("! "+id[q.poll()]);
		out.flush();
	}
}


import java.util.*;
import java.io.*;
public class Main {
	static int n,m,comp,tot,cnt;
	static int[] dfn=new int[112345];
	static int[] low=new int[112345];
	static int[] stk=new int[112345];
	static int[] cmp=new int[112345];
	static int[] u=new int[112345];
	static int[] v=new int[112345];
	static int[] deg=new int[112345];
	static int[] id=new int[112345];
	static int[] vis=new int[112345];
	static ArrayList<Integer>[] G=new ArrayList[112345];
	static void dfs(int u) {
		//System.out.printf("u=%d\n",u);
		dfn[u]=low[u]=++cnt;
		stk[++tot]=u;
		vis[u]=1;
		for (int i=0;i<G[u].size();++i) {
			int v=G[u].get(i);
			if (vis[v]>0) low[u]=Math.min(low[u],dfn[v]);
			else if (dfn[v]==0) {
				dfs(v);
				low[u]=Math.min(low[u],low[v]);
			}
		}
		if (low[u]==dfn[u]) {
			++comp;
			while (true) {
				vis[stk[tot]]=0;
				cmp[stk[tot--]]=comp;
				if (stk[tot+1]==u) break;
			}
			id[comp]=u;
		}
	}
	public static void main(String[] args) throws IOException {
		BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out=new PrintWriter(System.out);
		StringTokenizer sa=new StringTokenizer(in.readLine());
		n=Integer.parseInt(sa.nextToken());
		m=Integer.parseInt(sa.nextToken());
		for (int i=1;i<=n;++i) G[i]=new ArrayList<Integer>();
		for (int i=0;i<m;++i) {
			sa=new StringTokenizer(in.readLine());
			u[i]=Integer.parseInt(sa.nextToken());
			v[i]=Integer.parseInt(sa.nextToken());
			G[u[i]].add(v[i]);
		}
		for (int i=1;i<=n;++i) if (dfn[i]==0) dfs(i);
		//for (int i=1;i<=n;++i)
		//	System.out.printf("i=%d cmp=%d dfn=%d low=%d\n",i,cmp[i],dfn[i],low[i]);
		for (int i=1;i<=n;++i) G[i]=new ArrayList<Integer>();
		for (int i=0;i<m;++i)
			if (cmp[u[i]]!=cmp[v[i]]) {
				G[cmp[u[i]]].add(cmp[v[i]]);
				++deg[cmp[v[i]]];
			}
		Queue<Integer> q=new LinkedList<Integer>();
		for (int i=1;i<=comp;++i) if (deg[i]==0)
			q.add(i);
		int top=q.poll();
		while (!q.isEmpty()) {
			int u=q.poll();
			out.printf("? %d %d\n",id[top],id[u]);
			out.flush();
			sa=new StringTokenizer(in.readLine());
			int x=Integer.parseInt(sa.nextToken());
			if (x==0) {
				int tmp=u;
				u=top;
				top=tmp;
			}
			for (int i=0;i<G[u].size();++i) {
				int v=G[u].get(i);
				if (--deg[v]==0) q.add(v);
			}
		}
		out.println("! "+id[top]);
		out.flush();
	}
}


import java.util.*;
import java.io.*;
public class Main {
	static int n,m,comp,tot,cnt;
	static int[] dfn=new int[112345];
	static int[] low=new int[112345];
	static int[] stk=new int[112345];
	static int[] cmp=new int[112345];
	static int[] u=new int[112345];
	static int[] v=new int[112345];
	static int[] deg=new int[112345];
	static ArrayList<Integer>[] G=new ArrayList[112345];
	static void dfs(int u) {
		dfn[u]=low[u]=++cnt;
		stk[++tot]=u;
		for (int i=0;i<G[u].size();++i) {
			int v=G[u].get(i);
			if (dfn[v]>0) low[u]=Math.min(low[u],dfn[v]);
			else {
				dfs(v);
				low[u]=Math.min(low[u],low[v]);
			}
		}
		if (low[u]==dfn[u]) {
			++comp;
			while (true) {
				cmp[stk[tot--]]=comp;
				if (stk[tot+1]==u) break;
			}
		}
	}
	public static void main(String[] args) throws IOException {
		BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out=new PrintWriter(System.out);
		StringTokenizer sa=new StringTokenizer(in.readLine());
		n=Integer.parseInt(sa.nextToken());
		m=Integer.parseInt(sa.nextToken());
		for (int i=1;i<=n;++i) G[i]=new ArrayList<Integer>();
		for (int i=0;i<m;++i) {
			sa=new StringTokenizer(in.readLine());
			u[i]=Integer.parseInt(sa.nextToken());
			v[i]=Integer.parseInt(sa.nextToken());
			G[u[i]].add(v[i]);
		}
		for (int i=1;i<=n;++i) if (dfn[i]==0) dfs(i);
		for (int i=1;i<=n;++i) G[i]=new ArrayList<Integer>();
		for (int i=0;i<m;++i)
			if (cmp[u[i]]!=cmp[v[i]]) {
				G[cmp[u[i]]].add(cmp[v[i]]);
				++deg[cmp[v[i]]];
			}
		Queue<Integer> q=new LinkedList<Integer>();
		for (int i=1;i<=comp;++i) if (deg[i]==0)
			q.add(i);
		int top=q.poll();
		while (!q.isEmpty()) {
			int u=q.poll();
			out.printf("? %d %d\n",top,u);
			out.flush();
			sa=new StringTokenizer(in.readLine());
			int x=Integer.parseInt(sa.nextToken());
			if (x==0) {
				int tmp=u;
				u=top;
				top=tmp;
			}
			for (int i=0;i<G[u].size();++i) {
				int v=G[u].get(i);
				if (--deg[v]==0) q.add(v);
			}
		}
		for (int i=1;i<=n;++i) if (cmp[i]==top) {
			out.println("! "+top);
			out.flush();
			break;
		}
	}
}


import java.util.*;
import java.io.*;
public class Main {
	static int n,m,comp,tot,cnt;
	static int[] dfn=new int[112345];
	static int[] low=new int[112345];
	static int[] stk=new int[112345];
	static int[] cmp=new int[112345];
	static int[] u=new int[112345];
	static int[] v=new int[112345];
	static int[] deg=new int[112345];
	static int[] id=new int[112345];
	static int[] vis=new int[112345];
	static ArrayList<Integer>[] G=new ArrayList[112345];
	static void dfs(int u) {
		//System.out.printf("u=%d\n",u);
		dfn[u]=low[u]=++cnt;
		stk[++tot]=u;
		vis[u]=1;
		for (int i=0;i<G[u].size();++i) {
			int v=G[u].get(i);
			if (vis[v]>0) low[u]=Math.min(low[u],low[v]);
			else if (dfn[v]==0) {
				dfs(v);
				low[u]=Math.min(low[u],low[v]);
			}
		}
		if (low[u]==dfn[u]) {
			++comp;
			while (true) {
				vis[stk[tot]]=0;
				cmp[stk[tot]]=comp;
				if (stk[tot--]==u) break;
			}
			id[comp]=u;
		}
	}
	public static void main(String[] args) throws IOException {
		BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out=new PrintWriter(System.out);
		StringTokenizer sa=new StringTokenizer(in.readLine());
		n=Integer.parseInt(sa.nextToken());
		m=Integer.parseInt(sa.nextToken());
		for (int i=1;i<=n;++i) G[i]=new ArrayList<Integer>();
		for (int i=0;i<m;++i) {
			sa=new StringTokenizer(in.readLine());
			u[i]=Integer.parseInt(sa.nextToken());
			v[i]=Integer.parseInt(sa.nextToken());
			G[u[i]].add(v[i]);
		}
		for (int i=1;i<=n;++i) if (dfn[i]==0) dfs(i);
		//for (int i=1;i<=n;++i)
		//	System.out.printf("i=%d cmp=%d dfn=%d low=%d\n",i,cmp[i],dfn[i],low[i]);
		for (int i=1;i<=n;++i) G[i]=new ArrayList<Integer>();
		for (int i=0;i<m;++i)
			if (cmp[u[i]]!=cmp[v[i]]) {
				G[cmp[u[i]]].add(cmp[v[i]]);
				++deg[cmp[v[i]]];
			}
		Queue<Integer> q=new LinkedList<Integer>();
		for (int i=1;i<=comp;++i) if (deg[i]==0)
			q.add(i);
		int top=q.poll();
		while (!q.isEmpty()) {
			int u=q.poll();
			out.printf("? %d %d\n",id[top],id[u]);
			out.flush();
			sa=new StringTokenizer(in.readLine());
			int x=Integer.parseInt(sa.nextToken());
			if (x==0) {
				int tmp=u;
				u=top;
				top=tmp;
			}
			for (int i=0;i<G[u].size();++i) {
				int v=G[u].get(i);
				if (--deg[v]==0) q.add(v);
			}
		}
		out.println("! "+id[top]);
		out.flush();
	}
}


import java.util.*;
import java.io.*;
public class Main {
	static int n,m,comp,tot,cnt;
	static int[] dfn=new int[112345];
	static int[] low=new int[112345];
	static int[] stk=new int[112345];
	static int[] cmp=new int[112345];
	static int[] u=new int[112345];
	static int[] v=new int[112345];
	static int[] deg=new int[112345];
	static int[] ptr=new int[112345];
	static ArrayList<Integer>[] arr=new ArrayList[112345];
	static ArrayList<Integer>[] G=new ArrayList[112345];
	static void dfs(int u) {
		dfn[u]=low[u]=++cnt;
		stk[++tot]=u;
		for (int i=0;i<G[u].size();++i) {
			int v=G[u].get(i);
			if (dfn[v]>0&&cmp[v]==0) low[u]=Math.min(low[u],low[v]);
			else if (dfn[v]==0) {
				dfs(v);
				low[u]=Math.min(low[u],low[v]);
			}
		}
		if (low[u]==dfn[u]) {
			++comp;
			while (true) {
				cmp[stk[tot]]=comp;
				arr[comp].add(stk[tot]);
				if (stk[tot--]==u) break;
			}
		}
		//System.out.printf("low[%d]=%d dfn[%d]=%d\n",u,low[u],u,dfn[u]);
	}
	public static void main(String[] args) throws IOException {
		BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out=new PrintWriter(System.out);
		StringTokenizer sa=new StringTokenizer(in.readLine());
		n=Integer.parseInt(sa.nextToken());
		m=Integer.parseInt(sa.nextToken());
		for (int i=1;i<=n;++i) {
			G[i]=new ArrayList<Integer>();
			arr[i]=new ArrayList<Integer>();
		}
		for (int i=0;i<m;++i) {
			sa=new StringTokenizer(in.readLine());
			u[i]=Integer.parseInt(sa.nextToken());
			v[i]=Integer.parseInt(sa.nextToken());
			G[u[i]].add(v[i]);
		}
		for (int i=1;i<=n;++i) if (dfn[i]==0) dfs(i);
		for (int i=1;i<=n;++i) G[i]=new ArrayList<Integer>();
		for (int i=0;i<m;++i)
			if (cmp[u[i]]!=cmp[v[i]]) {
				//System.out.printf("u=%d v=%d cmpu=%d cmpv=%d\n",u[i],v[i],cmp[u[i]],cmp[v[i]]);
				G[cmp[u[i]]].add(cmp[v[i]]);
				++deg[cmp[v[i]]];
			}
		Queue<Integer> q=new LinkedList<Integer>();
		for (int i=1;i<=n;++i) if (deg[i]==0)
			q.add(i);
		int u=q.poll();
		while (q.size()>0) {
			int v=q.poll();
			out.printf("? %d %d\n",arr[u].get(ptr[u]),arr[v].get(ptr[v]));
			out.flush();
			int x=Integer.parseInt(in.readLine());
			if (x==0) {int k=u;u=v;v=k;}
			++ptr[v];
			if (ptr[v]==arr[v].size()) for (int i=0;i<G[v].size();++i) {
				int o=G[v].get(i);
				if (--deg[o]==0) q.add(o);
			}
		}
		out.println("! "+arr[u].get(ptr[u]));
		out.flush();
	}
}


import java.util.*;
import java.io.*;
public class Main {
	static int[] vis=new int[112345];
	static int[] deg=new int[112345];
	static ArrayList<Integer>[] G=new ArrayList[112345];
	static ArrayList<Integer>[] tree=new ArrayList[112345];
	static void dfs(int u) {
		if (vis[u]>0) return;
		vis[u]=1;
		for (int i=0;i<G[u].size();++i) {
			int v=G[u].get(i);
			if (vis[v]==1) continue;
			dfs(v);
			++deg[v];
			tree[u].add(v);
		}
		vis[u]=2;
	}
	public static void main(String[] args) throws IOException {
		BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out=new PrintWriter(System.out);
		StringTokenizer sa=new StringTokenizer(in.readLine());
		int n=Integer.parseInt(sa.nextToken());
		int m=Integer.parseInt(sa.nextToken());
		for (int i=1;i<=n;++i) {
			G[i]=new ArrayList<Integer>();
			tree[i]=new ArrayList<Integer>();
		}
		while (m-->0) {
			sa=new StringTokenizer(in.readLine());
			int u=Integer.parseInt(sa.nextToken());
			int v=Integer.parseInt(sa.nextToken());
			G[u].add(v);
		}
		for (int i=1;i<=n;++i) dfs(i);
		Queue<Integer> que=new LinkedList<Integer>();
		for (int i=1;i<=n;++i) if (deg[i]==0)
			que.add(i);
		int u=que.poll();
		while (!que.isEmpty()) {
			int v=que.poll();
			out.printf("? %d %d\n",u,v);
			out.flush();
			int x=Integer.parseInt(in.readLine());
			if (x==0) {int o=u;u=v;v=o;}
			for (int i=0;i<tree[v].size();++i) {
				int o=tree[v].get(i);
				if (--deg[o]==0) que.add(o);
			}
		}
		out.printf("! %d\n",u);
		out.close();
	}
}


import java.util.*;
import java.io.*;
public class Main {
	static int[] vis=new int[200000];
	static int[] deg=new int[200000];
	static ArrayList<Integer>[] G=new ArrayList[200000];
	static ArrayList<Integer>[] tree=new ArrayList[200000];
	static void dfs(int u) {
		if (vis[u]>0) return;
		vis[u]=1;
		for (int i=0;i<G[u].size();++i) {
			int v=G[u].get(i);
			if (vis[v]==1) continue;
			dfs(v);
			++deg[v];
			tree[u].add(v);
		}
		vis[u]=2;
	}
	public static void main(String[] args) throws IOException {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out=new PrintWriter(System.out);
		StringTokenizer sa=new StringTokenizer(br.readLine());
		int n=Integer.parseInt(sa.nextToken());
		int m=Integer.parseInt(sa.nextToken());
		for (int i=1;i<=n;++i) {
			G[i]=new ArrayList<Integer>();
			tree[i]=new ArrayList<Integer>();
		}
		while (m-->0) {
			sa=new StringTokenizer(br.readLine());
			int u=Integer.parseInt(sa.nextToken());
			int v=Integer.parseInt(sa.nextToken());
			G[u].add(v);
		}
		for (int i=1;i<=n;++i) dfs(i);
		Queue<Integer> que=new LinkedList<Integer>();
		for (int i=1;i<=n;++i) if (deg[i]==0)
			que.add(i);
		int u=que.poll();
		while (!que.isEmpty()) {
			int v=que.poll();
			out.printf("? %d %d\n",u,v);
			out.flush();
			int x=Integer.parseInt(br.readLine());
			if (x==0) {int o=u;u=v;v=o;}
			for (int i=0;i<tree[v].size();++i) {
				int o=tree[v].get(i);
				if (--deg[o]==0) que.add(o);
			}
		}
		out.printf("! %d\n",u);
		out.close();
	}
}


#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 5;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
template <typename T> void write(T x) {
	if (x < 0) x = -x, putchar('-');
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
template <typename T> void writeln(T x) {
	write(x);
	puts("");
}
int n, m, timer, dfn[MAXN], low[MAXN];
int tot, belong[MAXN], top, Stack[MAXN];
vector <int> a[MAXN], b[MAXN], s[MAXN];
bool instack[MAXN]; int d[MAXN];
void tarjan(int pos) {
	dfn[pos] = low[pos] = ++timer;
	Stack[++top] = pos;
	instack[pos] = true;
	for (auto x : a[pos]) {
		if (!dfn[x]) {
			tarjan(x);
			chkmin(low[pos], low[x]);
		} else if (instack[x]) chkmin(low[pos], dfn[x]);
	}
	if (low[pos] == dfn[pos]) {
		int tmp = Stack[top--];
		instack[tmp] = false;
		belong[tmp] = ++tot;
		while (tmp != pos) {
			tmp = Stack[top--];
			instack[tmp] = false;
			belong[tmp] = tot;
		}
	}

}
int main() {
	read(n), read(m);
	for (int i = 1; i <= m; i++) {
		int x, y; read(x), read(y);
		a[x].push_back(y);
	}
	for (int i = 1; i <= n; i++) {
		if (!dfn[i]) tarjan(i);
		s[belong[i]].push_back(i);
		for (auto x : a[i])
			if (belong[i] != belong[x]) {
				b[belong[i]].push_back(belong[x]);
				d[belong[x]]++;
			}
	}
	static int q[MAXN];
	int l = 0, r = -1;
	for (int i = 1; i <= tot; i++)
		if (d[i] == 0) q[++r] = i;
	while (l < r) {
		int x = q[l++], y = q[l++];
		cout << "? " << s[x].back() << ' ' << s[y].back() << endl;
		bool res; read(res);
		if (res) {
			q[--l] = x;
			s[y].pop_back();
			if (s[y].empty()) {
				for (auto p : b[y])
					if (--d[p] == 0) q[++r] = p;
			} else q[--l] = y;
		} else {
			q[--l] = y;
			s[x].pop_back();
			if (s[x].empty()) {
				for (auto p : b[x])
					if (--d[p] == 0) q[++r] = p;
			} else q[--l] = x;
		}
	}
	cout << "! " << s[q[l]].back() << endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define sqr(x) ((x)*(x))
#define ull unsigned long long
#define mp make_pair
#define ld long double
#define fi first
#define se second
#define PI pair<int,int>
inline char gc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
#define gc getchar
inline ll read(){
	ll x = 0; char ch = gc(); bool positive = 1;
	for (; !isdigit(ch); ch = gc())	if (ch == '-')	positive = 0;
	for (; isdigit(ch); ch = gc())	x = x * 10 + ch - '0';
	return positive ? x : -x;
}
inline void write(ll a){
    if(a<0){
    	a=-a; putchar('-');
	}
    if(a>=10)write(a/10);
    putchar('0'+a%10);
}
inline void writeln(ll a){write(a); puts("");}
inline void wri(ll a){write(a); putchar(' ');}
const int N=100005;
int dfn[N],to[N],low[N],q[N],vis[N],zh[N],rd[N];
int ti,cnt;
vector<int> v[N],V[N],e[N];
void dfs(int p){
	dfn[p]=low[p]=++ti;
	vis[p]=zh[p]=1; q[++*q]=p;
	for(auto i:v[p]){
		if(!vis[i]){
			dfs(i); low[p]=min(low[p],low[i]);
		}else if(zh[i])low[p]=min(low[p],dfn[i]);
	}
	//cout<<dfn[p]<<" "<<low[p]<<" "<<q[*q]<<endl;
	if(dfn[p]==low[p]){
		cnt++;
		while(q[*q+1]!=p){
			to[q[*q]]=cnt; zh[q[*q]]=0; --*q;
		}
	}
}
int id(int x){
	return V[x].size()?V[x][V[x].size()-1]:-1;
}
int ask(int x,int y){
	putchar('?'); putchar(' '); wri(x); writeln(y); fflush(stdout);
	return read();
}
int main(){
	int n=read(),m=read();
	for(int i=1;i<=m;i++){
		int s=read(),t=read();
		v[s].push_back(t);
	}
	for(int i=1;i<=n;i++)if(!dfn[i])dfs(i);
	for(int i=1;i<=n;i++){
		V[to[i]].push_back(i);
		for(auto j:v[i])if(to[i]!=to[j]){e[to[i]].push_back(to[j]); rd[to[j]]++;}
	}
	//for(int i=1;i<=n;i++)cout<<V[i][0]<<" "<<rd[i]<<endl;
	*q=0;
	for(int i=1;i<=n;i++)if(!rd[i])q[++*q]=i;
	for(int i=1;i<=*q;i++){
		if(*q==i){
			cout<<"! "<<id(q[i])<<endl; return 0;
		}
		while(id(q[i])!=-1&&id(q[i+1])!=-1){
			int t=ask(id(q[i]),id(q[i+1]));
			if(t)swap(q[i],q[i+1]);
			V[q[i]].pop_back();
		}
		for(auto j:e[q[i]])if(--rd[j]==0)q[++*q]=j;
	}

}
/*
4 2
1 2
3 4

*/


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define sqr(x) ((x)*(x))
#define ull unsigned long long
#define mp make_pair
#define ld long double
#define fi first
#define se second
#define PI pair<int,int>
inline char gc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
#define gc getchar
inline ll read(){
	ll x = 0; char ch = gc(); bool positive = 1;
	for (; !isdigit(ch); ch = gc())	if (ch == '-')	positive = 0;
	for (; isdigit(ch); ch = gc())	x = x * 10 + ch - '0';
	return positive ? x : -x;
}
inline void write(ll a){
    if(a<0){
    	a=-a; putchar('-');
	}
    if(a>=10)write(a/10);
    putchar('0'+a%10);
}
inline void writeln(ll a){write(a); puts("");}
inline void wri(ll a){write(a); putchar(' ');}
const int N=100005;
int dfn[N],to[N],low[N],q[N],vis[N],zh[N],rd[N];
int ti,cnt;
vector<int> v[N],V[N],e[N];
void dfs(int p){
	dfn[p]=low[p]=++ti;
	vis[p]=zh[p]=1; q[++*q]=p;
	for(auto i:v[p]){
		if(!vis[i]){
			dfs(i); low[p]=min(low[p],low[i]);
		}else if(zh[i])low[p]=min(low[p],dfn[i]);
	}
	//cout<<dfn[p]<<" "<<low[p]<<" "<<q[*q]<<endl;
	if(dfn[p]==low[p]){
		cnt++;
		while(q[*q+1]!=p){
			to[q[*q]]=cnt; zh[q[*q]]=0; --*q;
		}
	}
}
int id(int x){
	return V[x].size()?V[x][V[x].size()-1]:-1;
}
int ask(int x,int y){
	putchar('?'); putchar(' '); wri(x); writeln(y); fflush(stdout);
	return read();
}
int main(){
	int n=read(),m=read();
	for(int i=1;i<=m;i++){
		int s=read(),t=read();
		v[s].push_back(t);
	}
	for(int i=1;i<=n;i++)if(!dfn[i])dfs(i);
	for(int i=1;i<=n;i++){
		V[to[i]].push_back(i);
		for(auto j:v[i])if(to[i]!=to[j]){e[to[i]].push_back(to[j]); rd[to[j]]++;}
	}
	//for(int i=1;i<=n;i++)cout<<V[i][0]<<" "<<rd[i]<<endl;
	*q=0;
	for(int i=1;i<=cnt;i++)if(!rd[i])q[++*q]=i;
	for(int i=1;i<=*q;i++){
		if(*q==i){
			cout<<"! "<<id(q[i])<<endl; return 0;
		}
		while(id(q[i])!=-1&&id(q[i+1])!=-1){
			int t=ask(id(q[i]),id(q[i+1]));
			if(t)swap(q[i],q[i+1]);
			V[q[i]].pop_back();
		}
		for(auto j:e[q[i]])if(--rd[j]==0)q[++*q]=j;
	}

}
/*
4 2
1 2
3 4

*/


/*
　　　　　／＞　 フ
　　　　　| 　_　 _|
　 　　　／`ミ _x 彡
　　 　 /　　　 　 |
　　　 /　  ヽ　　 ?
　／￣|　　 |　|　|
　| (￣ヽ＿_ヽ_)_)
　＼二つ
 */

#include <queue>
#include <vector>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MP make_pair
#define ll long long
#define fi first
#define se second
using namespace std;

template <typename T>
void read(T &x) {
    x = 0; bool f = 0;
    char c = getchar();
    for (;!isdigit(c);c=getchar()) if (c=='-') f=1;
    for (;isdigit(c);c=getchar()) x=x*10+(c^48);
    if (f) x=-x;
}

template<typename F>
inline void write(F x, char ed = '\n') {
	static short st[30];short tp=0;
	if(x<0) putchar('-'),x=-x;
	do st[++tp]=x%10,x/=10; while(x);
	while(tp) putchar('0'|st[tp--]);
	putchar(ed);
}

template <typename T>
inline void Mx(T &x, T y) { x < y && (x = y); }

template <typename T>
inline void Mn(T &x, T y) { x > y && (x = y); }

#include <ctime>
const int N = 505, M = N * N;
vector<int> v[N], scc[N];

int h[N], ne[M], to[M], tot;
inline void add(int x, int y) {
	ne[++tot] = h[x], to[h[x] = tot] = y;
}

int col[N], deg[N], m, n, c;
int dfn[N], low[N], vis[N], st[N], cnt, tp;
void dfs(int x) {
	dfn[x] = low[x] = ++cnt, vis[x] = 1, st[++tp] = x;
	for (int i = h[x]; i; i = ne[i]) {
		int y = to[i];
		if (!dfn[y]) dfs(y), Mn(low[x], low[y]);
		else if (vis[y]) Mn(low[x], dfn[y]);
	}
	if (low[x] == dfn[x]) {
		int z;
		while (z = st[tp--]) {
			col[z] = x, scc[x].push_back(z), vis[z] = 0;
			if (z == x) break;
		}
	}
}

queue<int> q;
void addin(int x) {
	x = col[x];
	if (scc[x].size()) q.push(scc[x].back()), scc[x].pop_back();
	else for (auto y: v[x]) deg[y]--, !deg[y] && (q.push(y), scc[y].pop_back(), 0);
}

int ask(int x, int y) {
	cout << "? " << x << ' ' << y << endl;
	cin >> x; return x;
}

struct edges {
	int x, y;
	edges(int xx = 0, int yy = 0) : x(xx), y(yy) {}
}ed[M];

int main() {
	cin >> n >> m; c = clock();
	for (int i = 1, x, y;i <= m; i++)
		read(x), read(y), add(x, y), ed[i] = edges(x, y);
	for (int i = 1;i <= n; i++) if (!dfn[i]) dfs(i);
	for (int i = 1;i <= m; i++) {
		int x = ed[i].x, y = ed[i].y;
		if (col[x] == col[y]) continue;
		x = col[x], y = col[y];
		v[x].push_back(y), deg[y]++;
	}
	for (int i = 1;i <= n; i++)
		if (col[i] == i && !deg[i]) q.push(i), scc[i].pop_back();
	int las = q.front(); q.pop();
	while (q.size()) {
		int x = q.front(); q.pop();
		ask(las, x) ? (addin(x), 0) : (addin(las), las = x);
	}
	cout << "! " << las << endl; fflush(stdout);
	return 0;
}

/*

4 2
1 3
2 4
1 0 0 1

*/


/*
　　　　　／＞　 フ
　　　　　| 　_　 _|
　 　　　／`ミ _x 彡
　　 　 /　　　 　 |
　　　 /　  ヽ　　 ?
　／￣|　　 |　|　|
　| (￣ヽ＿_ヽ_)_)
　＼二つ
 */

#include <queue>
#include <vector>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MP make_pair
#define ll long long
#define fi first
#define se second
using namespace std;

template <typename T>
void read(T &x) {
    x = 0; bool f = 0;
    char c = getchar();
    for (;!isdigit(c);c=getchar()) if (c=='-') f=1;
    for (;isdigit(c);c=getchar()) x=x*10+(c^48);
    if (f) x=-x;
}

template<typename F>
inline void write(F x, char ed = '\n') {
	static short st[30];short tp=0;
	if(x<0) putchar('-'),x=-x;
	do st[++tp]=x%10,x/=10; while(x);
	while(tp) putchar('0'|st[tp--]);
	putchar(ed);
}

template <typename T>
inline void Mx(T &x, T y) { x < y && (x = y); }

template <typename T>
inline void Mn(T &x, T y) { x > y && (x = y); }

#include <ctime>
const int N = 205000, M = N;
vector<int> v[N], scc[N];

int h[N], ne[M], to[M], tot;
inline void add(int x, int y) {
	ne[++tot] = h[x], to[h[x] = tot] = y;
}

int col[N], deg[N], m, n, c;
int dfn[N], low[N], vis[N], st[N], cnt, tp;
void dfs(int x) {
	dfn[x] = low[x] = ++cnt, vis[x] = 1, st[++tp] = x;
	for (int i = h[x]; i; i = ne[i]) {
		int y = to[i];
		if (!dfn[y]) dfs(y), Mn(low[x], low[y]);
		else if (vis[y]) Mn(low[x], dfn[y]);
	}
	if (low[x] == dfn[x]) {
		int z;
		while (z = st[tp--]) {
			col[z] = x, scc[x].push_back(z), vis[z] = 0;
			if (z == x) break;
		}
	}
}

queue<int> q;
void addin(int x) {
	x = col[x];
	if (scc[x].size()) q.push(scc[x].back()), scc[x].pop_back();
	else for (auto y: v[x]) deg[y]--, !deg[y] && (q.push(y), scc[y].pop_back(), 0);
}

int ask(int x, int y) {
	cout << "? " << x << ' ' << y << endl;
	cin >> x; return x;
}

struct edges {
	int x, y;
	edges(int xx = 0, int yy = 0) : x(xx), y(yy) {}
}ed[M];

int main() {
	cin >> n >> m; c = clock();
	for (int i = 1, x, y;i <= m; i++)
		read(x), read(y), add(x, y), ed[i] = edges(x, y);
	for (int i = 1;i <= n; i++) if (!dfn[i]) dfs(i);
	for (int i = 1;i <= m; i++) {
		int x = ed[i].x, y = ed[i].y;
		if (col[x] == col[y]) continue;
		x = col[x], y = col[y];
		v[x].push_back(y), deg[y]++;
	}
	for (int i = 1;i <= n; i++)
		if (col[i] == i && !deg[i]) q.push(i), scc[i].pop_back();
	int las = q.front(); q.pop();
	while (q.size()) {
		int x = q.front(); q.pop();
		ask(las, x) ? (addin(x), 0) : (addin(las), las = x);
	}
	cout << "! " << las << endl; fflush(stdout);
	return 0;
}

/*

4 2
1 3
2 4
1 0 0 1

*/


#include <iostream>
#include <fstream>
#include <string>
#include <set>
#include <string.h>
#include <functional>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <stack>
#include <map>

#define FI first.first
#define SE first.second
#define TH second
#define fi first
#define se second
#define th second

using namespace std;

typedef long long ll;
typedef pair<int, int> ii;

const int maxN = 1e5 + 9, maxV = 536, MOD = 1e9 + 7, AND = (1 << 20) - 1, lg = 21;

vector<int> farg[maxN], adj[maxN], adjc[maxN], cpy[maxN], elems[maxN];

int incom[maxN], comp[maxN],idx;

set<ii> mys;
stack<int> stc;
bool vi[maxN];

void dfs(int nd){
  if(vi[nd]) return;
  vi[nd] = 1;
  for(int sn: adj[nd])
    dfs(sn);
  stc.push(nd);
}

void sfd(int nd){
  if(vi[nd]) return;
  vi[nd] = 1;
  while(stc.size() && vi[stc.top()]) stc.pop();
  for(int sn: farg[nd])
    sfd(sn);
  comp[nd] = idx;
  elems[idx].push_back(nd);
  cpy[idx].push_back(nd);
}

bool makeQuery(int a, int b){
  cout << "? " << a + 1 << ' ' << b + 1 << '\n';
  cout.flush();
  int ans;
  cin >> ans;
  return ans == 1;
}

void procesavec(vector<int> &one, vector<int>&two){
  while(one.size() && two.size()){
    if(makeQuery(one.back(), two.back())){
      two.pop_back();
    } else {
      one.pop_back();
    }
  }
}

int n, m;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);

  cin >> n >> m;

  for(int u, v, i = 0; i < m; i++){
    cin >> u >> v;
    u--;
    v--;
    adj[u].push_back(v);
    farg[v].push_back(u);
  }

  for(int i = 0; i < n; i++) dfs(i);
  memset(vi, 0, sizeof vi);
  while(stc.size()){
    while(stc.size() && vi[stc.top()]) stc.pop();
    if(stc.empty()) break;
    sfd(stc.top());
    idx++;
  }
  for(int i = 0; i < n; i++){
    for(int to: adj[i]){
      incom[comp[to]]++;
      adjc[comp[i]].push_back(comp[to]);
    }
  }

  for(int i = 0; i < idx; i++){
    mys.insert(ii(incom[i], i));
  }

  int nd = mys.begin()->se;
  mys.erase(mys.begin());

  //cout << nd + 1 << '\n';

  //for(int i = 0; i < idx; i++) cout << elems[i][0] +1<< '\n';

  //for(auto el: mys) cout << el.fi << ' ' << el.se +1<< '\n';

  while(mys.size() && mys.begin()->fi == 0){
    int frontup = mys.begin()->se;
    mys.erase(ii(incom[frontup], frontup));
    procesavec(elems[nd], elems[frontup]);
    if(elems[nd].empty()) swap(nd, frontup);

    for(int cmp: adjc[frontup]){
      mys.erase(ii(incom[cmp]--, cmp));
      mys.insert(ii(incom[cmp], cmp));
    }
    //for(auto el: mys) cout << el.fi << ' ' << el.se +1<< '\n';
  }

  cout << "! " << elems[nd].back() + 1 << '\n';

}


#include <iostream>
#include <fstream>
#include <string>
#include <set>
#include <string.h>
#include <functional>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <stack>
#include <map>

#define FI first.first
#define SE first.second
#define TH second
#define fi first
#define se second
#define th second

using namespace std;

typedef long long ll;
typedef pair<int, int> ii;

const int maxN = 1e5 + 9, maxV = 536, MOD = 1e9 + 7, AND = (1 << 20) - 1, lg = 21;

vector<int> farg[maxN], adj[maxN], adjc[maxN], elems[maxN];

int incom[maxN], comp[maxN],idx;

set<ii> mys;
stack<int> stc;
bool vi[maxN];

void dfs(int nd){
  if(vi[nd]) return;
  vi[nd] = 1;
  for(int sn: adj[nd])
    dfs(sn);
  stc.push(nd);
}

void sfd(int nd){
  if(vi[nd]) return;
  vi[nd] = 1;
  for(int sn: farg[nd])
    sfd(sn);
  comp[nd] = idx;
  elems[idx].push_back(nd);
}

bool makeQuery(int a, int b){
  cout << "? " << a + 1 << ' ' << b + 1 << '\n';
  cout.flush();
  int ans;
  cin >> ans;
  return ans == 1;
}

void procesavec(vector<int> &one, vector<int>&two){
  while(one.size() && two.size()){
    if(makeQuery(one.back(), two.back())){
      two.pop_back();
    } else {
      one.pop_back();
    }
  }
}

int n, m;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);

  cin >> n >> m;

  for(int u, v, i = 0; i < m; i++){
    cin >> u >> v;
    u--;
    v--;
    adj[u].push_back(v);
    farg[v].push_back(u);
  }

  for(int i = 0; i < n; i++) dfs(i);
  memset(vi, 0, sizeof vi);
  while(stc.size()){
    while(stc.size() && vi[stc.top()]) stc.pop();
    if(stc.empty()) break;
    sfd(stc.top());
    idx++;
  }
  for(int i = 0; i < n; i++){
    for(int to: adj[i]){
      if(comp[to] == comp[i]) continue;
      incom[comp[to]]++;
      adjc[comp[i]].push_back(comp[to]);
    }
  }

  for(int i = 0; i < idx; i++){
    mys.insert(ii(incom[i], i));
  }

  int nd = mys.begin()->se;
  mys.erase(mys.begin());

  //cout << nd + 1 << '\n';

  //for(int i = 0; i < idx; i++) cout << elems[i][0] +1<< '\n';

  //for(auto el: mys) cout << el.fi << ' ' << el.se +1<< '\n';

  while(mys.size() && mys.begin()->fi == 0){
    int frontup = mys.begin()->se;
    mys.erase(ii(incom[frontup], frontup));
    procesavec(elems[nd], elems[frontup]);
    if(elems[nd].empty()) swap(nd, frontup);

    for(int cmp: adjc[frontup]){
      mys.erase(ii(incom[cmp]--, cmp));
      mys.insert(ii(incom[cmp], cmp));
    }
    //for(auto el: mys) cout << el.fi << ' ' << el.se +1<< '\n';
  }

  cout << "! " << elems[nd].back() + 1 << '\n';

}


#include<bits/stdc++.h>
#define maxn 100010
using namespace std;
int head[maxn], nxt[maxn], a[maxn], edge, sta[maxn], top, col[maxn], low[maxn], dfn[maxn];
int now, cnt_scc, deg[maxn], sep[maxn], node[maxn];
set<int> num;
vector<int> neigh[maxn];
int read()
{
	int tmp = 0, fh = 1; char c = getchar();
	while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();}
	while (c >= '0' && c <= '9') {tmp = tmp * 10 + c - '0'; c = getchar();}
	return tmp * fh;
}
void create(int u, int v)
{
	edge++; a[edge] = v; nxt[edge] = head[u]; head[u] = edge;
}
void tarjan(int u)
{
	low[u] = dfn[u] = ++now;
	sta[++top] = u;
	col[u] = 1;
	for (int i = head[u]; i; i = nxt[i])
	{
		int v = a[i];
		if (col[v] == 0)
		{
			tarjan(v);
			low[u] = min(low[u], low[v]);
		}
		else if (col[v] == 1) low[u] = min(low[u], dfn[v]);
	}
	if (low[u] == dfn[u])
	{
		cnt_scc++;
		while (sta[top] != u)
		{
			sep[sta[top]] = cnt_scc;
			col[sta[top]] = -1;
			top--;
		}
		sep[u] = cnt_scc;
		col[u] = -1;
		top--;
	}
}
void dele(int x)
{
	num.erase(x);
	int len = neigh[x].size();
	for (int i = 0; i <= len - 1; i++)
	{
		int v = neigh[x][i];
		deg[v]--;
		if (deg[v] == 0) num.insert(v);
	}
}
int main()
{
	int n = read(), m = read();
	for (int i = 1; i <= m; i++)
	{
		int u = read(), v = read();
		create(u, v);
	}
	for (int i = 1; i <= n; i++)
		if (col[i] == 0) tarjan(i);
	for (int u = 1; u <= n; u++)
		for (int i = head[u]; i; i = nxt[i])
		{
			int v = a[i];
			if (sep[u] != sep[v])
			{
				neigh[sep[u]].push_back(sep[v]);
				deg[sep[v]]++;
			}
		}
	for (int i = 1; i <= cnt_scc; i++)
		if (deg[i] == 0) num.insert(i);
	for (int i = 1; i <= n; i++)
		node[sep[i]] = i;
	while (num.size() >= 2)
	{
		int t1, t2;
		set<int>::iterator it = num.begin();
		t1 = *it;
		it++; t2 = *it;
		printf("? %d %d\n", node[t1], node[t2]);
		fflush(stdout);
		int s = read();
		if (s == 0) dele(t1);
		else dele(t2);
	}
	int res = *(num.begin());
	printf("! %d\n", node[res]);
}


#include<bits/stdc++.h>
#define maxn 100010
using namespace std;
int head[maxn], nxt[maxn], a[maxn], edge, sta[maxn], top, col[maxn], low[maxn], dfn[maxn];
int now, cnt_scc, deg[maxn], sep[maxn];
set<int> num, node[maxn];
vector<int> neigh[maxn];
int read()
{
	int tmp = 0, fh = 1; char c = getchar();
	while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();}
	while (c >= '0' && c <= '9') {tmp = tmp * 10 + c - '0'; c = getchar();}
	return tmp * fh;
}
void create(int u, int v)
{
	edge++; a[edge] = v; nxt[edge] = head[u]; head[u] = edge;
}
void tarjan(int u)
{
	low[u] = dfn[u] = ++now;
	sta[++top] = u;
	col[u] = 1;
	for (int i = head[u]; i; i = nxt[i])
	{
		int v = a[i];
		if (col[v] == 0)
		{
			tarjan(v);
			low[u] = min(low[u], low[v]);
		}
		else if (col[v] == 1) low[u] = min(low[u], dfn[v]);
	}
	if (low[u] == dfn[u])
	{
		cnt_scc++;
		while (sta[top] != u)
		{
			sep[sta[top]] = cnt_scc;
			col[sta[top]] = -1;
			top--;
		}
		sep[u] = cnt_scc;
		col[u] = -1;
		top--;
	}
}
void dele(int x)
{
	node[sep[x]].erase(x);
	if (node[sep[x]].size() == 0)
	{
		x = sep[x];
		num.erase(x);
		int len = neigh[x].size();
		for (int i = 0; i <= len - 1; i++)
		{
			int v = neigh[x][i];
			deg[v]--;
			if (deg[v] == 0) num.insert(v);
		}
	}
}
int main()
{
	int n = read(), m = read();
	for (int i = 1; i <= m; i++)
	{
		int u = read(), v = read();
		create(u, v);
	}
	for (int i = 1; i <= n; i++)
		if (col[i] == 0) tarjan(i);
	for (int u = 1; u <= n; u++)
		for (int i = head[u]; i; i = nxt[i])
		{
			int v = a[i];
			if (sep[u] != sep[v])
			{
				neigh[sep[u]].push_back(sep[v]);
				deg[sep[v]]++;
			}
		}
	for (int i = 1; i <= cnt_scc; i++)
		if (deg[i] == 0) num.insert(i);
	for (int i = 1; i <= n; i++)
		node[sep[i]].insert(i);
	while (num.size() >= 2)
	{
		int t1, t2;
		set<int>::iterator it = num.begin();
		t1 = *it;
		it++; t2 = *it;
		t1 = *(node[t1].begin());
		t2 = *(node[t2].begin());
		printf("? %d %d\n", t1, t2);
		fflush(stdout);
		int s = read();
		if (s == 0) dele(t1);
		else dele(t2);
	}
	int res = *(num.begin());
	printf("! %d\n", *(node[res].begin()));
}


#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

typedef long long ll;
typedef long double ld;
typedef complex<ld> cd;

typedef pair<int, int> pi;
typedef pair<ll,ll> pl;
typedef pair<ld,ld> pd;

typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<cd> vcd;

template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= (a); i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
#define trav(a, x) for (auto& a : x)

#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound

#define sz(x) (int)x.size()
#define beg(x) x.begin()
#define en(x) x.end()
#define all(x) beg(x), en(x)
#define resz resize

const int MOD = 1000000007; // 998244353
const ll INF = 1e18;
const int MX = 100001;
const ld PI = 4*atan((ld)1);

template<class T> void ckmin(T &a, T b) { a = min(a, b); }
template<class T> void ckmax(T &a, T b) { a = max(a, b); }

template<class A, class B> A operator+=(A& l, const B& r) { return l = l+r; }
template<class A, class B> A operator-=(A& l, const B& r) { return l = l-r; }
template<class A, class B> A operator*=(A& l, const B& r) { return l = l*r; }
template<class A, class B> A operator/=(A& l, const B& r) { return l = l/r; }

namespace input {
    template<class T> void re(complex<T>& x);
    template<class T1, class T2> void re(pair<T1,T2>& p);
    template<class T> void re(vector<T>& a);
    template<class T, size_t SZ> void re(array<T,SZ>& a);

    template<class T> void re(T& x) { cin >> x; }
    void re(double& x) { string t; re(t); x = stod(t); }
    void re(ld& x) { string t; re(t); x = stold(t); }
    template<class Arg, class... Args> void re(Arg& first, Args&... rest) {
        re(first); re(rest...);
    }

    template<class T> void re(complex<T>& x) { T a,b; re(a,b); x = cd(a,b); }
    template<class T1, class T2> void re(pair<T1,T2>& p) { re(p.f,p.s); }
    template<class T> void re(vector<T>& a) { F0R(i,sz(a)) re(a[i]); }
    template<class T, size_t SZ> void re(array<T,SZ>& a) { F0R(i,SZ) re(a[i]); }
}

using namespace input;

namespace output {
    template<class T1, class T2> void pr(const pair<T1,T2>& x);
    template<class T, size_t SZ> void pr(const array<T,SZ>& x);
    template<class T> void pr(const vector<T>& x);
    template<class T> void pr(const set<T>& x);
    template<class T1, class T2> void pr(const map<T1,T2>& x);

    template<class T> void pr(const T& x) { cout << x; }
    template<class Arg, class... Args> void pr(const Arg& first, const Args&... rest) {
        pr(first); pr(rest...);
    }

    template<class T1, class T2> void pr(const pair<T1,T2>& x) {
        pr("{",x.f,", ",x.s,"}");
    }
    template<class T> void prContain(const T& x) {
        pr("{");
        bool fst = 1; trav(a,x) pr(!fst?", ":"",a), fst = 0;
        pr("}");
    }
    template<class T, size_t SZ> void pr(const array<T,SZ>& x) { prContain(x); }
    template<class T> void pr(const vector<T>& x) { prContain(x); }
    template<class T> void pr(const set<T>& x) { prContain(x); }
    template<class T1, class T2> void pr(const map<T1,T2>& x) { prContain(x); }

    void ps() { pr("\n"); }
    template<class Arg, class... Args> void ps(const Arg& first, const Args&... rest) {
        pr(first," "); ps(rest...); // print w/ spaces
    }
}

using namespace output;

namespace io {
    void setIn(string s) { freopen(s.c_str(),"r",stdin); }
    void setOut(string s) { freopen(s.c_str(),"w",stdout); }
    void setIO(string s = "") {
        ios_base::sync_with_stdio(0); cin.tie(0); // fast I/O
        if (sz(s)) { setIn(s+".in"), setOut(s+".out"); } // for USACO
    }
}

using namespace io;

template<class T> T invGeneral(T a, T b) {
    a %= b; if (a == 0) return b == 1 ? 0 : -1;
    T x = invGeneral(b,a);
    return x == -1 ? -1 : ((1-(ll)b*x)/a+b)%b;
}

template<class T> struct modInt {
    T val;
    T mod = 0;
    // static const T mod = MOD;

    void normalize() {
        if (mod == 0) return;
        val %= mod; if (val < 0) val += mod;
    }
    modInt(T v = 0, T m = 0) : val(v), mod(m) { normalize(); }
    // modInt(T v = 0, T m = 0) : val(v) { normalize(); }

    explicit operator T() const { return val; }
    friend ostream& operator<<(ostream& os, const modInt& a) { return os << a.val; }
    friend bool operator==(const modInt& a, const modInt& b) { return a.val == b.val; }
    friend bool operator!=(const modInt& a, const modInt& b) { return !(a == b); }

    friend void check(modInt& a, modInt& b) { // make sure all operations are valid
        // comment out if mod is static const
        if (a.mod > 0 && b.mod > 0) { assert(a.mod == b.mod); return; }
        T mod = max(a.mod,b.mod); if (mod == 0) mod = MOD;
        if (a.mod != mod) { a.mod = mod; a.normalize(); }
        if (b.mod != mod) { b.mod = mod; b.normalize(); }
    }
    friend modInt operator+(modInt a, modInt b) {
        check(a,b); a.val += (T)b;
        if (a.val >= a.mod) a.val -= a.mod;
        return a;
    }
    friend modInt operator-(modInt a, modInt b) {
        check(a,b); a.val -= (T)b;
        if (a.val < 0) a.val += a.mod;
        return a;
    }
    friend modInt operator-(const modInt& a) { return modInt(0)-a; }

    friend modInt operator*(modInt a, modInt b) {
        check(a,b); a.val = (ll)a.val*(T)b%a.mod; return a;
    }
    friend modInt exp(modInt a, ll p) {
        modInt ans(1,a.mod);
        for (; p; p /= 2, a *= a) if (p&1) ans *= a;
        return ans;
    }
    friend modInt inv(const modInt& a) {
        return {invGeneral(a.val,a.mod),a.mod};
        // return exp(b,b.mod-2) if prime
    }
    friend modInt operator/(modInt a, modInt b) {
        check(a,b); return a*inv(b);
    }
};

typedef modInt<int> mi;
typedef pair<mi,mi> pmi;
typedef vector<mi> vmi;
typedef vector<pmi> vpmi;

queue<int> q;

template<int SZ> struct scc {
    int N, comp[SZ];
    vi adj[SZ], radj[SZ], todo, allComp;
    bitset<SZ> visit;
    vi rcomp[SZ];

    int in[SZ];
    vi child[SZ];

    void addEdge(int a, int b) { adj[a].pb(b), radj[b].pb(a); }

    void dfs(int v) {
        visit[v] = 1;
        trav(w,adj[v]) if (!visit[w]) dfs(w);
        todo.pb(v);
    }

    void dfs2(int v, int val) {
        comp[v] = val;
        trav(w,radj[v]) if (comp[w] == -1) dfs2(w,val);
    }

    void genSCC() { // fills allComp
        FOR(i,1,N+1) comp[i] = -1, visit[i] = 0;
        FOR(i,1,N+1) if (!visit[i]) dfs(i);
        reverse(all(todo)); // toposort
        trav(i,todo) if (comp[i] == -1) dfs2(i,i), allComp.pb(i);
        FOR(i,1,N+1) rcomp[comp[i]].pb(i);
        FOR(i,1,N+1) trav(j,adj[i]) if (comp[i] != comp[j]) child[comp[i]].pb(comp[j]);
        FOR(i,1,N+1) {
            sort(all(child[i])); child[i].erase(unique(all(child[i])),child[i].end());
            trav(t,child[i]) in[t] ++;
        }
        FOR(i,1,N+1) if (comp[i] == i && in[i] == 0) q.push(i);
    }
};

scc<MX> S;
int n,m;

bool query(int a, int b) {
    cout << "? " << a << " " << b << endl;
    int x; re(x); return x;
}

int main() {
    re(n,m); S.N = n;
    F0R(i,m) {
        int u,v; re(u,v);
        S.addEdge(u,v);
    }
    S.genSCC();
    auto a = q.front(); q.pop();
    while (sz(q)) {
        auto b = q.front(); q.pop();
        while (sz(S.rcomp[a]) && sz(S.rcomp[b])) {
            if (query(S.rcomp[a].back(),S.rcomp[b].back())) S.rcomp[b].pop_back();
            else S.rcomp[a].pop_back();
        }
        if (!sz(S.rcomp[a])) swap(a,b);
        trav(t,S.child[b]) {
            S.in[t] --;
            if (!S.in[t]) q.push(t);
        }
    }
    cout << "! " << S.rcomp[a].back() << endl;
}

/* stuff you should look for
    * int overflow, array bounds
    * special cases (n=1?), set tle
    * do smth instead of nothing and stay organized
*/


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#define pb push_back

const int N=100005;

int n,m,cnt,last[N],low[N],dfn[N],tim,stack[N],top,bel[N],ret[N],a[N],sz,ls[N],nx[N],pos[N],deg[N],tot;
bool ins[N];
struct edge{int from,to,next;}e[N];
std::vector<int> vec[N],pts[N];

void addedge(int u,int v)
{
	e[++cnt].from=u;e[cnt].to=v;e[cnt].next=last[u];last[u]=cnt;
}

void tarjan(int x)
{
	dfn[x]=low[x]=++tim;
	stack[++top]=x;ins[x]=1;
	for (int i=last[x];i;i=e[i].next)
		if (!dfn[e[i].to]) tarjan(e[i].to),low[x]=std::min(low[x],low[e[i].to]);
		else if (ins[e[i].to]) low[x]=std::min(low[x],dfn[e[i].to]);
	if (dfn[x]==low[x])
	{
		tot++;int y=0;
		while (y!=x)
		{
			y=stack[top--];ins[y]=0;
			bel[y]=tot;pts[tot].pb(y);
		}
		ret[tot]=pts[tot].size();
	}
}

void add(int x)
{
	for (int i=0;i<pts[x].size();i++)
	{
		int y=pts[x][i];
		a[++sz]=y;pos[y]=sz;
		ls[sz]=ls[n+1];nx[sz]=n+1;
		nx[ls[sz]]=ls[n+1]=sz;
	}
}

void del(int x)
{
	nx[ls[x]]=nx[x];ls[nx[x]]=ls[x];
	x=bel[a[x]];ret[x]--;
	if (!ret[x])
	{
		for (int i=0;i<vec[x].size();i++)
		{
			deg[vec[x][i]]--;
			if (!deg[vec[x][i]]) add(vec[x][i]);
		}
	}
}

int ask(int x,int y)
{
	printf("? %d %d\n",x,y);
	fflush(stdout);
	int k;scanf("%d",&k);
	return k;
}

int main()
{
	scanf("%d%d",&n,&m);
	for (int i=1;i<=m;i++)
	{
		int x,y;scanf("%d%d",&x,&y);
		addedge(x,y);
	}
	for (int i=1;i<=n;i++) if (!dfn[i]) tarjan(i);
	for (int i=1;i<=m;i++)
	{
		int x=bel[e[i].from],y=bel[e[i].to];
		if (x!=y) vec[x].pb(y),deg[y]++;
	}
	int tp=0;
	for (int i=1;i<=n;i++) if (!deg[bel[i]]) {tp=i;break;}
	for (int i=1;i<=tot;i++) if (!deg[i]) add(i);
	for (int i=1;i<=sz;i++) nx[i]=i+1,ls[i]=i-1;
	nx[0]=1;ls[n+1]=sz;nx[sz]=n+1;
	while (1)
	{
		if (bel[a[nx[0]]]==bel[tp]&&bel[a[ls[n+1]]]==bel[tp]) {printf("! %d\n",tp);fflush(stdout);return 0;}
		if (bel[a[nx[0]]]!=bel[tp])
		{
			int y=nx[0];
			if (ask(tp,a[y])) del(y);
			else del(pos[tp]),tp=a[y];
		}
		else
		{
			int y=ls[n+1];
			if (ask(tp,a[y])) del(y);
			else del(pos[tp]),tp=a[y];
		}
	}
	return 0;
}


#include <bits/stdc++.h>
#define N 100010
#define M 400010
#define ll long long
#define INF 10000010
#define rep(i,l,r) for (int i=(l);i<=(r);i++)
#define per(i,r,l) for (int i=(r);i>=(l);i--)
#define erep(i,x) for (int i=fir[x];i;i=nxt[i])
#define erep_(i,x) for (int i=fir_[x];i;i=nxt_[i])
using namespace std;
int n,m,dfn[N],low[N],times(0),st[N],top(0),is[N];
int fir[N],to[M],nxt[M],tot(1),num[N],cnt(0),d[N];
int fir_[N],to_[M],nxt_[M],tot_(1),mark[N],q[N],r[N];
vector<int> v[N];

inline void add(int u,int v){
	to[++tot]=v; nxt[tot]=fir[u]; fir[u]=tot;
}

inline void add_(int u,int v){
	to_[++tot_]=v; nxt_[tot_]=fir_[u]; fir_[u]=tot_;
}

void dfs(int x){
	dfn[x]=low[x]=++times;
	st[++top]=x; is[x]=1;
	erep(i,x){
		if (dfn[to[i]]){
			if (!is[to[i]])
				low[x]=min(low[x],dfn[to[i]]);
		}
		else{
			dfs(to[i]);
			low[x]=min(low[x],low[to[i]]);
		}
	}
	if (dfn[x]==low[x]){
		num[++cnt]=1; mark[x]=cnt;
		v[cnt].push_back(0);
		v[cnt].push_back(x);
		while (st[top]!=x){
			is[st[top]]=0,top--; mark[st[top]]=cnt;
			num[cnt]++; v[cnt].push_back(st[top]);
		}
		top--; is[x]=0;
	}
}

int work(int s,int a,int b){
	int x=1,y=1,t,s_=s;
	for (int i=0;x<=num[a] && y<=num[b];i^=1)
		if (!i)
			for (;y<=num[b];y++){
				printf("? %d %d\n",s,v[b][y]);
				cout.flush();
				scanf("%d",&t);
				if (!t){
					s=v[b][y]; y++;
					break;
				}
			}
		else
			for (;x<=num[a];x++)
				if (v[a][x]!=s_){
					printf("? %d %d\n",s,v[a][x]);
					cout.flush();
					scanf("%d",&t);
					if (!t){
						s=v[a][x]; x++;
						break;
					}
				}
	return s;
}

int solve(){
	int l=1,r=0;
	rep(i,1,cnt)
		if (!d[i])
			q[++r]=i;
	if (r==1)
		return v[q[r]][1];
	l++; int x=v[q[1]][1];
	for (;l<=r;l++){
		x=work(x,q[1],q[l]);
		if (mark[x]!=q[1])
			swap(q[1],q[l]);
		erep_(i,q[l]){
			d[to_[i]]--;
			if (!d[to_[i]])
				q[++r]=to_[i];
		}
	}
	return x;
}

int main(){
//	freopen("a.in","r",stdin);
//	freopen("a.out","w",stdout);
	scanf("%d%d",&n,&m);
	int u,v;
	rep(i,1,m){
		scanf("%d%d",&u,&v);
		add(u,v);
	}
	rep(i,1,n)
		if (!dfn[i])
			dfs(i);
	rep(i,1,n)
		erep(j,i)
			if (mark[to[j]]!=mark[i])
				add_(mark[i],mark[to[j]]),d[mark[to[j]]]++;
	printf("! %d\n",solve());
	cout.flush();
	return 0;
}


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

int a[2002];
int n,m;
int rem;
int vagfol;
int ans1,ans2=0;
int hapi[2002];
int mark[2002];
int k=1;
void bot()
{
    for(int i=k; i<=m; i++)
        if(hapi[i]<(ans1+1))
        {
            k=i;
            return;
        }
}
void hot()
{
    for(int i=k; i<=m; i++)
        if(hapi[i]<ans1)
        {
            k=i;
            return;
        }

}

int main()
{
    memset(mark,0,sizeof(mark));
    memset(mark,0,sizeof(hapi));
    cin>>n>>m;
    vagfol=n/m;
    rem=n%m;
    ans1=vagfol;

    for(int i=1; i<=n; i++)
    {
        cin>>a[i];
    }
    int kem=rem;
    for(int i=1; i<=n; i++)
    {
        if(a[i]<=m)
        {
            if(kem>0)
            {
                if(hapi[a[i]]==ans1+1)
                {
                    kem--;
                    continue;
                }
            }
            else
            {
                if(hapi[a[i]]==ans1)
                {
                    continue;
                }
            }
            hapi[a[i]]++;
            mark[i]=1;
        }
    }
    int p=0;
    for(int i=1; i<=n; i++)
    {
        if(mark[i])
            p++;
    }
    if(p==n)
    {
        cout<<ans1<<" "<<ans2<<endl;
        for(int i=1; i<=n; i++)
        {
            cout<<a[i]<<" ";
        }
        cout<<endl;
        return 0;

    }

    /*
        for(int i=1; i<=n; i++)
        {
            if(mark[i])
                cout<<i<<" "<<a[i]<<"  "<<hapi[a[i]]<<endl;
        }
        cout<<endl;
     */

    k=1;
    hot();
    for(int i=1; i<=n; i++)
    {
        if(mark[i]==1)
            continue;
        if(k>m)
            break;
        ans2++;
        mark[i]=1;
        a[i]=k;
        hapi[k]++;
        if(hapi[k]==ans1)
            hot();
    }

    k=1;
    bot();
    for(int i=1; i<=n; i++)
    {
        if(mark[i]==1)
            continue;
        if(k>m)
            break;
        ans2++;
        mark[i]=1;
        a[i]=k;
        hapi[k]++;
        if(hapi[k]==ans1+1)
            bot();
    }

    cout<<ans1<<" "<<ans2<<endl;
    for(int i=1; i<=n; i++)
    {
        cout<<a[i]<<" ";
    }
    cout<<endl;
    /*for(int i=1; i<=n; i++)
    {
        if(mark[i])
            continue;

        if(a[i]<=m)
        {
            hapi[a[i]]++;
        }
    }
    */
}


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

ll a[2002];
ll n,m;
ll rem;
ll vagfol;
ll ans1,ans2=0;
//int hapi[2002];
map<ll,ll>mapi;
//map<int,int>::iterator gud;
ll mark[2002];
ll k=1;
void bot()
{
    for(ll i=k; i<=m; i++)
        if(mapi[i]<(ans1+1))
        {
            k=i;
            return;
        }
}
void hot()
{
    for(ll i=k; i<=m; i++)
        if(mapi[i]<ans1)
        {
            k=i;
            return;
        }
        k=n+1;

}

int main()
{
    memset(mark,0,sizeof(mark));
    cin>>n>>m;
    vagfol=n/m;
    rem=n%m;
    ans1=vagfol;

    for(ll i=1; i<=n; i++)
    {
        cin>>a[i];
    }
    ll kem=rem;
    for(ll i=1; i<=n; i++)
    {
        if(a[i]<=m)
        {
            if(kem>0)
            {
                if(mapi[a[i]]==ans1+1)
                {
                    kem--;
                    continue;
                }
            }
            else
            {
                if(mapi[a[i]]==ans1)
                {
                    continue;
                }
            }
            mapi[a[i]]++;
            mark[i]=1;
        }
    }

    ll p=0;
    for(int i=1; i<=n; i++)
    {
        if(mark[i])
            p++;
    }
    if(p==n)
    {
        cout<<ans1<<" "<<ans2<<endl;
        for(ll i=1; i<=n; i++)
        {
            cout<<a[i]<<" ";
        }
        cout<<endl;
        return 0;

    }

    k=1;
    hot();
   // cout<<"k="<<k<<endl;
    for(ll i=1; i<=n; i++)
    {
        if(mark[i]==1)
            continue;
        if(k>m)
            break;
        ans2++;
        mark[i]=1;
        a[i]=k;
        mapi[k]++;
        if(mapi[k]==ans1)
            hot();
    }

   /* for(int i=1; i<=n; i++)
        {
            if(mark[i])
                cout<<i<<" "<<a[i]<<"  "<<mapi[a[i]]<<endl;
        }
        cout<<endl;
*/
/*
    k=1;
    bot();
    for(ll i=1; i<=n; i++)
    {
        if(mark[i]==1)
            continue;
        if(k>m)
            break;
        ans2++;
        mark[i]=1;
        a[i]=k;
        mapi[k]++;
        if(mapi[k]==ans1+1)
            bot();
    }

*/
    cout<<ans1<<" "<<ans2<<endl;
    for(ll i=1; i<=n; i++)
    {
        cout<<a[i]<<" ";
    }
    cout<<endl;
    /*for(int i=1; i<=n; i++)
    {
        if(mark[i])
            continue;

        if(a[i]<=m)
        {
            hapi[a[i]]++;
        }
    }
    */
}


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

ll a[2002];
ll n,m;
ll rem;
ll vagfol;
ll ans1,ans2=0;
//int hapi[2002];
map<ll,ll>mapi;
//map<int,int>::iterator gud;
ll mark[2002];
ll k=1;
void bot()
{
    for(ll i=k; i<=m; i++)
        if(mapi[i]<(ans1+1))
        {
            k=i;
            return;
        }
}
void hot()
{
    for(ll i=k; i<=m; i++)
        if(mapi[i]<ans1)
        {
            k=i;
            return;
        }

}

int main()
{
    memset(mark,0,sizeof(mark));
    cin>>n>>m;
    vagfol=n/m;
    rem=n%m;
    ans1=vagfol;

    for(ll i=1; i<=n; i++)
    {
        cin>>a[i];
    }
    ll kem=rem;
    for(ll i=1; i<=n; i++)
    {
        if(a[i]<=m)
        {
            if(kem>0)
            {
                if(mapi[a[i]]==ans1+1)
                {
                    kem--;
                    continue;
                }
            }
            else
            {
                if(mapi[a[i]]==ans1)
                {
                    continue;
                }
            }
            mapi[a[i]]++;
            mark[i]=1;
        }
    }
    ll p=0;
    for(int i=1; i<=n; i++)
    {
        if(mark[i])
            p++;
    }
    if(p==n)
    {
        cout<<ans1<<" "<<ans2<<endl;
        for(ll i=1; i<=n; i++)
        {
            cout<<a[i]<<" ";
        }
        cout<<endl;
        return 0;

    }

    /*
        for(int i=1; i<=n; i++)
        {
            if(mark[i])
                cout<<i<<" "<<a[i]<<"  "<<hapi[a[i]]<<endl;
        }
        cout<<endl;
     */

    k=1;
    hot();
    for(ll i=1; i<=n; i++)
    {
        if(mark[i]==1)
            continue;
        if(k>m)
            break;
        ans2++;
        mark[i]=1;
        a[i]=k;
        mapi[k]++;
        if(mapi[k]==ans1)
            hot();
    }

    k=1;
    bot();
    for(ll i=1; i<=n; i++)
    {
        if(mark[i]==1)
            continue;
        if(k>m)
            break;
        ans2++;
        mark[i]=1;
        a[i]=k;
        mapi[k]++;
        if(mapi[k]==ans1+1)
            bot();
    }

    cout<<ans1<<" "<<ans2<<endl;
    for(ll i=1; i<=n; i++)
    {
        cout<<a[i]<<" ";
    }
    cout<<endl;
    /*for(int i=1; i<=n; i++)
    {
        if(mark[i])
            continue;

        if(a[i]<=m)
        {
            hapi[a[i]]++;
        }
    }
    */
}


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

int a[2002];
int n,m;
int rem;
int vagfol;
int ans1,ans2=0;
int hapi[2002];
int mark[2002];
int k=1;
void bot()
{
    for(int i=k; i<=m; i++)
        if(hapi[i]<(ans1+1))
        {
            k=i;
            return;
        }
}
void hot()
{
    for(int i=k; i<=m; i++)
        if(hapi[i]<ans1)
        {
            k=i;
            return;
        }

}

int main()
{
    memset(mark,0,sizeof(mark));
    memset(mark,0,sizeof(hapi));
    cin>>n>>m;
    vagfol=n/m;
    rem=n%m;
    ans1=vagfol;

    for(int i=1; i<=n; i++)
    {
        cin>>a[i];
    }
    int kem=rem;
    for(int i=1; i<=n; i++)
    {
        if(a[i]<=m)
        {
            if(kem>0)
            {
                if(hapi[a[i]]==ans1+1)
                {
                    kem--;
                    continue;
                }
            }
            else
            {
                if(hapi[a[i]]==ans1)
                {
                    continue;
                }
            }
            hapi[a[i]]++;
            mark[i]=1;
        }
    }
/*
    for(int i=1; i<=n; i++)
    {
        if(mark[i])
            cout<<i<<" "<<a[i]<<"  "<<hapi[a[i]]<<endl;
    }
    cout<<endl;
 */

    k=1;
    hot();
    for(int i=1; i<=n; i++)
    {
        if(mark[i]==1)
            continue;
        ans2++;
        mark[i]=1;
        a[i]=k;
        hapi[k]++;
        if(hapi[k]==ans1)
            hot();
    }

    k=1;
    bot();
    for(int i=1; i<=n; i++)
    {
        if(mark[i]==1)
            continue;
        ans2++;
        mark[i]=1;
        a[i]=k;
        hapi[k]++;
        if(hapi[k]==ans1+1)
            bot();
    }

    cout<<ans1<<" "<<ans2<<endl;
    for(int i=1; i<=n; i++)
    {
        cout<<a[i]<<" ";
    }
    cout<<endl;
    /*for(int i=1; i<=n; i++)
    {
        if(mark[i])
            continue;

        if(a[i]<=m)
        {
            hapi[a[i]]++;
        }
    }
    */
}


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

int n,m,ans1,ans2;
int a[2002];
int mark[2002];
int mapp[2002];
int i;
int topp;
stack<int>s;

void debug()
{
    for(int i=1;i<=n;i++)
    cout<<mark[i]<<" ";
    cout<<endl<<endl;

    for(int i=1;i<=m;i++)
    cout<<mapp[i]<<" ";
    cout<<endl<<endl;

    return;
}

void print()
{
    cout<<ans1<<" "<<ans2<<endl;
    for(i=1;i<=n;i++)
    cout<<a[i]<<" ";
    cout<<endl;
    return;
}

int main()
{
    //freopen("input.txt","r",stdin);

    cin>>n>>m;

    for(i=1; i<=n; i++)
        cin>>a[i];

    ans1=n/m;

    memset(mark,0,sizeof(mark));
    memset(mapp,0,sizeof(mapp));

    for(i=1; i<=n; i++)
    {
        if(a[i]>m)
            continue;

        if( mapp[ a[i] ]==ans1 )
            continue;

        mapp[ a[i] ]++;
        mark[i]=1;
    }

    //debug();

    for(i=1; i<=m; i++)
    {
        if(mapp[i]<ans1)
            s.push(i);
    }

    if(s.size()==0)
    {
        print();
        return 0;
    }

    topp=s.top();
    s.pop();

    for(i=1; i<=n; i++)
    {
        if(a[i]>m)
        {
            if(mapp[topp]<ans1)
            {
                mark[i]=1;
                a[i]=topp;
                mapp[topp]++;
                ans2++;
            }
            else
            {
                if(s.size()==0)
                {
                    print();
                    return 0;
                }
                topp=s.top();
                s.pop();
                --i;
            }
        }
    }

    //debug();

    for(i=1; i<=n; i++)
    {
        if(mark[i])
            continue;

        if(mapp[topp]<ans1)
        {
            mark[i]=1;
            a[i]=topp;
            mapp[topp]++;
            ans2++;
        }
        else
        {
            if(s.size()==0)
            {
                print();
                return 0;
            }
            topp=s.top();
            s.pop();
        }
    }
    print();
    return 0;
}


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

int a[2002];
int n,m;
int rem;
int vagfol;
int ans1,ans2;
//map<int>mapi;
int hapi[2004];
int mark[2004];
map<int,int>::iterator ii;
int k=1;
void bot()
{
    for(int i=k; i<=m; i++)
        if(hapi[i]<ans1+1)
        {
            k=i;
            return;
        }
}
void hot()
{
    for(int i=k; i<=m; i++)
        if(hapi[i]<ans1)
        {
            k=i;
            return;
        }

}

//int ans2=0;
int main()
{
    memset(mark,0,sizeof(mark));
    memset(mark,0,sizeof(hapi));
    cin>>n>>m;
    vagfol=n/m;
    rem=n%m;
    ans1=vagfol;

    for(int i=1; i<=n; i++)
    {
        cin>>a[i];
        //    mapi[a[i]]++;
    }
    //ii=mapi;
    int kem=rem;
    for(int i=1; i<=n; i++)
    {
        if(a[i]<=m)
        {
            if(kem)
            {
                if(hapi[a[i]]==ans1+1)
                {
                    kem--;
                    continue;
                }
            }
            else
            {
                if(hapi[a[i]]==ans1)
                {
                    continue;
                }
            }
            hapi[a[i]]++;
            mark[i]=1;
            // mapi[]
        }
    }
/*
    for(int i=1; i<=n; i++)
    {
        if(mark[i])
            cout<<i<<" "<<a[i]<<"  "<<hapi[a[i]]<<endl;
    }
    cout<<endl;
 */   k=1;
    hot();

//cout<<"k="<<k<<endl;
    for(int i=1; i<=n; i++)
    {
        if(mark[i]==1)
            continue;
        ans2++;

        mark[i]=1;
        a[i]=k;
        hapi[k]++;
        if(hapi[k]==ans1)
            hot();

    }
    for(int i=1; i<=n; i++)
    {
        if(mark[i]==1)
            continue;

        ans2++;
        mark[i]=1;
        a[i]=k;
        hapi[k]++;
        if(hapi[k]==ans1+1)
            bot();

    }

    cout<<ans1<<" "<<ans2<<endl;
    for(int i=1; i<=n; i++)
    {
        cout<<a[i]<<" ";
    }
    cout<<endl;
    /*for(int i=1; i<=n; i++)
    {
        if(mark[i])
            continue;

        if(a[i]<=m)
        {
            hapi[a[i]]++;
        }
    }
    */
}


//Bismillahir Rahmanir Rahim
#include <bits/stdc++.h>

using namespace std;

long long int a[1000009];
long long int b[1000009];

int minimum(long long b[], int m)
{
    int i=0, cur_min=0;
    for(i=0; i<m; i++)
    {
        if(b[i]<b[cur_min])
        {
            cur_min=i;
        }
        else if(b[i]==b[cur_min])
        {
            if(i<cur_min)
            {
                cur_min=i;
            }
        }
        else
        {

        }

    }
    return cur_min;

}

int main()
{
    int n, m,k, change=0;
    scanf("%d %d", &n, &m);
    int i;
    for(i=0; i<2500; i++)
    {
        b[i]=0;
    }
    for(i=0; i<n; i++)
    {
        scanf("%d", &a[i]);
        if(a[i]<=m)
        {
            k=a[i]-1;
            b[k]++;            //occurence increasing;
        }

    }
    /* for(i=0;i<m;i++)
     {
         printf("%d", b[i]);
     }
     */

    printf("\n\n\n");
    int avg;
    avg=n/m;
    int now;
    now=minimum(b, m);          //finding the index of the minimum value in B
    //printf("(%d)", now+1);
    for(i=0; i<n; i++)          //Case 1: the number in A is not within 1-m
    {
        if(a[i]>m)
        {
            a[i]=now+1;
            b[now]++;
            now=minimum(b, m);
            change++;
        }
        else                    //Case 2: the number is within 1-M
        {
            if(b[a[i]-1]>avg)
            {
                b[a[i]-1]--;    //decreasing higher occurence
                a[i]=now+1;
                b[now]++;       //increasing lower occurences
                now=minimum(b,m);
                change++;
            }
        }
        //printf("(%d %d)\n", b[now], change);
        if(b[now]>=avg)break;

    }

    printf("%d %d\n", avg, change);
    for(i=0; i<n; i++)
    {
        printf("%d ", a[i]);
    }

}


//Bismillahir Rahmanir Rahim
#include <bits/stdc++.h>

using namespace std;

int minimum(int b[], int m)
{
    int i=0, cur_min=0;
    for(i=0; i<m; i++)
    {
        if(b[i]<b[cur_min])
        {
            cur_min=i;
        }
        else if(b[i]==b[cur_min])
        {
            if(i<cur_min)
            {
                cur_min=i;
            }
        }
        else
        {

        }

    }
    return cur_min;

}

int main()
{
    int n, m,k, change=0;
    scanf("%d %d", &n, &m);

    int a[2000];
    int b[2000];

    int i;
    for(i=0; i<2000; i++)
    {
        b[i]==0;
    }
    for(i=0; i<n; i++)
    {
        scanf("%d", &a[i]);
        if(a[i]<=m)
        {
            k=a[i]-1;
            b[k]++;            //occurence increasing;
        }

    }
    /* for(i=0;i<m;i++)
     {
         printf("%d", b[i]);
     }
     */

    printf("\n\n\n");
    int avg;
    avg=n/m;
    int now;
    now=minimum(b, m);          //finding the index of the minimum value in B
    //printf("(%d)", now+1);
    for(i=0; i<n; i++)          //Case 1: the number in A is not within 1-m
    {
        if(a[i]>m)
        {
            a[i]=now+1;
            b[now]++;
            now=minimum(b, m);
            change++;
        }
        else                    //Case 2: the number is within 1-M
        {
            if(b[a[i]-1]>avg)
            {
                b[a[i]-1]--;    //decreasing higher occurence
                a[i]=now+1;
                b[now]++;       //increasing lower occurences
                now=minimum(b,m);
                change++;
            }
        }
        //printf("(%d %d)\n", b[now], change);
        if(b[now]>=avg)break;

    }

    printf("%d %d\n", avg, change);
    for(i=0; i<n; i++)
    {
        printf("%d ", a[i]);
    }
    printf("\n");
    return 0;

}


//Bismillahir Rahimanir Rahim
#include <bits/stdc++.h>

using namespace std;

int minimum(int b[], int m)
{
    int i=0, cur_min=0;
    for(i=0; i<m; i++)
    {
        if(b[i]<b[cur_min])
        {
            cur_min=i;
        }
    }
    return cur_min;

}

int main()
{
    int n, m,k, change=0;
    scanf("%d %d", &n, &m);

    int a[2000];
    int b[2000];

    int i;
    for(i=0; i<2000; i++)
    {
        b[i]==0;
    }
    for(i=0; i<n; i++)
    {
        scanf("%d", &a[i]);
        if(a[i]<=m)
        {
            k=a[i]-1;
            b[k]++;
        }

    }
    /* for(i=0;i<m;i++)
     {
         printf("%d", b[i]);
     }
     */

    printf("\n\n\n");
    int avg;
    avg=n/m;
    int now;
    now=minimum(b, m);
    //printf("(%d)", now+1);
    for(i=0; i<n; i++)
    {
        if(a[i]>m)
        {
            a[i]=now+1;
            b[now]++;
            now=minimum(b, m);
            change++;
        }
        else
        {
            if(b[a[i]-1]>avg)
            {
                a[i]=now+1;
                b[now]++;
                now=minimum(b,m);
                change++;
            }
        }
        //printf("(%d %d)\n", b[now], change);
        if(b[now]>=avg)break;

    }

    printf("%d %d\n", avg, change);
    for(i=0; i<n; i++)
    {
        printf("%d ", a[i]);
    }

}


//Bismillahir Rahimanir Rahim
#include <bits/stdc++.h>

using namespace std;

int minimum(int b[], int m)
{
    int i=0, cur_min=0;
    for(i=0; i<m; i++)
    {
        if(b[i]<b[cur_min])
        {
            cur_min=i;
        }
    }
    return cur_min;

}

int main()
{
    int n, m,k, change=0;
    scanf("%d %d", &n, &m);

    int a[2000];
    int b[2000];

    int i;
    for(i=0; i<2000; i++)
    {
        b[i]==0;
    }
    for(i=0; i<n; i++)
    {
        scanf("%d", &a[i]);
        if(a[i]<=m)
        {
            k=a[i]-1;
            b[k]++;
        }

    }
    /* for(i=0;i<m;i++)
     {
         printf("%d", b[i]);
     }
     */

    printf("\n\n\n");
    int avg;
    avg=n/m;
    int now;
    now=minimum(b, m);
    //printf("(%d)", now+1);
    for(i=0; i<n; i++)
    {
        if(a[i]>m)
        {
            a[i]=now+1;
            b[now]++;
            now=minimum(b, m);
            change++;
        }
        else
        {
            if(b[a[i]-1]>avg)
            {
                b[a[i]-1]--;
                a[i]=now+1;
                b[now]++;
                now=minimum(b,m);
                change++;
            }
        }
        //printf("(%d %d)\n", b[now], change);
        if(b[now]>=avg)break;

    }

    printf("%d %d\n", avg, change);
    for(i=0; i<n; i++)
    {
        printf("%d ", a[i]);
    }

}


//Bismillahir Rahmanir Rahim
#include <bits/stdc++.h>

using namespace std;

int minimum(int b[], int m)
{
    int i=0, cur_min=0;
    for(i=0; i<m; i++)
    {
        if(b[i]<b[cur_min])
        {
            cur_min=i;
        }
    }
    return cur_min;

}

int main()
{
    int n, m,k, change=0;
    scanf("%d %d", &n, &m);

    int a[4000];
    int b[4000];

    int i;
    for(i=0; i<2000; i++)
    {
        b[i]==0;
    }
    for(i=0; i<n; i++)
    {
        scanf("%d", &a[i]);
        if(a[i]<=m)
        {
            k=a[i]-1;
            b[k]++;            //occurence increasing;
        }

    }
    int avg;
    avg=n/m;
    int now;
    now=minimum(b, m);          //finding the index of the minimum value in B

    for(i=0; i<n; i++)          //Case 1: the number in A is not within 1-m
    {
        if(b[now]>=avg)break;

        if(a[i]>m)
        {
            a[i]=now+1;
            b[now]++;
            now=minimum(b, m);
            change++;
        }
        else                    //Case 2: the number is within 1-M
        {
            if(b[a[i]-1]>avg)
            {
                b[a[i]-1]--;
                a[i]=now+1;
                b[now]++;
                now=minimum(b,m);
                change++;
            }
        }
        if(b[now]>=avg)break;

    }

    printf("%d %d\n", avg, change);
    for(i=0; i<n; i++)
    {
        printf("%d ", a[i]);
    }
	printf("\n");
	return 0;

}


//Bismillahir Rahmanir Rahim
#include <bits/stdc++.h>

using namespace std;

int minimum(int b[], int m)
{
    int i=0, cur_min=0;
    for(i=0; i<m; i++)
    {
        if(b[i]<b[cur_min])
        {
            cur_min=i;
        }
    }
    return cur_min;

}

int main()
{
    int n, m,k, change=0;
    scanf("%d %d", &n, &m);

    int a[2000];
    int b[2000];

    int i;
    for(i=0; i<2000; i++)
    {
        b[i]==0;
    }
    for(i=0; i<n; i++)
    {
        scanf("%d", &a[i]);
        if(a[i]<=m)
        {
            k=a[i]-1;
            b[k]++;            //occurence increasing;
        }

    }
    int avg;
    avg=n/m;
    int now;
    now=minimum(b, m);          //finding the index of the minimum value in B

    for(i=0; i<n; i++)          //Case 1: the number in A is not within 1-m
    {
        if(a[i]>m)
        {
            a[i]=now+1;
            b[now]++;
            now=minimum(b, m);
            change++;
        }
        else                    //Case 2: the number is within 1-M
        {
            if(b[a[i]-1]>avg)
            {
                b[a[i]-1]--;
                a[i]=now+1;
                b[now]++;
                now=minimum(b,m);
                change++;
            }
        }
        if(b[now]>=avg)break;

    }

    printf("%d %d\n", avg, change);
    for(i=0; i<n; i++)
    {
        printf("%d ", a[i]);
    }
	printf("\n");
	return 0;

}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
    {
      ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
 ll n,m,i,j,a[2001],c[2001],k,ans=0,x=0,y=0,z=0,b[2001],r=0;
 bool ch[2001]={false};
cin>>n>>m;
for(i=1;i<=n;i++)
{
  cin>>a[i];
  if(a[i]<=m)
    c[a[i]]++;

}
x=n/m;
for(i=1;i<=m;i++)
{
  while(c[i]<x)
  {
    for(j=1;j<=n;j++)
    {
      if(a[j]>m || c[a[j]]>x)
      {
        if(a[j]<=m)
          c[a[j]]--; //interchange ke liye
        a[j]=i;
        c[a[j]]++;
        ans++;
        break;
      }
    }
  }
}
cout<<x<<" "<<ans<<"\n";
for(i=1;i<=n;i++)
cout<<a[i]<<" ";
 return 0;

}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
    {
      ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
 int n,m,i,j,a[2001],c[2001],k,ans=0,x=0,y=0,z=0,b[2001],r=0;
 bool ch[2001]={false};
scanf("%d %d",&n,&m);
for(i=1;i<=n;i++)
{
  scanf("%d",&a[i]);
  if(a[i]<=m)
    c[a[i]]++;

}
x=n/m;
for(i=1;i<=m;i++)
{
  while(c[i]<x)
  {
    for(j=1;j<=n;j++)
    {
      if(a[j]>m || c[a[j]]>x)
      {
        if(a[j]<=m)
          c[a[j]]--; //interchange ke liye
        a[j]=i;
        c[a[j]]++;
        ans++;
        break;
      }
    }
  }
}
printf("%d %d\n",x,ans);
for(i=1;i<=n;i++)
printf("%d ",a[i]);
 return 0;

}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2005;
int main()
    {
      ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
 int n,m,i,j,a[N],c[N],k,ans=0,x=0,y=0,z=0;

scanf("%d %d",&n,&m);
for(i=1;i<=n;i++)
{
  scanf("%d",&a[i]);
  if(a[i]<=m)
    c[a[i]]++;

}
x=n/m;
for(i=1;i<=m;i++)
{
  while(c[i]<x)
  {
    for(j=1;j<=n;j++)
    {
      if(a[j]>m || c[a[j]]>x){

        if(a[j]<=m)
          c[a[j]]--; //interchange ke liye
        a[j]=i;
        c[a[j]]++;
        ans++;
        break;
      }
    }
  }
}
printf("%d %d\n",x,ans);
for(i=1;i<=n;i++)
printf("%d ",a[i]);
 return 0;

}


#include <bits/stdc++.h>
using namespace std;
int a[20010];
map <int, int> M;
int main(){
    int n, m;
    cin>>n>>m;
    for (int i=1; i<=n; i++){
        cin>>a[i];
        if (a[i]<=m)
        M[a[i]]++;
    }
    int ans= 0,x;
    x=n/m;
    for (int i=1; i<=m; i++){
        while (M[i] < x){
            for (int j=1; j<=n; j++){
                if (a[j]>m || M[a[j]]>x){
                    if (a[j]<=m) M[a[j]]--;
                    a[j]= i;
                    M[i]++;
                    ans++;
                    break;
                }
            }
        }
    }
    cout<<x<<" "<<ans<<endl;
    for (int i=1; i<=n; i++) cout<<a[i]<<" ";
        cout<<endl;

}


#include <bits/stdc++.h>
using namespace std;
const int N=2005;
int main()
    {
     // ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
 int n,m,i,j,a[N],c[N],k,ans=0,x=0;

cin>>n>>m;
for(i=1;i<=n;i++)
{
  cin>>a[i];
  if(a[i]<=m)
    c[a[i]]++;

}
x=n/m;
ans=0;
for(i=1;i<=m;i++)
{
  while(c[i]<x)
  {
    for(j=1;j<=n;j++){
      if(a[j]>m || c[a[j]]>x){
        if(a[j]<=m) c[a[j]]--; //interchange ke liye
        a[j]=i;
        c[a[j]]++;
        ans++;
        break;
      }
    }
  }
}
cout<<x<<" "<<ans<<"\n";
for(i=1;i<=n;i++)
cout<<a[i]<<" ";
}


#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

int road[2005];
int cnt[2005];

int main()
{
    int m,n;
    scanf("%d %d",&n,&m);
    for(int i=0 ; i<n ; i++)
    {
        scanf("%d",&road[i]);
        if(road[i]<=m)
        {
            cnt[road[i]]++;
        }
    }
    int num=n/m;
    int change=0;
    for(int i=1 ; i<=m ; i++)
    {
        if(cnt[i]<num)
        {
            for(int j=0 ; j<n ; j++)
            {
                if(road[j]>m)
                {
                    change++;
                    road[j]=i;
                    cnt[i]++;
                }
                else if(cnt[road[j]]>num)
                {
                    change++;
                    cnt[road[j]]--;
                    road[j]=i;
                    cnt[i]++;

                }
                if(cnt[i]==num)
                    break;
            }
        }
    }
    printf("%d %d\n",num,change);
    printf("%d",road[0]);
    for(int i=1; i<n ; i++)
    {
        printf(" %d",road[i]);
    }
    printf("\n");
    return 0;
}


#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

int road[2005];
int cnt[2005];

int serch(int m,int num)
{
    int val=1;
    for(int i=1 ; i<=m ; i++)
    {
        if(cnt[i]<num&&cnt[i]<cnt[val])
            val=i;
    }
    return val;
}

int main()
{
    int m,n;
    memset(road,0,sizeof(road));
    memset(cnt,0,sizeof(cnt));
    scanf("%d %d",&n,&m);
    int num=n/m;
    for(int i=0 ; i<n ; i++)
    {
        scanf("%d",&road[i]);
        if(road[i]<=m)
        {
            cnt[road[i]]++;
        }
    }
    int change=0;
    int save=n%m;
    int b=serch(m,num+(save>0));
    for(int i=0 ; i<n ; i++)
    {
        if(road[i]>m)
        {
            change++;
            road[i]=b;
            cnt[b]++;
            if(cnt[b]>=num+(save>0))
            {
                save--;
                b=serch(m,num+(save>0));
            }
        }
    }
    b=serch(m,num);
    if(cnt[b]<num)
    {
        for(int i=0 ; i<n ; i++)
        {
            if(cnt[road[i]]>num+1&&road[i]!=b)
            {
                cnt[road[i]]--;
                cnt[b]++;
                road[i]=b;
                change++;
                if(cnt[b]>=num)
                {
                    b=serch(m,num);
                }
            }
        }
    }
    for(int i=0 ; i<m ; i++)
    {
        if(cnt[i]>num+1)
        {
            b=serch(m,num+1);
            for(int j=0 ; j<n ; j++)
            {
                if(road[j]==i)
                {
                    change++;
                    road[j]=b;
                    cnt[i]--;
                    cnt[b]++;
                    if(cnt[b]==num+1)
                    {
                        b=serch(m,num+1);
                    }
                    if(cnt[i]==num+1)
                        break;
                }
            }
        }
    }
    /*
    if(cnt[b]>num+1)
    {

        for(int i=0 ; i<n ; i++)
        {
            if(cnt[road[i]]>num+1)
            {
                cnt[road[i]]--;
                cnt[b]++;
                road[i]=b;
                change++;
                if(cnt[b]>=num+1)
                {
                    b=serch(m,num+1);
                }
            }
        }
    }
*/
    printf("%d %d\n",num,change);
    printf("%d",road[0]);
    for(int i=1 ; i<n ; i++)
    {
        printf(" %d",road[i]);
    }
    printf("\n");
    return 0;
}


#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

int road[2005];
int cnt[2005];

int serch(int m,int num)
{
    int val=1;
    for(int i=1 ; i<=m ; i++)
    {
        if(cnt[i]<num&&cnt[i]<cnt[val])
            val=i;
    }
    return val;
}

int main()
{
    int m,n;
    memset(road,0,sizeof(road));
    memset(cnt,0,sizeof(cnt));
    scanf("%d %d",&n,&m);
    int num=n/m;
    int save=n%m;
    for(int i=0 ; i<n ; i++)
    {
        scanf("%d",&road[i]);
        if(road[i]<=m)
        {
            cnt[road[i]]++;
        }
    }
    int change=0;
    int b=serch(m,num);
    for(int i=0 ; i<n ; i++)
    {
        if(road[i]>m)
        {
            change++;
            road[i]=b;
            cnt[b]++;
            if(cnt[b]>=num+(save>0))
            {
                save--;
                b=serch(m,num+(save>0));
            }
        }
        else if(cnt[road[i]]>num+(save>0))
        {
            change++;
            cnt[road[i]]--;
            road[i]=b;
            cnt[b]++;
            if(cnt[b]>=num+(save>0))
            {
                save--;
                b=serch(m,num+(save>0));
            }
        }
    }
    printf("%d %d\n",num,change);
    printf("%d",road[0]);
    for(int i=1 ; i<n ; i++)
    {
        printf(" %d",road[i]);
    }
    printf("\n");
    return 0;
}


#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

int road[2005];
int cnt[2005];

int serch(int m,int num)
{
    int val=1;
    for(int i=1 ; i<=m ; i++)
    {
        if(cnt[i]<num&&cnt[i]<cnt[val])
            val=i;
    }
    return val;
}

int main()
{
    int m,n;
    memset(road,0,sizeof(road));
    memset(cnt,0,sizeof(cnt));
    scanf("%d %d",&n,&m);
    int num=n/m;
    for(int i=0 ; i<n ; i++)
    {
        scanf("%d",&road[i]);
        if(road[i]<=m)
        {
            cnt[road[i]]++;
        }
    }
    int change=0;
    int b=serch(m,num);
    for(int i=0 ; i<n ; i++)
    {
        if(road[i]>m)
        {
            change++;
            road[i]=b;
            cnt[b]++;
            if(cnt[b]>=num)
            {
                b=serch(m,num);
                if(cnt[b]>=num)
                {
                    b=serch(m,num);
                }
            }
        }
    }
    b=serch(m,num);
    if(cnt[b]<num)
    {
        for(int i=0 ; i<n ; i++)
        {
            if(cnt[road[i]]>num+1)
            {
                cnt[road[i]]--;
                cnt[b]++;
                road[i]=b;
                change++;
                if(cnt[b]>=num)
                {
                    b=serch(m,num);
                }
            }
        }
    }
    b=serch(m,num);
    if(cnt[b]<num)
    {
        for(int i=0 ; i<n ; i++)
        {
            if(cnt[road[i]]>num)
            {
                cnt[road[i]]--;
                cnt[b]++;
                road[i]=b;
                change++;
                if(cnt[b]>=num)
                {
                    b=serch(m,num);
                }
            }
        }
    }

    printf("%d %d\n",num,change);
    printf("%d",road[0]);
    for(int i=1 ; i<n ; i++)
    {
        printf(" %d",road[i]);
    }
    printf("\n");
    return 0;
}