#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
template <typename T>
using vec = vector<T>;
template <typename K, typename V>
using um = unordered_map<K, V>;
template <typename K, typename V>
using om = map<K, V>;
template <typename K>
using us = unordered_set<K>;
template <typename K>
using os = set<K>;
using vi = vec<int>;
using vl = vec<ll>;
using vpi = vec<pii>;
using vpl = vec<pll>;
template <typename T>
inline void maxa(T& st, T v) {
  st = max(st, v);
}
template <typename T>
inline void mina(T& st, T v) {
  st = min(st, v);
}
inline void setprec(ostream& out, int prec) {
  out << setprecision(prec) << fixed;
}
template <typename T>
ostream& operator<<(ostream& out, vector<T> iter) {
  out << "[";
  for (auto t : iter) {
    out << t << ", ";
  }
  out << "]";
  return out;
}
template <typename T>
void debugArray(T* arr, int sz) {
  cout << "[";
  for (int i = 0; i < sz; i++) {
    cout << arr[i] << ", ";
  }
  cout << "]\n";
}
template <typename T>
void printArray(T* arr, int sz) {
  for (int i = 0; i < sz; i++) {
    cout << arr[i] << " ";
  }
  cout << "\n";
}
inline void scan() {}
template <typename F, typename... R>
inline void scan(F& f, R&... r) {
  cin >> f;
  scan(r...);
}
template <typename F>
inline void println(F t) {
  cout << t << '\n';
}
template <typename F, typename... R>
inline void println(F f, R... r) {
  cout << f << " ";
  println(r...);
}
inline void print() {}
template <typename F, typename... R>
inline void print(F f, R... r) {
  cout << f;
  print(r...);
}
int di_;
string dnms_, casttostr_ = ",";
void debug_() { cout << endl; }
template <typename T>
string debug_tostring_(T val) {
  ostringstream os;
  os << val;
  return os.str();
}
string debug_name_(string s, string str_val) {
  string ret = "";
  if (s[0] == ' ') {
    ret += ' ';
    s = s.substr(1);
  }
  if (s[0] == '"' && s[s.length() - 1] == '"') {
    ret += string("[") + str_val + "]";
  } else if (s.length() == (size_t)3 && s[0] == '\'' && s[2] == '\'') {
    ret += '(' + str_val + ')';
  } else {
    ret += s + ": " + str_val;
  }
  return ret;
}
template <typename F, typename... R>
void debug_(F f, R... r) {
  int bc = 0;
  string pr = "";
  while (bc != 0 || dnms_[di_] != ',') {
    if (dnms_[di_] == '(') {
      bc++;
    } else if (dnms_[di_] == ')') {
      bc--;
    }
    pr += dnms_[di_++];
  }
  di_++;
  cout << debug_name_(pr, debug_tostring_(f)) << ",";
  debug_(r...);
}
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
struct pt {
  ll i, x, y;
  bool operator<(const pt& o) const { return x == o.x ? y < o.y : x < o.x; }
};
const int MN = 1e5 + 1;
int n;
pt pts[MN];
pair<ll, ll> slope(int i) {
  ll mn = pts[i + 1].y - pts[i].y;
  ll md = pts[i + 1].x - pts[i].x;
  ll gcdv = gcd(mn, md);
  if (md < 0) {
    md *= -1;
    mn *= -1;
  }
  gcdv = abs(gcdv);
  return make_pair(mn / gcdv, md / gcdv);
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  scan(n);
  for (int i = 0; i < n; i++) {
    scan(pts[i].x, pts[i].y);
    pts[i].i = i + 1;
  }
  sort(pts, pts + n);
  for (int i = 0; i < n - 2; i++) {
    bool work = true;
    if (pts[i].x == pts[i + 1].x && pts[i + 1].x == pts[i + 2].x) {
      continue;
    } else if (pts[i].x == pts[i + 1].x || pts[i + 1].x == pts[i + 2].x) {
      work = true;
    } else {
      work = slope(i) != slope(i + 1);
    }
    if (work) {
      println(pts[i].i, pts[i + 1].i, pts[i + 2].i);
      return 0;
    }
  }
  assert(0);
  return 0;
}
