#include <iostream>
#include <vector>
using namespace std;
// #include "ToyDesign.h"
// vector<vector<int>> secret_ans;
// vector<vector<vector<int>>> levels;
// int Connected(int lvl, int a, int b){
// int x=-1, y=-1;
// for(int i = 0; i<levels[lvl].size(); i++){
// int count = 0;
// for(auto j:levels[lvl][i]) if(j == a || j==b) count++;
// if(count == 0) continue;
// if(count == 2) return lvl;
// if(count == 1){
// if(x == -1) x = i;
// else y = i;
// }
// }
// levels.push_back(levels[lvl]);
// for(auto i : levels.back()[y]) levels.back()[x].push_back(i);
// levels.back()[y].assign(0, 0);
// return levels.size()-1;
// }
// -----------------------------------------------------------------------------------
int Connected(int lvl, int a, int b){
cout<<"? "<<lvl<<' '<<a<<' '<<b<<endl;
int ans; cin>>ans;
return ans;
}
int lastLevel = 0;
vector<int> rep;
struct segTree{
int l; int r;
int leader;
segTree * lc, * rc;
int level;
segTree(int ind){
leader = rep[ind];
l = r = ind;
level = 0;
lc = rc = nullptr;
}
segTree(segTree*le, segTree*ri, int stLevel){
lc = le;
rc = ri;
l = lc->l;
r = rc->r;
leader = lc->leader;
if(stLevel == -1) stLevel = rc->level;
level = Connected(stLevel, lc->leader, rc->leader);
lastLevel++;
}
};
segTree * build(int l, int r, int leftLevel){
int mid = (l+r)/2;
if(l==r) return new segTree(l);
segTree * le = build(l, mid, leftLevel);
segTree * ri = build(mid+1, r, le->level);
return new segTree(le, ri, ((lastLevel == rep.size()-1)?0 : lastLevel));
// else return new segTree(build(l, mid), build(mid+1, r));
}
int query(segTree * st, int nd){
if(st->l == st->r) return st->leader;
if(st->lc->level == Connected(st->lc->level, nd, st->lc->leader)) return query(st->lc, nd);
else return query(st->rc, nd);
}
void ToyDesign(int n, int max_ops){
rep.clear();
rep.push_back(1);
for(int i = 2; i<=n; i++){
int b = Connected(lastLevel, 1, i);
if(b>lastLevel) rep.push_back(i);
lastLevel = b;
}
segTree * seg = build(0, rep.size()-1, -1);
vector<pair<int, int>> ans;
int repind = 0;
for(int i = 1; i<=n; i++){
if(i == rep[repind]){
repind++;
continue;
}
ans.push_back({i, query(seg, i)});
}
cout<<"! "<<ans.size()<<endl;
for(auto i : ans) cout<<i.first<<' '<<i.second<<endl;
}
// int main(void){
// freopen("input.txt", "r", stdin);
// int n1, m1; cin>>n1>>m1;
// secret_ans.assign(m1, {});
// for(int i = 0; i<n1; i++){
// int a, b; cin>>a>>b;
// secret_ans[a].push_back(b);
// }
// levels.push_back(secret_ans);
// ToyDesign(n1, 10000);
// }
int main(void){
int n, maxq;
cin>>n;
ToyDesign(n, 0);
return 0;
}