#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <list>
#include <vector>
#include <utility>
#include <queue>
#include <cmath>
#include <set>
#include <algorithm>
#include <unordered_map>

using namespace std;

#define MAX_SIZE 32
#define MAX_I MAX_SIZE - 1
#define pLL *(unsigned long long *)
#define tLL (unsigned long long)

class bigInt {

   unsigned int pInt[MAX_SIZE];
   int size;
   char sign;

public:

   bigInt() {
      memset(pInt, 0, MAX_SIZE);
      size = 0;
      sign = 1;
   }

   bigInt(long long x) {
      *this = x;
   }

   inline bigInt& operator=(long long x) {
      memset(pInt, 0, MAX_SIZE);
      if (x < 0) {
         x = ~x + 1;
         sign = -1;
      }
      else {
         sign = 1;
      }
      pLL pInt = x;
      if (x == 0) size = 0;
      else if (pInt[1] == 0) {
         size = 1;
      }
      else {
         size = 2;
      }
      return *this;
   }

   friend bigInt operator+(bigInt lhs, bigInt rhs);
   friend bigInt operator-(bigInt lhs, bigInt rhs);
   friend bigInt operator*(bigInt lhs, bigInt rhs);
   friend bigInt abs(bigInt x);

   inline bool operator<(const bigInt& other) {
      if (sign < other.sign) return true;
      if (sign > other.sign) return false;
      if (size < other.size) return true;
      if (size > other.size) return false;
      for (int i = 0; i < size; i++) {
         if (pInt[i] < other.pInt[i]) return true;
         if (pInt[i] > other.pInt[i]) return false;
      }
      return false;
   }

   inline bool operator>(const bigInt& other) {
      if (sign < other.sign) return false;
      if (sign > other.sign) return true;
      if (size < other.size) return false;
      if (size > other.size) return true;
      for (int i = 0; i < size; i++) {
         if (pInt[i] < other.pInt[i]) return false;
         if (pInt[i] > other.pInt[i]) return true;
      }
      return false;

   }

   inline bool operator==(const bigInt& other) {
      if (sign != other.sign) return false;
      if (size != other.size) return false;
      for (int i = 0; i < size; i++) {
         if (pInt[i] != other.pInt[i]) return false;
      }
      return true;
   }
};

bigInt abs(bigInt x) {
   x.sign = 1;
   return x;
}

inline bigInt operator+(bigInt lhs, bigInt rhs) {
   bigInt res;
   if (lhs.sign == rhs.sign) {
      int maxsize = (lhs.size > rhs.size ? lhs.size : rhs.size);
      for (int i = 0; i < maxsize; i++) {
         pLL(res.pInt + i) += tLL lhs.pInt[i] + tLL rhs.pInt[i];
      }
      if (res.pInt[maxsize] != 0) res.size = maxsize + 1;
      else res.size = maxsize;
      res.sign = lhs.sign;
   }
   else {
      char lsign = lhs.sign, rsign = rhs.sign;
      lhs.sign = rhs.sign = 1;
      if (lhs == rhs) return res;
      bigInt *pbs, *pls;
      if (lhs < rhs) {
         res.sign = rsign;
         pbs = &rhs;
         pls = &lhs;
      }
      else {
         res.sign = lsign;
         pbs = &lhs;
         pls = &rhs;
      }
      int maxsize = pbs->size;
      for (int i = 0; i < maxsize; i++) {
         pLL(res.pInt + i) += tLL pbs->pInt[i] - tLL pls->pInt[i];
      }
      for (int i = maxsize - 1; i >= 0; --i) {
         if (res.pInt[i] != 0) {
            res.size = i + 1;
            break;
         }
      }
   }
   return res;
}

inline bigInt operator-(bigInt lhs, bigInt rhs) {
   if (rhs.size == 0) return lhs;
   rhs.sign *= -1;
   return lhs + rhs;
}

inline bigInt operator*(bigInt lhs, bigInt rhs) {
   bigInt res;
   if (lhs.size == 0 || rhs.size == 0) return res;
   int maxsize = lhs.size + rhs.size;
   for (int i = 0; i < lhs.size; i++) {
      bigInt tmp;
      for (int j = 0; j < rhs.size; j++) {
         pLL(tmp.pInt + i + j) = tLL lhs.pInt[i] * tLL rhs.pInt[j];
      }
      for (int k = maxsize - 1; k >= 0; --k) {
         if (tmp.pInt[k] != 0) {
            tmp.size = k + 1;
            break;
         }
      }
      res = res + tmp;
   }
   for (int k = maxsize - 1; k >= 0; --k) {
      if (res.pInt[k] != 0) {
         res.size = k + 1;
         break;
      }
   }
   return res;
}

bigInt xs[100000], ys[100000];

int main() {
   int n;
   cin >> n;
   int min1 = 0, min2 = 1;
   for (int i = 0; i < n; i++) {
      int x, y;
      cin >> x >> y;
      ys[i] = y;
      xs[i] = x;
   }
   bigInt mindist = ~(1LL << 63);
   for (int i = 1; i < n; i++) {
      bigInt dist = ((xs[i] - xs[0]) * (xs[i] - xs[0])) + ((ys[i] - ys[0]) * (ys[i] - ys[0]));
      if (dist < mindist) {
         mindist = dist;
         min2 = i;
      }
   }
   int mini = 0;
   bigInt a = ys[min2] - ys[min1];
   bigInt b = xs[min1] - xs[min2];
   bigInt x = (a * xs[min1]);
   bigInt y = (b * ys[min1]);
   bigInt c = bigInt(0) - (a * xs[min1]) - (b * ys[min1]);
   mindist = ~(1LL << 63);
   for (int i = 1; i < n; i++) {
      bigInt dist = abs(a * xs[i] + b * ys[i] + c);
      if (!(dist == bigInt(0)) && dist < mindist) {
         mindist = dist;
         mini = i;
      }
   }

   cout << min1 + 1 << ' ' << min2 + 1 << ' ' << mini + 1 << endl;

   return 0;
}


#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <list>
#include <vector>
#include <utility>
#include <queue>
#include <cmath>
#include <set>
#include <algorithm>
#include <unordered_map>

using namespace std;

#define MAX_SIZE 32
#define MAX_I MAX_SIZE - 1
#define pLL *(unsigned long long *)
#define tLL (unsigned long long)

class bigInt {
   union {
      unsigned int pInt[MAX_SIZE];
      unsigned long long p_LL[MAX_SIZE / 2];
   };
   int size;
   char sign;

public:

   bigInt() {
      memset(pInt, 0, MAX_SIZE * sizeof(unsigned int));
      size = 0;
      sign = 1;
   }

   bigInt(long long x) {
      *this = x;
   }

   bigInt(const bigInt& x) {
      *this = x;
   }

   inline bigInt& operator=(const bigInt& x) {
      memcpy(this, &x, sizeof(bigInt));
      return *this;
   }

   inline bigInt& operator=(long long x) {
      memset(pInt, 0, MAX_SIZE * sizeof(unsigned int));
      if (x < 0) {
         x = ~x + 1;
         sign = -1;
      }
      else {
         sign = 1;
      }
      pLL pInt = x;
      if (x == 0) size = 0;
      else if (pInt[1] == 0) {
         size = 1;
      }
      else {
         size = 2;
      }
      return *this;
   }

   friend bigInt operator+(bigInt lhs, bigInt rhs);
   friend bigInt operator-(bigInt lhs, bigInt rhs);
   friend bigInt operator*(bigInt lhs, bigInt rhs);
   friend bigInt abs(bigInt x);

   inline bool operator<(const bigInt& other) {
      if (sign < other.sign) return true;
      if (sign > other.sign) return false;
      if (size < other.size) return true;
      if (size > other.size) return false;
      for (int i = size - 1; i >= 0; --i) {
         if (pInt[i] < other.pInt[i]) return true;
         if (pInt[i] > other.pInt[i]) return false;
      }
      return false;
   }

   inline bool operator>(const bigInt& other) {
      if (sign < other.sign) return false;
      if (sign > other.sign) return true;
      if (size < other.size) return false;
      if (size > other.size) return true;
      for (int i = size - 1; i >= 0; --i) {
         if (pInt[i] < other.pInt[i]) return false;
         if (pInt[i] > other.pInt[i]) return true;
      }
      return false;

   }

   inline bool operator==(const bigInt& other) {
      if (sign != other.sign) return false;
      if (size != other.size) return false;
      for (int i = 0; i < size; i++) {
         if (pInt[i] != other.pInt[i]) return false;
      }
      return true;
   }
};

bigInt abs(bigInt x) {
   x.sign = 1;
   return x;
}

inline bigInt operator+(bigInt lhs, bigInt rhs) {
   bigInt res;
   if (lhs.sign == rhs.sign) {
      int maxsize = (lhs.size > rhs.size ? lhs.size : rhs.size);
      for (int i = 0; i < maxsize; i++) {
         pLL(res.pInt + i) += tLL lhs.pInt[i] + tLL rhs.pInt[i];
      }
      if (res.pInt[maxsize] != 0) res.size = maxsize + 1;
      else res.size = maxsize;
      res.sign = lhs.sign;
   }
   else {
      char lsign = lhs.sign, rsign = rhs.sign;
      lhs.sign = rhs.sign = 1;
      if (lhs == rhs) return res;
      bigInt *pbs, *pls;
      if (lhs < rhs) {
         res.sign = rsign;
         pbs = &rhs;
         pls = &lhs;
      }
      else {
         res.sign = lsign;
         pbs = &lhs;
         pls = &rhs;
      }
      int maxsize = pbs->size;
      for (int i = 0; i < maxsize; i++) {
         pLL(res.pInt + i) += tLL pbs->pInt[i] - tLL pls->pInt[i];
      }
      for (int i = maxsize - 1; i >= 0; --i) {
         if (res.pInt[i] != 0) {
            res.size = i + 1;
            break;
         }
      }
   }
   return res;
}

inline bigInt operator-(bigInt lhs, bigInt rhs) {
   if (rhs.size == 0) return lhs;
   rhs.sign *= -1;
   return lhs + rhs;
}

inline bigInt operator*(bigInt lhs, bigInt rhs) {
   bigInt res;
   if (lhs.size == 0 || rhs.size == 0) return res;
   int maxsize = lhs.size + rhs.size;
   for (int i = 0; i < lhs.size; i++) {
      bigInt tmp;
      for (int j = 0; j < rhs.size; j++) {
         pLL(tmp.pInt + i + j) = tLL lhs.pInt[i] * tLL rhs.pInt[j];
      }
      for (int k = maxsize - 1; k >= 0; --k) {
         if (tmp.pInt[k] != 0) {
            tmp.size = k + 1;
            break;
         }
      }
      res = res + tmp;
   }
   for (int k = maxsize - 1; k >= 0; --k) {
      if (res.pInt[k] != 0) {
         res.size = k + 1;
         break;
      }
   }
   res.sign = lhs.sign * rhs.sign;
   return res;
}

#define inttouse bigInt

inttouse xs[100000], ys[100000];

int main() {
   int n;
   scanf("%d", &n);
   int min1 = 0, min2 = 1;
   for (int i = 0; i < n; i++) {
      long long x, y;
      scanf("%I64d%I64d", &x, &y);
      ys[i] = y;
      xs[i] = x;
   }
   inttouse mindist = ~(1LL << 63);
   for (int i = 2; i < n; i++) {
      inttouse dist = ((xs[i] - xs[0]) * (xs[i] - xs[0])) + ((ys[i] - ys[0]) * (ys[i] - ys[0]));
      if (dist < mindist) {
         mindist = dist;
         min2 = i;
      }
   }
   int mini = 0;
   inttouse a = ys[min2] - ys[min1];
   inttouse b = xs[min1] - xs[min2];
   inttouse c = inttouse(0) - (a * xs[min1]) - (b * ys[min1]);
   mindist = ~(1LL << 63);
   for (int i = 1; i < n; i++) {
      inttouse dist = abs(a * xs[i] + b * ys[i] + c);
      if (!(dist == inttouse(0)) && dist < mindist) {
         mindist = dist;
         mini = i;
      }
   }

   printf("%d %d %d\n", min1 + 1, min2 + 1, mini + 1);

   return 0;
}


#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <list>
#include <vector>
#include <utility>
#include <queue>
#include <cmath>
#include <set>
#include <algorithm>
#include <unordered_map>

using namespace std;

#define MAX_I MAX_SIZE - 1
#define pLL *(unsigned long long *)
#define tLL (unsigned long long)

template<int MAX_SIZE = 32>
class bigInt {

   unsigned int pInt[MAX_SIZE];
   int size;
   char sign;

public:

   inline bigInt() {
      memset(pInt, 0, MAX_SIZE * sizeof(unsigned int));
      size = 0;
      sign = 1;
   }

   inline bigInt(long long x) {
      *this = x;
   }

   inline bigInt(const bigInt& x) {
      *this = x;
   }

   inline bigInt& operator=(const bigInt& x) {
      memcpy(this, &x, sizeof(bigInt));
      return *this;
   }

   inline bigInt& operator=(long long x) {
      memset(pInt, 0, MAX_SIZE * sizeof(unsigned int));
      if (x < 0) {
         x = ~x + 1;
         sign = -1;
      }
      else {
         sign = 1;
      }
      pLL pInt = x;
      if (x == 0) size = 0;
      else if (pInt[1] == 0) {
         size = 1;
      }
      else {
         size = 2;
      }
      return *this;
   }

   inline friend bigInt operator+(bigInt lhs, bigInt rhs) {
      bigInt res;
      if (lhs.sign == rhs.sign) {
         int maxsize = (lhs.size > rhs.size ? lhs.size : rhs.size);
         for (int i = 0; i < maxsize; i++) {
            pLL(res.pInt + i) += tLL lhs.pInt[i] + tLL rhs.pInt[i];
         }
         if (res.pInt[maxsize] != 0) res.size = maxsize + 1;
         else res.size = maxsize;
         res.sign = lhs.sign;
      }
      else {
         char lsign = lhs.sign, rsign = rhs.sign;
         lhs.sign = rhs.sign = 1;
         if (lhs == rhs) return res;
         bigInt *pbs, *pls;
         if (lhs < rhs) {
            res.sign = rsign;
            pbs = &rhs;
            pls = &lhs;
         }
         else {
            res.sign = lsign;
            pbs = &lhs;
            pls = &rhs;
         }
         int maxsize = pbs->size;
         for (int i = 0; i < maxsize; i++) {
            pLL(res.pInt + i) += tLL pbs->pInt[i] - tLL pls->pInt[i];
         }
         for (int i = maxsize - 1; i >= 0; --i) {
            if (res.pInt[i] != 0) {
               res.size = i + 1;
               break;
            }
         }
      }
      return res;
   }

   inline friend bigInt operator-(bigInt lhs, bigInt rhs) {
      if (rhs.size == 0) return lhs;
      rhs.sign *= -1;
      return lhs + rhs;
   }

   inline friend bigInt operator*(bigInt lhs, bigInt rhs) {
      bigInt res;
      if (lhs.size == 0 || rhs.size == 0) return res;
      int maxsize = lhs.size + rhs.size;
      for (int i = 0; i < lhs.size; i++) {
         bigInt tmp;
         for (int j = 0; j < rhs.size; j++) {
            pLL(tmp.pInt + i + j) = tLL lhs.pInt[i] * tLL rhs.pInt[j];
         }
         for (int k = maxsize - 1; k >= 0; --k) {
            if (tmp.pInt[k] != 0) {
               tmp.size = k + 1;
               break;
            }
         }
         res = res + tmp;
      }
      for (int k = maxsize - 1; k >= 0; --k) {
         if (res.pInt[k] != 0) {
            res.size = k + 1;
            break;
         }
      }
      res.sign = lhs.sign * rhs.sign;
      return res;
   }

   inline friend bigInt abs(bigInt x) {
      x.sign = 1;
      return x;
   }

   inline bool operator<(const bigInt& other) {
      if (sign < other.sign) return true;
      if (sign > other.sign) return false;
      if (size < other.size) return true;
      if (size > other.size) return false;
      for (int i = size - 1; i >= 0; --i) {
         if (pInt[i] < other.pInt[i]) return true;
         if (pInt[i] > other.pInt[i]) return false;
      }
      return false;
   }

   inline bool operator<=(const bigInt& other) {
      return !(*this > other);
   }

   inline bool operator>(const bigInt& other) {
      if (sign < other.sign) return false;
      if (sign > other.sign) return true;
      if (size < other.size) return false;
      if (size > other.size) return true;
      for (int i = size - 1; i >= 0; --i) {
         if (pInt[i] < other.pInt[i]) return false;
         if (pInt[i] > other.pInt[i]) return true;
      }
      return false;
   }

   inline bool operator>=(const bigInt& other) {
      return !(*this < other);
   }

   inline bool operator==(const bigInt& other) {
      if (sign != other.sign) return false;
      if (size != other.size) return false;
      for (int i = 0; i < size; i++) {
         if (pInt[i] != other.pInt[i]) return false;
      }
      return true;
   }

   inline bool operator!=(const bigInt& other) {
      return !(*this == other);
   }
};

#undef MAX_I
#undef pLL
#undef tLL

#define inttouse bigInt<>

inttouse xs[100000], ys[100000];

int main() {
   int n;
   scanf("%d", &n);
   int min1 = 0, min2 = 1;
   for (int i = 0; i < n; i++) {
      long long x, y;
      scanf("%I64d%I64d", &x, &y);
      ys[i] = y;
      xs[i] = x;
   }
   inttouse mindist = ~(1LL << 63);
   for (int i = 1; i < n; i++) {
      inttouse dist = ((xs[i] - xs[0]) * (xs[i] - xs[0])) + ((ys[i] - ys[0]) * (ys[i] - ys[0]));
      if (dist < mindist) {
         mindist = dist;
         min2 = i;
      }
   }
   int mini = 0;
   inttouse a = ys[min2] - ys[min1];
   inttouse b = xs[min1] - xs[min2];
   inttouse c = inttouse(0) - (a * xs[min1]) - (b * ys[min1]);
   mindist = ~(1LL << 63);
   for (int i = 1; i < n; i++) {
      inttouse dist = abs(a * xs[i] + b * ys[i] + c);
      if (!(dist == inttouse(0)) && dist < mindist) {
         mindist = dist;
         mini = i;
      }
   }

   printf("%d %d %d\n", min1 + 1, min2 + 1, mini + 1);

   return 0;
}


#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <list>
#include <vector>
#include <utility>
#include <queue>
#include <cmath>
#include <set>
#include <algorithm>
#include <unordered_map>

using namespace std;

int main() {
   int n;
   cin >> n;
   int xs[100000], ys[100000];
   int min1 = 0, min2 = 1;
   cin >> xs[0] >> ys[0];
   cin >> xs[1] >> ys[1];
   if (xs[0] > xs[1]) {
      min1 = 1; min2 = 0;
   }
   else if (xs[0] == xs[1]) {
      if (ys[0] > ys[1]) {
         min1 = 1; min2 = 0;
      }
   }
   for (int i = 2; i < n; i++) {
      cin >> xs[i] >> ys[i];
      if (xs[i] < xs[min1]) {
         min2 = min1;
         min1 = i;
      }
      else if (xs[i] == xs[min1]) {
         if (ys[i] <= ys[min1]) {
            min2 = min1;
            min1 = i;
         }
      }
      else if (xs[i] < xs[min2]) {
         min2 = i;
      }
      else if (xs[i] == xs[min2]) {
         if (ys[i] <= ys[min2]) {
            min2 = i;
         }
      }
   }
   int mini = 0;
   if (xs[min1] == xs[min2]) {
      int mindist = 1000000001;
      for (int i = 0; i < n; i++) {
         int dist = abs(xs[i] - xs[min1]);
         if (dist > 0 && dist < mindist) {
            mindist = dist;
            mini = i;
         }
      }
   }
   else {
      if (xs[min1] > xs[min2]) {
         swap(min1, min2);
      }
      long double a = (ys[min2] - ys[min1]) / (xs[min2] - xs[min1]);
      long double b = ys[min1] - (a * xs[min1]);
      long double mindist = 10e90L;
      for (int i = 0; i < n; i++) {
         long double dist = abs(a * xs[i] - ys[i] + b) / sqrt(a * a + 1);
         if (dist > 0.000001 && dist < mindist) {
            mindist = dist;
            mini = i;
         }
      }
   }

   cout << min1 + 1 << min2 + 1 << mini + 1 << endl;

   return 0;
}


#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <list>
#include <vector>
#include <utility>
#include <queue>
#include <cmath>
#include <set>
#include <algorithm>
#include <unordered_map>

using namespace std;

int main() {
   int n;
   cin >> n;
   int xs[100000], ys[100000];
   int min1 = 0, min2;
   for (int i = 0; i < n; i++) {
      cin >> xs[i] >> ys[i];
   }
   unsigned long long mindist = 18446744073709551615LL;
   for (int i = 1; i < n; i++) {
      unsigned long long dist = ((xs[i] - xs[0]) * (xs[i] - xs[0])) + ((ys[i] - ys[0]) * (ys[i] - ys[0]));
      if (dist < mindist) {
         mindist = dist;
         min2 = i;
      }
   }
   int mini = 0;
   long long a = ys[min2] - ys[min1];
   long long b = xs[min1] - xs[min2];
   long long c = 0 - (a * xs[min1]) - (b * ys[min1]);
   mindist = 18446744073709551615LL;
   for (int i = 1; i < n; i++) {
      unsigned long long dist = abs(a * xs[i] + b * ys[i] + c);
      if (dist > 0 && dist < mindist) {
         mindist = dist;
         mini = i;
      }
   }

   cout << min1 + 1 << ' ' << min2 + 1 << ' ' << mini + 1 << endl;

   return 0;
}


#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <list>
#include <vector>
#include <utility>
#include <queue>
#include <cmath>
#include <set>
#include <algorithm>
#include <unordered_map>

using namespace std;

#define MAX_SIZE 32
#define MAX_I MAX_SIZE - 1
#define pLL *(unsigned long long *)
#define tLL (unsigned long long)

class bigInt {
   union {
      unsigned int pInt[MAX_SIZE];
      unsigned long long p_LL[MAX_SIZE / 2];
   };
   int size;
   char sign;

public:

   bigInt() {
      memset(pInt, 0, MAX_SIZE * sizeof(unsigned int));
      size = 0;
      sign = 1;
   }

   bigInt(long long x) {
      *this = x;
   }

   bigInt(const bigInt& x) {
      *this = x;
   }

   inline bigInt& operator=(const bigInt& x) {
      memcpy(this, &x, sizeof(bigInt));
      return *this;
   }

   inline bigInt& operator=(long long x) {
      memset(pInt, 0, MAX_SIZE * sizeof(unsigned int));
      if (x < 0) {
         x = ~x + 1;
         sign = -1;
      }
      else {
         sign = 1;
      }
      pLL pInt = x;
      if (x == 0) size = 0;
      else if (pInt[1] == 0) {
         size = 1;
      }
      else {
         size = 2;
      }
      return *this;
   }

   friend bigInt operator+(bigInt lhs, bigInt rhs);
   friend bigInt operator-(bigInt lhs, bigInt rhs);
   friend bigInt operator*(bigInt lhs, bigInt rhs);
   friend bigInt abs(bigInt x);

   inline bool operator<(const bigInt& other) {
      if (sign < other.sign) return true;
      if (sign > other.sign) return false;
      if (size < other.size) return true;
      if (size > other.size) return false;
      for (int i = size - 1; i >= 0; --i) {
         if (pInt[i] < other.pInt[i]) return true;
         if (pInt[i] > other.pInt[i]) return false;
      }
      return false;
   }

   inline bool operator>(const bigInt& other) {
      if (sign < other.sign) return false;
      if (sign > other.sign) return true;
      if (size < other.size) return false;
      if (size > other.size) return true;
      for (int i = size - 1; i >= 0; --i) {
         if (pInt[i] < other.pInt[i]) return false;
         if (pInt[i] > other.pInt[i]) return true;
      }
      return false;

   }

   inline bool operator==(const bigInt& other) {
      if (sign != other.sign) return false;
      if (size != other.size) return false;
      for (int i = 0; i < size; i++) {
         if (pInt[i] != other.pInt[i]) return false;
      }
      return true;
   }
};

bigInt abs(bigInt x) {
   x.sign = 1;
   return x;
}

inline bigInt operator+(bigInt lhs, bigInt rhs) {
   bigInt res;
   if (lhs.sign == rhs.sign) {
      int maxsize = (lhs.size > rhs.size ? lhs.size : rhs.size);
      for (int i = 0; i < maxsize; i++) {
         pLL(res.pInt + i) += tLL lhs.pInt[i] + tLL rhs.pInt[i];
      }
      if (res.pInt[maxsize] != 0) res.size = maxsize + 1;
      else res.size = maxsize;
      res.sign = lhs.sign;
   }
   else {
      char lsign = lhs.sign, rsign = rhs.sign;
      lhs.sign = rhs.sign = 1;
      if (lhs == rhs) return res;
      bigInt *pbs, *pls;
      if (lhs < rhs) {
         res.sign = rsign;
         pbs = &rhs;
         pls = &lhs;
      }
      else {
         res.sign = lsign;
         pbs = &lhs;
         pls = &rhs;
      }
      int maxsize = pbs->size;
      for (int i = 0; i < maxsize; i++) {
         pLL(res.pInt + i) += tLL pbs->pInt[i] - tLL pls->pInt[i];
      }
      for (int i = maxsize - 1; i >= 0; --i) {
         if (res.pInt[i] != 0) {
            res.size = i + 1;
            break;
         }
      }
   }
   return res;
}

inline bigInt operator-(bigInt lhs, bigInt rhs) {
   if (rhs.size == 0) return lhs;
   rhs.sign *= -1;
   return lhs + rhs;
}

inline bigInt operator*(bigInt lhs, bigInt rhs) {
   bigInt res;
   if (lhs.size == 0 || rhs.size == 0) return res;
   int maxsize = lhs.size + rhs.size;
   for (int i = 0; i < lhs.size; i++) {
      bigInt tmp;
      for (int j = 0; j < rhs.size; j++) {
         pLL(tmp.pInt + i + j) = tLL lhs.pInt[i] * tLL rhs.pInt[j];
      }
      for (int k = maxsize - 1; k >= 0; --k) {
         if (tmp.pInt[k] != 0) {
            tmp.size = k + 1;
            break;
         }
      }
      res = res + tmp;
   }
   for (int k = maxsize - 1; k >= 0; --k) {
      if (res.pInt[k] != 0) {
         res.size = k + 1;
         break;
      }
   }
   res.sign = lhs.sign * rhs.sign;
   return res;
}

#define inttouse bigInt

inttouse xs[100000], ys[100000];

int main() {
   int n;
   cin >> n;
   int min1 = 0, min2 = 1;
   for (int i = 0; i < n; i++) {
      int x, y;
      cin >> x >> y;
      ys[i] = y;
      xs[i] = x;
   }
   inttouse mindist = ~(1LL << 63);
   for (int i = 1; i < n; i++) {
      inttouse dist = ((xs[i] - xs[0]) * (xs[i] - xs[0])) + ((ys[i] - ys[0]) * (ys[i] - ys[0]));
      if (dist < mindist) {
         mindist = dist;
         min2 = i;
      }
   }
   int mini = 0;
   inttouse a = ys[min2] - ys[min1];
   inttouse b = xs[min1] - xs[min2];
   inttouse c = inttouse(0) - (a * xs[min1]) - (b * ys[min1]);
   mindist = ~(1LL << 63);
   for (int i = 1; i < n; i++) {
      inttouse dist = abs(a * xs[i] + b * ys[i] + c);
      if (!(dist == inttouse(0)) && dist < mindist) {
         mindist = dist;
         mini = i;
      }
   }

   cout << min1 + 1 << ' ' << min2 + 1 << ' ' << mini + 1 << endl;

   return 0;
}


#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <list>
#include <vector>
#include <utility>
#include <queue>
#include <cmath>
#include <set>
#include <algorithm>
#include <unordered_map>

using namespace std;

int main() {
   int n;
   cin >> n;
   int xs[100000], ys[100000];
   int min1 = 0, min2 = 1;
   cin >> xs[0] >> ys[0];
   cin >> xs[1] >> ys[1];
   if (xs[0] > xs[1]) {
      min1 = 1; min2 = 0;
   }
   else if (xs[0] == xs[1]) {
      if (ys[0] > ys[1]) {
         min1 = 1; min2 = 0;
      }
   }
   for (int i = 2; i < n; i++) {
      cin >> xs[i] >> ys[i];
      if (xs[i] < xs[min1]) {
         min2 = min1;
         min1 = i;
      }
      else if (xs[i] == xs[min1]) {
         if (ys[i] <= ys[min1]) {
            min2 = min1;
            min1 = i;
         }
      }
      else if (xs[i] < xs[min2]) {
         min2 = i;
      }
      else if (xs[i] == xs[min2]) {
         if (ys[i] <= ys[min2]) {
            min2 = i;
         }
      }
   }
   int mini = 0;
   if (xs[min1] == xs[min2]) {
      int mindist = 1000000001;
      for (int i = 0; i < n; i++) {
         int dist = abs(xs[i] - xs[min1]);
         if (dist > 0 && dist < mindist) {
            mindist = dist;
            mini = i;
         }
      }
   }
   else if (ys[min1] == ys[min2]) {
      int mindist = 1000000001;
      for (int i = 0; i < n; i++) {
         int dist = abs(ys[i] - ys[min1]);
         if (dist > 0 && dist < mindist) {
            mindist = dist;
            mini = i;
         }
      }
   }
   else {
      long long a = ys[min2] - ys[min1];
      long long b = xs[min1] - xs[min2];
      long long c = 0 - (a * xs[min1]) - (b * ys[min1]);
      long long mindist = 2LL * 2000000000LL * 2000000000LL + 1LL;
      for (int i = 0; i < n; i++) {
         if (i == min1 || i == min2) continue;
         long long dist = abs(a * xs[i] + b * ys[i] + c);
         if (dist > 0 && dist < mindist) {
            mindist = dist;
            mini = i;
         }
      }
   }

   cout << min1 + 1 << min2 + 1 << mini + 1 << endl;

   return 0;
}


#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <list>
#include <vector>
#include <utility>
#include <queue>
#include <cmath>
#include <set>
#include <algorithm>
#include <unordered_map>

using namespace std;

#define MAX_SIZE 32
#define MAX_I MAX_SIZE - 1
#define pLL *(unsigned long long *)
#define tLL (unsigned long long)

class bigInt {
   union {
      unsigned int pInt[MAX_SIZE];
      unsigned long long p_LL[MAX_SIZE / 2];
   };
   int size;
   char sign;

public:

   bigInt() {
      memset(pInt, 0, MAX_SIZE * sizeof(unsigned int));
      size = 0;
      sign = 1;
   }

   bigInt(long long x) {
      *this = x;
   }

   bigInt(const bigInt& x) {
      *this = x;
   }

   inline bigInt& operator=(const bigInt& x) {
      memcpy(this, &x, sizeof(bigInt));
      return *this;
   }

   inline bigInt& operator=(long long x) {
      memset(pInt, 0, MAX_SIZE * sizeof(unsigned int));
      if (x < 0) {
         x = ~x + 1;
         sign = -1;
      }
      else {
         sign = 1;
      }
      pLL pInt = x;
      if (x == 0) size = 0;
      else if (pInt[1] == 0) {
         size = 1;
      }
      else {
         size = 2;
      }
      return *this;
   }

   friend bigInt operator+(bigInt lhs, bigInt rhs);
   friend bigInt operator-(bigInt lhs, bigInt rhs);
   friend bigInt operator*(bigInt lhs, bigInt rhs);
   friend bigInt abs(bigInt x);

   inline bool operator<(const bigInt& other) {
      if (sign < other.sign) return true;
      if (sign > other.sign) return false;
      if (size < other.size) return true;
      if (size > other.size) return false;
      for (int i = size - 1; i >= 0; --i) {
         if (pInt[i] < other.pInt[i]) return true;
         if (pInt[i] > other.pInt[i]) return false;
      }
      return false;
   }

   inline bool operator>(const bigInt& other) {
      if (sign < other.sign) return false;
      if (sign > other.sign) return true;
      if (size < other.size) return false;
      if (size > other.size) return true;
      for (int i = size - 1; i >= 0; --i) {
         if (pInt[i] < other.pInt[i]) return false;
         if (pInt[i] > other.pInt[i]) return true;
      }
      return false;

   }

   inline bool operator==(const bigInt& other) {
      if (sign != other.sign) return false;
      if (size != other.size) return false;
      for (int i = 0; i < size; i++) {
         if (pInt[i] != other.pInt[i]) return false;
      }
      return true;
   }
};

bigInt abs(bigInt x) {
   x.sign = 1;
   return x;
}

inline bigInt operator+(bigInt lhs, bigInt rhs) {
   bigInt res;
   if (lhs.sign == rhs.sign) {
      int maxsize = (lhs.size > rhs.size ? lhs.size : rhs.size);
      for (int i = 0; i < maxsize; i++) {
         pLL(res.pInt + i) += tLL lhs.pInt[i] + tLL rhs.pInt[i];
      }
      if (res.pInt[maxsize] != 0) res.size = maxsize + 1;
      else res.size = maxsize;
      res.sign = lhs.sign;
   }
   else {
      char lsign = lhs.sign, rsign = rhs.sign;
      lhs.sign = rhs.sign = 1;
      if (lhs == rhs) return res;
      bigInt *pbs, *pls;
      if (lhs < rhs) {
         res.sign = rsign;
         pbs = &rhs;
         pls = &lhs;
      }
      else {
         res.sign = lsign;
         pbs = &lhs;
         pls = &rhs;
      }
      int maxsize = pbs->size;
      for (int i = 0; i < maxsize; i++) {
         pLL(res.pInt + i) += tLL pbs->pInt[i] - tLL pls->pInt[i];
      }
      for (int i = maxsize - 1; i >= 0; --i) {
         if (res.pInt[i] != 0) {
            res.size = i + 1;
            break;
         }
      }
   }
   return res;
}

inline bigInt operator-(bigInt lhs, bigInt rhs) {
   if (rhs.size == 0) return lhs;
   rhs.sign *= -1;
   return lhs + rhs;
}

inline bigInt operator*(bigInt lhs, bigInt rhs) {
   bigInt res;
   if (lhs.size == 0 || rhs.size == 0) return res;
   int maxsize = lhs.size + rhs.size;
   for (int i = 0; i < lhs.size; i++) {
      bigInt tmp;
      for (int j = 0; j < rhs.size; j++) {
         pLL(tmp.pInt + i + j) = tLL lhs.pInt[i] * tLL rhs.pInt[j];
      }
      for (int k = maxsize - 1; k >= 0; --k) {
         if (tmp.pInt[k] != 0) {
            tmp.size = k + 1;
            break;
         }
      }
      res = res + tmp;
   }
   for (int k = maxsize - 1; k >= 0; --k) {
      if (res.pInt[k] != 0) {
         res.size = k + 1;
         break;
      }
   }
   return res;
}

#define inttouse bigInt

inttouse xs[100000], ys[100000];

int main() {
   int n;
   cin >> n;
   int min1 = 0, min2 = 1;
   for (int i = 0; i < n; i++) {
      int x, y;
      cin >> x >> y;
      ys[i] = y;
      xs[i] = x;
   }
   inttouse mindist = ~(1LL << 63);
   for (int i = 1; i < n; i++) {
      inttouse dist = ((xs[i] - xs[0]) * (xs[i] - xs[0])) + ((ys[i] - ys[0]) * (ys[i] - ys[0]));
      if (dist < mindist) {
         mindist = dist;
         min2 = i;
      }
   }
   int mini = 0;
   inttouse a = ys[min2] - ys[min1];
   inttouse b = xs[min1] - xs[min2];
   inttouse c = inttouse(0) - (a * xs[min1]) - (b * ys[min1]);
   mindist = ~(1LL << 63);
   for (int i = 1; i < n; i++) {
      inttouse dist = abs(a * xs[i] + b * ys[i] + c);
      if (!(dist == inttouse(0)) && dist < mindist) {
         mindist = dist;
         mini = i;
      }
   }

   cout << min1 + 1 << ' ' << min2 + 1 << ' ' << mini + 1 << endl;

   return 0;
}


#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <list>
#include <vector>
#include <utility>
#include <queue>
#include <cmath>
#include <set>
#include <algorithm>
#include <unordered_map>

using namespace std;

#define pLL(x) *(unsigned long long*)(pInt + x)
#define respLL(x) *(unsigned long long*)(res.pInt + x)
#define tmppLL(x) *(unsigned long long*)(tmp.pInt + x)
#define tLL (unsigned long long)
#define MAX_SIZE 8
#define LAST_I MAX_SIZE - 1

class bigInt {
   union {
      unsigned int pInt[MAX_SIZE];
      unsigned long long pLL[MAX_SIZE / 2];
      unsigned char pByte[MAX_SIZE * 4];
   };
   int size;
   char sign;

public:

   bigInt() {
      size = 0;
      memset(pInt, 0, MAX_SIZE * sizeof(unsigned int));
   }

   bigInt(long long x) {
      *this = x;
   }

   inline bigInt& operator=(long long x) {
      memset(pInt, 0, MAX_SIZE * sizeof(unsigned int));
      if (x < 0) {
         sign = -1;
         x = ~x + 1;
      }
      else {
         sign = 1;
      }
      size = 0;
      for (int i = 63; i >= 0; --i) {
         if (x & (1LL < i)) {
            size = 64 - i;
            break;
         }
      }
      x = (x << 32) + (x >> 32);
      pLL(LAST_I - 1) = x;
      return *this;
   }

   friend const bigInt operator+(const bigInt lhs, const bigInt rhs);
   friend const bigInt operator-(const bigInt lhs, const bigInt rhs);
   friend const bigInt operator*(const bigInt lhs, const bigInt rhs);

   void makeAbs() {
      sign = 1;
   }

   inline bool operator<(const bigInt& other) {
      if (size == 0 && other.size == 0) return false;
      if (sign < other.sign) return true;
      if (sign > other.sign) return false;
      if (size < other.size) return true;
      if (size > other.size) return false;
      int isize = ((size + 31) >> 5);
      for (int i = 1; i <= isize; i++) {
         if (pInt[LAST_I - isize + i] > other.pInt[LAST_I - isize + i]) return false;
         if (pInt[LAST_I - isize + i] < other.pInt[LAST_I - isize + i]) return true;
      }
      return false;
   }

   inline bool operator>(const bigInt& other) {
      if (size == 0 && other.size == 0) return false;
      if (sign < other.sign) return false;
      if (sign > other.sign) return true;
      if (size < other.size) return false;
      if (size > other.size) return true;
      int isize = ((size + 31) >> 5);
      for (int i = 1; i <= isize; i++) {
         if (pInt[LAST_I - isize + i] < other.pInt[LAST_I - isize + i]) return false;
         if (pInt[LAST_I - isize + i] > other.pInt[LAST_I - isize + i]) return true;
      }
      return false;
   }

   inline bool operator==(const bigInt& other) {
      if (size == other.size) {
         if (size == 0) return true;
         if (sign == other.sign) {
            int isize = ((size + 31) >> 5);
            for (int i = 0; i < isize; i++) {
               if (pInt[LAST_I - i] != other.pInt[LAST_I - i]) return false;
            }
            return true;
         }
      }
      return false;
   }
};

inline const bigInt operator*(const bigInt lhs, const bigInt rhs) {
   bigInt res = 0;
   unsigned int maxsize = lhs.size + rhs.size;
   res.sign = lhs.sign * rhs.sign;
   if (maxsize == 0) return res;
   int lisize = ((lhs.size + 31) >> 5);
   int risize = ((rhs.size + 31) >> 5);
   for (int i = 0; i < lisize; i++) {
      bigInt tmp = 0;
      for (int j = 0; j < risize; j++) {
         unsigned long long x = tLL lhs.pInt[LAST_I - i] * tLL rhs.pInt[LAST_I - j];
         x = (x << 32) + (x >> 32);
         tmppLL(LAST_I - 1 - i - j) += x;
      }
      unsigned long long x = tmppLL(LAST_I - i - risize);
      x = (x << 32) + (x >> 32);
      tmp.size = 0;
      for (int i = 63; i >= 0; --i) {
         if (x & (1LL < i)) {
            tmp.size = 64 - i;
            break;
         }
      }
      res = res + tmp;
   }
   --maxsize;
   if (res.pInt[LAST_I - (maxsize >> 5)] & (1U << (maxsize & 31))) res.size = maxsize + 1;
   else res.size = maxsize;
   return res;
}

inline const bigInt operator+(const bigInt lhs, const bigInt rhs) {
   bigInt res = 0;
   int lsize = lhs.size, rsize = rhs.size;
   int maxsize = lsize < rsize ? rsize : lsize;
   if (maxsize == 0) return res;
   if (lhs.sign == rhs.sign) {
      res.sign = lhs.sign;
      int i = LAST_I;
      while (lsize > 0 || rsize > 0) {
         unsigned long long x = tLL lhs.pInt[i] + tLL rhs.pInt[i];
         x = (x << 32) + (x >> 32);
         respLL(i - 1) += x;
         lsize -= 32;
         rsize -= 32;
         --i;
      }
      if (res.pInt[LAST_I - (maxsize >> 5)] & (1U << (maxsize & 31))) res.size = maxsize + 1;
      else res.size = maxsize;
   }
   else {
      const bigInt *pbs, *pls;
      bigInt ltmp = lhs, rtmp = rhs;
      ltmp.makeAbs();
      rtmp.makeAbs();
      if (ltmp < rtmp) {
         pls = &lhs;
         pbs = &rhs;
         res.sign = rhs.sign;
      }
      else {
         pls = &rhs;
         pbs = &lhs;
         res.sign = lhs.sign;
      }
      int i = LAST_I;
      while (lsize > 0 || rsize > 0) {
         unsigned long long x = tLL pbs->pInt[i] - tLL pls->pInt[i];
         x = (x << 32) + (x >> 32);
         respLL(i - 1) += x;
         lsize -= 32;
         rsize -= 32;
         --i;
      }
      res.size = 0;
      for (int j = maxsize - 1; j >= 0; --j) {
         if (res.pInt[LAST_I - (j >> 5)] & (1U << (j & 31))) {
            res.size = j + 1;
            break;
         }
      }
   }

   return res;
}

inline const bigInt operator-(const bigInt lhs, const bigInt rhs) {
   bigInt newrhs = rhs;
   newrhs.sign *= -1;
   return lhs + newrhs;
}

bigInt xs[100000], ys[100000];

int main() {
   int n;
   cin >> n;
   int min1 = 0, min2 = 1;
   for (int i = 0; i < n; i++) {
      long long x, y;
      cin >> x >> y;
      ys[i] = y;
      xs[i] = x;
   }
   bigInt mindist = ~(1LL << 63);
   for (int i = 1; i < n; i++) {
      bigInt dist = ((xs[i] - xs[0]) * (xs[i] - xs[0])) + ((ys[i] - ys[0]) * (ys[i] - ys[0]));
      if (dist < mindist) {
         mindist = dist;
         min2 = i;
      }
   }
   int mini = 0;
   bigInt a = ys[min2] - ys[min1];
   bigInt b = xs[min1] - xs[min2];
   bigInt x = (a * xs[min1]);
   bigInt y = (b * ys[min1]);
   bigInt c = bigInt(0) - (a * xs[min1]) - (b * ys[min1]);
   mindist = ~(1LL << 63);
   for (int i = 1; i < n; i++) {
      bigInt dist = a * xs[i] + b * ys[i] + c;
      dist.makeAbs();
      if (!(dist == bigInt(0)) && dist < mindist) {
         mindist = dist;
         mini = i;
      }
   }

   cout << min1 + 1 << ' ' << min2 + 1 << ' ' << mini + 1 << endl;

   return 0;
}


#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <list>
#include <vector>
#include <utility>
#include <queue>
#include <cmath>
#include <set>
#include <algorithm>
#include <unordered_map>

using namespace std;

int main() {
   int n;
   cin >> n;
   int xs[100000], ys[100000];
   int min1 = 0, min2 = 1;
   cin >> xs[0] >> ys[0];
   cin >> xs[1] >> ys[1];
   if (xs[0] > xs[1]) {
      min1 = 1; min2 = 0;
   }
   else if (xs[0] == xs[1]) {
      if (ys[0] > ys[1]) {
         min1 = 1; min2 = 0;
      }
   }
   for (int i = 2; i < n; i++) {
      cin >> xs[i] >> ys[i];
      if (xs[i] < xs[min1]) {
         min2 = min1;
         min1 = i;
      }
      else if (xs[i] == xs[min1]) {
         if (ys[i] <= ys[min1]) {
            min2 = min1;
            min1 = i;
         }
      }
      else if (xs[i] < xs[min2]) {
         min2 = i;
      }
      else if (xs[i] == xs[min2]) {
         if (ys[i] <= ys[min2]) {
            min2 = i;
         }
      }
   }
   int mini = 0;
   if (xs[min1] == xs[min2]) {
      int mindist = 1000000001;
      for (int i = 0; i < n; i++) {
         int dist = abs(xs[i] - xs[min1]);
         if (dist > 0 && dist < mindist) {
            mindist = dist;
            mini = i;
         }
      }
   }
   else {
      if (xs[min1] > xs[min2]) {
         swap(min1, min2);
      }
      long double a = (ys[min2] - ys[min1]) / (xs[min2] - xs[min1]);
      long double b = ys[min1] - (a * xs[min1]);
      long double mindist = 10e90L;
      for (int i = 0; i < n; i++) {
         long double dist = abs(a * xs[i] - ys[i] + b) / sqrt(a * a + 1);
         if (dist > 0.001 && dist < mindist) {
            mindist = dist;
            mini = i;
         }
      }
   }

   cout << min1 + 1 << min2 + 1 << mini + 1 << endl;

   return 0;
}


#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <list>
#include <vector>
#include <utility>
#include <queue>
#include <cmath>
#include <cstdint>
#include <set>
#include <algorithm>
#include <unordered_map>

using namespace std;

#define t32 (uint32_t)
#define t64 (uint64_t)

template<int MAX_SIZE = 32>
class bigInt {

   uint32_t pInt[MAX_SIZE];
   int32_t size;
   int8_t sign;

public:

   inline bigInt() {
      memset(pInt, 0, MAX_SIZE * sizeof(decltype(pInt[0])));
      size = 0;
      sign = 1;
   }

   inline bigInt(int64_t x) {
      *this = x;
   }

   inline bigInt(const bigInt& x) {
      *this = x;
   }

   inline bigInt& operator=(const bigInt& x) {
      memcpy(this, &x, sizeof(bigInt));
      return *this;
   }

   inline bigInt& operator=(int64_t x) {
      memset(pInt, 0, MAX_SIZE * sizeof(decltype(pInt[0])));
      if (x < 0) {
         x = ~x + 1;
         sign = -1;
      }
      else {
         sign = 1;
      }
      pInt[0] = t32 x;
      pInt[1] = t32 (x >> 32);
      if (x == 0) size = 0;
      else if (pInt[1] == 0) {
         size = 1;
      }
      else {
         size = 2;
      }
      return *this;
   }

   inline friend bigInt operator+(bigInt lhs, bigInt rhs) {
      bigInt res;
      if (lhs.sign == rhs.sign) {
         int32_t maxsize = (lhs.size > rhs.size ? lhs.size : rhs.size);
         for (int i = 0; i < maxsize; i++) {
            uint64_t x = t64 lhs.pInt[i] + t64 rhs.pInt[i];
            res.pInt[i] += t32 x;
            res.pInt[i + 1] += t32 (x >> 32);
         }
         if (res.pInt[maxsize] != 0) res.size = maxsize + 1;
         else res.size = maxsize;
         res.sign = lhs.sign;
      }
      else {
         char lsign = lhs.sign, rsign = rhs.sign;
         lhs.sign = rhs.sign = 1;
         if (lhs == rhs) return res;
         bigInt *pbs, *pls;
         if (lhs < rhs) {
            res.sign = rsign;
            pbs = &rhs;
            pls = &lhs;
         }
         else {
            res.sign = lsign;
            pbs = &lhs;
            pls = &rhs;
         }
         int32_t maxsize = pbs->size;
         for (int i = 0; i < maxsize; i++) {
            uint64_t x = t64 pbs->pInt[i] - t64 pls->pInt[i];
            res.pInt[i] += t32 x;
            res.pInt[i + 1] += t32 (x >> 32);
         }
         for (int i = maxsize - 1; i >= 0; --i) {
            if (res.pInt[i] != 0) {
               res.size = i + 1;
               break;
            }
         }
      }
      return res;
   }

   inline friend bigInt operator-(bigInt lhs, bigInt rhs) {
      if (rhs.size == 0) return lhs;
      rhs.sign *= -1;
      return lhs + rhs;
   }

   inline friend bigInt operator*(bigInt lhs, bigInt rhs) {
      bigInt res;
      if (lhs.size == 0 || rhs.size == 0) return res;
      int32_t maxsize = lhs.size + rhs.size;
      for (int i = 0; i < lhs.size; i++) {
         bigInt tmp;
         for (int j = 0; j < rhs.size; j++) {
            uint64_t x = t64 lhs.pInt[i] * t64 rhs.pInt[j];
            tmp.pInt[i + j] = t32 x;
            tmp.pInt[i + j + 1] = t32 (x >> 32);
         }
         for (int k = maxsize - 1; k >= 0; --k) {
            if (tmp.pInt[k] != 0) {
               tmp.size = k + 1;
               break;
            }
         }
         res = res + tmp;
      }
      for (int k = maxsize - 1; k >= 0; --k) {
         if (res.pInt[k] != 0) {
            res.size = k + 1;
            break;
         }
      }
      res.sign = lhs.sign * rhs.sign;
      return res;
   }

   inline friend bigInt abs(bigInt x) {
      x.sign = 1;
      return x;
   }

   inline bool operator<(const bigInt& other) {
      if (sign < other.sign) return true;
      if (sign > other.sign) return false;
      if (size < other.size) return true;
      if (size > other.size) return false;
      for (int i = size - 1; i >= 0; --i) {
         if (pInt[i] < other.pInt[i]) return true;
         if (pInt[i] > other.pInt[i]) return false;
      }
      return false;
   }

   inline bool operator<=(const bigInt& other) {
      return !(*this > other);
   }

   inline bool operator>(const bigInt& other) {
      if (sign < other.sign) return false;
      if (sign > other.sign) return true;
      if (size < other.size) return false;
      if (size > other.size) return true;
      for (int i = size - 1; i >= 0; --i) {
         if (pInt[i] < other.pInt[i]) return false;
         if (pInt[i] > other.pInt[i]) return true;
      }
      return false;
   }

   inline bool operator>=(const bigInt& other) {
      return !(*this < other);
   }

   inline bool operator==(const bigInt& other) {
      if (sign != other.sign) return false;
      if (size != other.size) return false;
      for (int i = 0; i < size; i++) {
         if (pInt[i] != other.pInt[i]) return false;
      }
      return true;
   }

   inline bool operator!=(const bigInt& other) {
      return !(*this == other);
   }
};

#undef t32
#undef t64

#define inttouse bigInt<32>

inttouse xs[100000], ys[100000];

int main() {
   int n;
   scanf("%d", &n);
   int min1 = 0, min2 = 1;
   for (int i = 0; i < n; i++) {
      long long x, y;
      scanf("%lld%lld", &x, &y);
      ys[i] = y;
      xs[i] = x;
   }
   inttouse mindist = ~(1LL << 63);
   for (int i = 1; i < n; i++) {
      inttouse dist = ((xs[i] - xs[0]) * (xs[i] - xs[0])) + ((ys[i] - ys[0]) * (ys[i] - ys[0]));
      if (dist < mindist) {
         mindist = dist;
         min2 = i;
      }
   }
   int mini = 0;
   inttouse a = ys[min2] - ys[min1];
   inttouse b = xs[min1] - xs[min2];
   inttouse c = inttouse(0) - (a * xs[min1]) - (b * ys[min1]);
   mindist = ~(1LL << 63);
   for (int i = 1; i < n; i++) {
      inttouse dist = abs(a * xs[i] + b * ys[i] + c);
      if (!(dist == inttouse(0)) && dist < mindist) {
         mindist = dist;
         mini = i;
      }
   }

   printf("%d %d %d\n", min1 + 1, min2 + 1, mini + 1);

   return 0;
}


#include<iostream>
#include<vector>
#define ll long long int
#include <queue>
#include <string.h>
#include <bitset>
#include <algorithm>
#include <fstream>
#include <map>
#define MAX 2000000000000000
#include <cmath>
#define pp pair < int , int >
#include <stack>

using namespace std;

ifstream f("date.in");

int n;

struct pct{
    int x, y, idx;
    double degrees;
}v[300001];

double convert(double vt)
{
    return (180*vt)/3.14;
}

void slurpees(pct &A)
{
    if(A.x<0 && A.y>0)
        A.degrees = 180 - A.degrees;
    if(A.x<0 && A.y<0)
        A.degrees+=180;
    else
        if(A.x>0 && A.y<0 )
            A.degrees = 360-A.degrees;

}

void criterium(pct &A)
{
    if(A.y==0)
    {
        if(A.x>=0)
            A.degrees= 0;
        else
            A.degrees = 180;
        return;
    }
    if(A.x==0)
    {
        if(A.y>=0)
            A.degrees = 90;
        else A.degrees = 270;
        return;
    }
    double val = atan(double(A.y)/A.x);
    A.degrees = abs(convert(val));
    slurpees(A);
}

bool comp(pct A, pct B)
{
    if(A.degrees<B.degrees || A.degrees==B.degrees && (A.x<B.x || A.y<B.y))
        return true;
    return false;
}

int main()
{
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>v[i].x>>v[i].y;
        v[i].idx = i;
        criterium(v[i]);
    }
    sort(v+1, v+n+1, comp);
/*    for(int i=1; i<=n; i++)
        cout<<v[i].x<<" "<<v[i].y<<" "<<v[i].degrees<<'\n';
    cout<<'\n';*/
    cout<<v[1].idx<<" "<<v[2].idx<<" "<<v[3].idx;
}


#include<iostream>
#include<vector>
#define ll long long int
#include <queue>
#include <string.h>
#include <bitset>
#include <algorithm>
#include <fstream>
#include <map>
#define MAX 2000000000000000
#include <cmath>
#define pp pair < int , int >
#include <stack>

using namespace std;

ifstream f("date.in");

int n;

struct pct{
    long long x, y, idx;
}v[300001];

 bool cmp(pct A, pct B)
 {
     if(A.x<B.x || A.x==B.x && A.y<B.y)
        return true;
     return false;
 }

int main()
{
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>v[i].x>>v[i].y;
        v[i].idx=i;
    }
    sort(v+1, v+n+1, cmp);
    int m=3;
    while(m<=n && (v[1].x-v[2].x)*(v[1].y-v[m].y)==(v[1].y-v[2].y)*(v[1].x-v[m].x))m++;
    /*for(int i=1; i<=n; i++)
        cout<<v[i].x<<" "<<v[i].y<<" "<<v[i].idx<<'\n';
    cout<<'\n';*/
    cout<<v[1].idx<<" "<<v[2].idx<<" "<<v[m].idx;
}


#include<iostream>
#include<vector>
#define ll long long int
#include <queue>
#include <string.h>
#include <bitset>
#include <algorithm>
#include <fstream>
#include <map>
#define MAX 2000000000000000
#include <cmath>
#define pp pair < int , int >
#include <stack>

using namespace std;

ifstream f("date.in");

int n;

struct pct{
    int x, y, idx;
    double degrees;
}v[300001];

double convert(double vt)
{
    return (180*vt)/3.14;
}

void slurpees(pct &A)
{
    if(A.x<0 && A.y>0)
        A.degrees = 180 - A.degrees;
    if(A.x<0 && A.y<0)
        A.degrees+=180;
    else
        if(A.x>0 && A.y<0 )
            A.degrees = 360-A.degrees;

}

void criterium(pct &A)
{
    if(A.y==0)
    {
        if(A.x>=0)
            A.degrees= 0;
        else
            A.degrees = 180;
        return;
    }
    if(A.x==0)
    {
        if(A.y>=0)
            A.degrees = 90;
        else A.degrees = 270;
        return;
    }
    double val = atan(double(A.y)/A.x);
    A.degrees = abs(convert(val));
    slurpees(A);
}

bool comp(pct A, pct B)
{
    if(A.degrees<B.degrees || A.degrees==B.degrees && (A.x<B.x || A.y>B.y))
        return true;
    return false;
}

int main()
{
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>v[i].x>>v[i].y;
        v[i].idx = i;
        criterium(v[i]);
    }
    sort(v+1, v+n+1, comp);
/*    for(int i=1; i<=n; i++)
        cout<<v[i].x<<" "<<v[i].y<<" "<<v[i].degrees<<'\n';
    cout<<'\n';*/
    cout<<v[1].idx<<" "<<v[2].idx<<" "<<v[3].idx;
}


#include<iostream>
#include<vector>
#define ll long long int
#include <queue>
#include <string.h>
#include <bitset>
#include <algorithm>
#include <fstream>
#include <map>
#define MAX 2000000000000000
#include <cmath>
#define pp pair < int , int >
#include <stack>

using namespace std;

ifstream f("date.in");

int n;

struct pct{
    int x, y, idx;
    double tangent;
}v[300001];

void criterium(pct &A)
{
    if(A.y==0)
    {
        A.tangent = 0;
        return;
    }
    if(A.x==0)
    {
        A.tangent = 3.14/2;
        return;
    }
    double val = tan(double(A.y)/A.x);
    A.tangent = val;
}

bool comp(pct A, pct B)
{
    if(A.tangent<B.tangent || A.tangent==B.tangent && A.x<B.x)
        return true;
    return false;
}

int main()
{
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>v[i].x>>v[i].y;
        v[i].idx = i;
        criterium(v[i]);
        //cout<<v[i].x<<" "<<v[i].y<<" "<<v[i].tangent<<endl;
    }
    //cout<<'\n';
    sort(v+1, v+n+1, comp);
    /*for(int i=1; i<=n; i++)
        cout<<v[i].x<<" "<<v[i].y<<" "<<v[i].tangent<<'\n';*/
    cout<<v[1].idx<<" "<<v[2].idx<<" "<<v[3].idx;
}


#include<iostream>
#include<vector>
#define ll long long int
#include <queue>
#include <string.h>
#include <bitset>
#include <algorithm>
#include <fstream>
#include <map>
#define MAX 2000000000000000
#include <cmath>
#define pp pair < int , int >
#include <stack>

using namespace std;

ifstream f("date.in");

int n;

struct pct{
    int x, y, idx;
    double degrees;
}v[300001];

double convert(double vt)
{
    return (180*vt)/3.14;
}

void slurpees(pct &A)
{
    if(A.x<0 && A.y>0)
        A.degrees = 180 - A.degrees;
    if(A.x<0 && A.y<0)
        A.degrees+=180;
    else
        if(A.x>0 && A.y<0 )
            A.degrees = 360-A.degrees;

}

void criterium(pct &A)
{
    if(A.y==0)
    {
        if(A.x>=0)
            A.degrees= 0;
        else
            A.degrees = 180;
        return;
    }
    if(A.x==0)
    {
        if(A.y>=0)
            A.degrees = 90;
        else A.degrees = 270;
        return;
    }
    double val = atan(double(A.y)/A.x);
    A.degrees = abs(convert(val));
    slurpees(A);
}

bool comp(pct A, pct B)
{
    if(A.degrees<B.degrees || A.degrees==B.degrees && A.x<B.x)
        return true;
    return false;
}

int main()
{
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>v[i].x>>v[i].y;
        v[i].idx = i;
        criterium(v[i]);
    }
    sort(v+1, v+n+1, comp);
/*    for(int i=1; i<=n; i++)
        cout<<v[i].x<<" "<<v[i].y<<" "<<v[i].degrees<<'\n';
    cout<<'\n';*/

    cout<<v[1].idx<<" "<<v[2].idx<<" "<<v[3].idx;
}


#include<iostream>
#include<vector>
#define ll long long int
#include <queue>
#include <string.h>
#include <bitset>
#include <algorithm>
#include <fstream>
#include <map>
#define MAX 2000000000000000
#include <cmath>
#define pp pair < int , int >
#include <stack>

using namespace std;

ifstream f("date.in");

int n;

struct pct{
    ll x, y, idx;
    double degrees;
}v[300001];

double convert(double vt)
{
    return (180*vt)/3.14;
}

void slurpees(pct &A)
{
    if(A.x<0 && A.y>0)
        A.degrees = 180 - A.degrees;
    if(A.x<0 && A.y<0)
        A.degrees+=180;
    else
        if(A.x>0 && A.y<0 )
            A.degrees = 360-A.degrees;

}

void criterium(pct &A)
{
    if(A.y==0)
    {
        if(A.x>=0)
            A.degrees= 0;
        else
            A.degrees = 180;
        return;
    }
    if(A.x==0)
    {
        if(A.y>=0)
            A.degrees = 90;
        else A.degrees = 270;
        return;
    }
    double val = atan(double(A.y)/A.x);
    A.degrees = abs(convert(val));
    slurpees(A);
}

bool comp(pct A, pct B)
{
    if(A.degrees<B.degrees || A.degrees==B.degrees && ((A.x<B.x &&A.x>=0 && A.y>=0) || (A.x>B.x && A.x<=0 && B.x<=0) || (A.y<B.y && A.y<=0 && B.y<=0) || (A.y>B.y && A.y>=0 && B.y>=0)))
        return true;
    return false;
}

int main()
{
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>v[i].x>>v[i].y;
        v[i].idx = i;
        criterium(v[i]);
    }
    sort(v+1, v+n+1, comp);
/*    for(int i=1; i<=n; i++)
        cout<<v[i].x<<" "<<v[i].y<<" "<<v[i].degrees<<'\n';
    cout<<'\n';*/
    cout<<v[1].idx<<" "<<v[2].idx<<" "<<v[3].idx;
}


#include<iostream>
#include<vector>
#define ll long long int
#include <queue>
#include <string.h>
#include <bitset>
#include <algorithm>
#include <fstream>
#include <map>
#define MAX 2000000000000000
#include <cmath>
#define pp pair < int , int >
#include <stack>

using namespace std;

ifstream f("date.in");

int n;

struct pct{
    int x, y, idx;
    double degrees;
}v[300001];

double convert(double vt)
{
    return (180*vt)/3.14;
}

void slurpees(pct &A)
{
    if(A.x<0 && A.y>0)
        A.degrees = 180 - A.degrees;
    if(A.x<0 && A.y<0)
        A.degrees+=180;
    else
        if(A.x>0 && A.y<0 )
            A.degrees = 360-A.degrees;

}

void criterium(pct &A)
{
    if(A.y==0)
    {
        if(A.x>=0)
            A.degrees= 0;
        else
            A.degrees = 180;
        return;
    }
    if(A.x==0)
    {
        if(A.y>=0)
            A.degrees = 90;
        else A.degrees = 270;
        return;
    }
    double val = atan(double(A.y)/A.x);
    A.degrees = abs(convert(val));
    slurpees(A);
}

bool comp(pct A, pct B)
{
    if(A.degrees<B.degrees || A.degrees==B.degrees && ((A.x<B.x &&A.x>=0 && A.y>=0) || (A.x>B.x && A.x<=0 && B.x<=0) || (A.y<B.y && A.y<=0 && B.y<=0) || (A.y>B.y && A.y>=0 && B.y>=0)))
        return true;
    return false;
}

int main()
{
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>v[i].x>>v[i].y;
        v[i].idx = i;
        criterium(v[i]);
    }
    sort(v+1, v+n+1, comp);
/*    for(int i=1; i<=n; i++)
        cout<<v[i].x<<" "<<v[i].y<<" "<<v[i].degrees<<'\n';
    cout<<'\n';*/
    cout<<v[1].idx<<" "<<v[2].idx<<" "<<v[3].idx;
}


#include<iostream>
#include<vector>
#define ll long long int
#include <queue>
#include <string.h>
#include <bitset>
#include <algorithm>
#include <fstream>
#include <map>
#define MAX 2000000000000000
#include <cmath>
#define pp pair < int , int >
#include <stack>

using namespace std;

ifstream f("date.in");

int n;

struct pct{
    int x, y, idx;
}v[300001];

 bool cmp(pct A, pct B)
 {
     if(A.x<B.x || A.x==B.x && A.y<B.y)
        return true;
     return false;
 }

int main()
{
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>v[i].x>>v[i].y;
        v[i].idx=i;
    }
    sort(v+1, v+n+1, cmp);
    int m=3;
    while((v[1].x-v[2].x)*(v[1].y-v[m].y)==(v[1].y-v[2].y)*(v[1].x-v[m].x))m++;
    /*for(int i=1; i<=n; i++)
        cout<<v[i].x<<" "<<v[i].y<<" "<<v[i].idx<<'\n';
    cout<<'\n';*/
    cout<<v[1].idx<<" "<<v[2].idx<<" "<<v[m].idx;
}


#include<iostream>
#include<vector>
#define ll long long int
#include <queue>
#include <string.h>
#include <bitset>
#include <algorithm>
#include <fstream>
#include <map>
#define MAX 2000000000000000
#include <cmath>
#define pp pair < int , int >
#include <stack>

using namespace std;

ifstream f("date.in");

int n;

struct pct{
    int x, y, idx;
}v[300001];

 bool cmp(pct A, pct B)
 {
     if(A.x<B.x || A.x==B.x && A.y<B.y)
        return true;
     return false;
 }

int main()
{
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>v[i].x>>v[i].y;
        v[i].idx=i;
    }
    sort(v+1, v+n+1, cmp);
    int m=3;
    while(m<n && (v[1].x-v[2].x)*(v[1].y-v[m].y)==(v[1].y-v[2].y)*(v[1].x-v[m].x))m++;
    /*for(int i=1; i<=n; i++)
        cout<<v[i].x<<" "<<v[i].y<<" "<<v[i].idx<<'\n';
    cout<<'\n';*/
    cout<<v[1].idx<<" "<<v[2].idx<<" "<<v[m].idx;
}


#include<iostream>
#include<vector>
#define ll long long int
#include <queue>
#include <string.h>
#include <bitset>
#include <algorithm>
#include <fstream>
#include <map>
#define MAX 2000000000000000
#include <cmath>
#define pp pair < int , int >
#include <stack>

using namespace std;

ifstream f("date.in");

int n;

struct pct{
    int x, y, idx;
}v[300001];

 bool cmp(pct A, pct B)
 {
     if(A.x<B.x || A.x==B.x && A.y<B.y)
        return true;
     return false;
 }

int main()
{
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>v[i].x>>v[i].y;
        v[i].idx=i;
    }
    sort(v+1, v+n+1, cmp);
    /*for(int i=1; i<=n; i++)
        cout<<v[i].x<<" "<<v[i].y<<" "<<v[i].idx<<'\n';
    cout<<'\n';*/
    cout<<v[1].idx<<" "<<v[2].idx<<" "<<v[3].idx;
}


#include <iostream>
#include <math.h>
using namespace std;
const int N_MAX = 1e5;
struct punct
{
    double x, y;
}puncte[N_MAX + 1];
int n, b, ales;
long double minimul = 1e18, minima = 1e18;
double pat(double t)
{
    return t * t;
}

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> puncte[i].x >> puncte[i].y;
        if(i != 1)
        {
            double dist = sqrt(pat(puncte[1].x - puncte[i].x) + pat(puncte[1].y - puncte[i].y));
            if(dist < minima)
            {
                minima = dist;
                b = i;
            }
        }
    }
    double dist = minima;
    for(int i = 2; i <= n; i++)
    {
        if(i == b || fabs((puncte[b].y - puncte[1].y) * puncte[i].x + (puncte[1].x - puncte[b].x) * puncte[i].y + puncte[1].y * puncte[b].x - puncte[1].x * puncte[b].y) < 1e-28)
            continue;
        double dist1 = sqrt(pat(puncte[i].x - puncte[1].x) + pat(puncte[i].y - puncte[1].y));
        double dist2 = sqrt(pat(puncte[i].x - puncte[b].x) + pat(puncte[i].y - puncte[b].y));
        double p = (dist + dist1 + dist2) / 2;
        double primul = p - dist;
        if(primul < 1e-28)
        	primul = 0;
        double doilea = p - dist;
        if(doilea < 1e-28)
        	doilea = 0;
        double treilea = p - dist;
        if(treilea < 1e-28)
        	treilea = 0;
        double arie = sqrt(p * primul * doilea * treilea);
        if(arie < minimul)
        {
            minimul = arie;
            ales = i;
        }
    }
    cout << "1 " << b << " " << ales;
}


#include <iostream>
#include <math.h>
using namespace std;
const int N_MAX = 1e5;
struct punct
{
    double x, y;
}puncte[N_MAX + 1];
int n, b, ales;
double minimul = 1e18, minima = 1e18;
double pat(double t)
{
    return t * t;
}

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> puncte[i].x >> puncte[i].y;
        if(i != 1)
        {
            double dist = sqrt(pat(puncte[1].x - puncte[i].x) + pat(puncte[1].y - puncte[i].y));
            if(dist < minima)
            {
                minima = dist;
                b = i;
            }
        }
    }
    double dist = minima;
    for(int i = 2; i <= n; i++)
    {
        if(i == b || fabs((puncte[b].y - puncte[1].y) * puncte[i].x + (puncte[1].x - puncte[b].x) * puncte[i].y + puncte[1].y * puncte[b].x - puncte[1].x * puncte[b].y) < 1e-28)
            continue;
        double dist1 = sqrt(pat(puncte[i].x - puncte[1].x) + pat(puncte[i].y - puncte[1].y));
        double dist2 = sqrt(pat(puncte[i].x - puncte[b].x) + pat(puncte[i].y - puncte[b].y));
        double p = (dist + dist1 + dist2) / 2;
        double arie = sqrt(p * (p - dist) * (p - dist1) * (p - dist2));
        if(arie < minimul)
        {
            minimul = arie;
            ales = i;
        }
    }
    cout << "1 " << b << " " << ales;
}


#include <iostream>
#include <math.h>
using namespace std;
const int N_MAX = 1e5;
struct punct
{
    double x, y;
}puncte[N_MAX + 1];
int n, b, ales;
long double minimul = 1e18, minima = 1e18;
double pat(double t)
{
    return t * t;
}

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> puncte[i].x >> puncte[i].y;
        if(i != 1)
        {
            double dist = sqrt(pat(puncte[1].x - puncte[i].x) + pat(puncte[1].y - puncte[i].y));
            if(dist < minima)
            {
                minima = dist;
                b = i;
            }
        }
    }
    double dist = minima;
    for(int i = 2; i <= n; i++)
    {
        if(i == b || fabs((puncte[b].y - puncte[1].y) * puncte[i].x + (puncte[1].x - puncte[b].x) * puncte[i].y + puncte[1].y * puncte[b].x - puncte[1].x * puncte[b].y) < 1e-28)
            continue;
        double dist1 = sqrt(pat(puncte[i].x - puncte[1].x) + pat(puncte[i].y - puncte[1].y));
        double dist2 = sqrt(pat(puncte[i].x - puncte[b].x) + pat(puncte[i].y - puncte[b].y));
        double p = (dist + dist1 + dist2) / 2;
        double primul = p - dist;
        if(primul < 1e-90)
        	primul = 0;
        double doilea = p - dist1;
        if(doilea < 1e-90)
        	doilea = 0;
        double treilea = p - dist2;
        if(treilea < 1e-90)
        	treilea = 0;
        double arie = sqrt(p * primul * doilea * treilea);
        if(arie < minimul)
        {
            minimul = arie;
            ales = i;
        }
    }
    cout << "1 " << b << " " << ales;
}


#include <iostream>
#include <math.h>
using namespace std;
const int N_MAX = 1e5;
struct punct
{
    double x, y;
}puncte[N_MAX + 1];
int n, ales;
double minimul = 1e18;
double pat(double t)
{
    return t * t;
}

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
        cin >> puncte[i].x >> puncte[i].y;
    double dist = sqrt(pat(puncte[1].x - puncte[2].x) + pat(puncte[1].y - puncte[2].y));
    for(int i = 3; i <= n; i++)
    {
        if(fabs((puncte[2].y - puncte[1].y) * puncte[i].x + (puncte[1].x - puncte[2].x) * puncte[i].y + puncte[1].y * puncte[2].x - puncte[1].x * puncte[2].y) < 1e-8)
        {
            cout << i << " ";
            continue;
        }
        double dist1 = sqrt(pat(puncte[i].x - puncte[1].x) + pat(puncte[i].y - puncte[1].y));
        double dist2 = sqrt(pat(puncte[i].x - puncte[2].x) + pat(puncte[i].y - puncte[2].y));
        double p = (dist + dist1 + dist2) / 2;
        double arie = sqrt(p * (p - dist) * (p - dist1) * (p - dist2));
        if(arie < minimul)
        {
            minimul = arie;
            ales = i;
        }
    }
    cout << "1 2 " << ales;
}


#include <iostream>
#include <math.h>
using namespace std;
const int N_MAX = 1e5;
struct punct
{
    double x, y;
}puncte[N_MAX + 1];
int n, b, ales;
long double minimul = 1e18, minima = 1e18;
double pat(double t)
{
    return t * t;
}

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> puncte[i].x >> puncte[i].y;
        if(i != 1)
        {
            double dist = sqrt(pat(puncte[1].x - puncte[i].x) + pat(puncte[1].y - puncte[i].y));
            if(dist < minima)
            {
                minima = dist;
                b = i;
            }
        }
    }
    double dist = minima;
    for(int i = 2; i <= n; i++)
    {
        if(i == b || fabs((puncte[b].y - puncte[1].y) * puncte[i].x + (puncte[1].x - puncte[b].x) * puncte[i].y + puncte[1].y * puncte[b].x - puncte[1].x * puncte[b].y) < 1e-28)
            continue;
        double dist1 = sqrt(pat(puncte[i].x - puncte[1].x) + pat(puncte[i].y - puncte[1].y));
        double dist2 = sqrt(pat(puncte[i].x - puncte[b].x) + pat(puncte[i].y - puncte[b].y));
        double p = (dist + dist1 + dist2) / 2;
        double primul = p - dist;
        if(primul < 1e-90)
        	primul = 0;
        double doilea = p - dist;
        if(doilea < 1e-90)
        	doilea = 0;
        double treilea = p - dist;
        if(treilea < 1e-90)
        	treilea = 0;
        double arie = sqrt(p * primul * doilea * treilea);
        if(arie < minimul)
        {
            minimul = arie;
            ales = i;
        }
    }
    cout << "1 " << b << " " << ales;
}


#include <iostream>
#include <math.h>
using namespace std;
const int N_MAX = 1e5;
struct punct
{
    double x, y;
}puncte[N_MAX + 1];
int n, ales;
double minimul = 1e18;
double pat(double t)
{
    return t * t;
}

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
        cin >> puncte[i].x >> puncte[i].y;
    double dist = sqrt(pat(puncte[1].x - puncte[2].x) + pat(puncte[1].y - puncte[2].y));
    for(int i = 3; i <= n; i++)
    {
        if(fabs((puncte[2].y - puncte[1].y) * puncte[i].x + (puncte[1].x - puncte[2].x) * puncte[i].y + puncte[1].y * puncte[2].x - puncte[1].x * puncte[2].y) < 1e-6)
            continue;
        double dist1 = sqrt(pat(puncte[i].x - puncte[1].x) + pat(puncte[i].y - puncte[1].y));
        double dist2 = sqrt(pat(puncte[i].x - puncte[2].x) + pat(puncte[i].y - puncte[2].y));
        double p = (dist + dist1 + dist2) / 2;
        double arie = sqrt(p * (p - dist) * (p - dist1) * (p - dist2));
        if(arie < minimul)
        {
            minimul = arie;
            ales = i;
        }
    }
    cout << "1 2 " << ales;
}


#include <iostream>
#include <math.h>
using namespace std;
const int N_MAX = 1e5;
struct punct
{
    double x, y;
}puncte[N_MAX + 1];
int n, b, ales;
double minimul = 1e18, minima = 1e18;
double pat(double t)
{
    return t * t;
}

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> puncte[i].x >> puncte[i].y;
        if(i != 1)
        {
            double dist = sqrt(pat(puncte[1].x - puncte[i].x) + pat(puncte[1].y - puncte[i].y));
            if(dist < minima)
            {
                minima = dist;
                b = i;
            }
        }
    }
    double dist = minima;
    for(int i = 2; i <= n; i++)
    {
        if(i == b || fabs((puncte[b].y - puncte[1].y) * puncte[i].x + (puncte[1].x - puncte[b].x) * puncte[i].y + puncte[1].y * puncte[b].x - puncte[1].x * puncte[b].y) < 1e-8)
            continue;
        double dist1 = sqrt(pat(puncte[i].x - puncte[1].x) + pat(puncte[i].y - puncte[1].y));
        double dist2 = sqrt(pat(puncte[i].x - puncte[b].x) + pat(puncte[i].y - puncte[b].y));
        double p = (dist + dist1 + dist2) / 2;
        double arie = sqrt(p * (p - dist) * (p - dist1) * (p - dist2));
        if(arie < minimul)
        {
            minimul = arie;
            ales = i;
        }
    }
    cout << "1 " << b << " " << ales;
}


#include <iostream>
#include <math.h>
using namespace std;
const int N_MAX = 1e5;
struct punct
{
    double x, y;
}puncte[N_MAX + 1];
int n, ales;
double minimul = 1e18;
double pat(double t)
{
    return t * t;
}

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
        cin >> puncte[i].x >> puncte[i].y;
    double dist = sqrt(pat(puncte[1].x - puncte[2].x) + pat(puncte[1].y - puncte[2].y));
    for(int i = 3; i <= n; i++)
    {
        double dist1 = sqrt(pat(puncte[i].x - puncte[1].x) + pat(puncte[i].y - puncte[1].y));
        double dist2 = sqrt(pat(puncte[i].x - puncte[2].x) + pat(puncte[i].y - puncte[2].y));
        double p = (dist + dist1 + dist2) / 2;
        double arie = sqrt(p * (p - dist) * (p - dist1) * (p - dist2));
        if(arie < minimul)
        {
            minimul = arie;
            ales = i;
        }
    }
    cout << "1 2 " << ales;
}


#include <iostream>
#include <math.h>
using namespace std;
const int N_MAX = 1e5;
struct punct
{
    double x, y;
}puncte[N_MAX + 1];
int n, ales;
double minimul = 1e18;
double pat(double t)
{
    return t * t;
}

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
        cin >> puncte[i].x >> puncte[i].y;
    double dist = sqrt(pat(puncte[1].x - puncte[2].x) + pat(puncte[1].y - puncte[2].y));
    for(int i = 3; i <= n; i++)
    {
        if(fabs((puncte[2].y - puncte[1].y) * puncte[i].x - (puncte[1].x - puncte[2].x) * puncte[i].y + puncte[1].y * puncte[2].x - puncte[1].x * puncte[2].y) < 1e-6)
            continue;
        double dist1 = sqrt(pat(puncte[i].x - puncte[1].x) + pat(puncte[i].y - puncte[1].y));
        double dist2 = sqrt(pat(puncte[i].x - puncte[2].x) + pat(puncte[i].y - puncte[2].y));
        double p = (dist + dist1 + dist2) / 2;
        double arie = sqrt(p * (p - dist) * (p - dist1) * (p - dist2));
        if(arie < minimul)
        {
            minimul = arie;
            ales = i;
        }
    }
    cout << "1 2 " << ales;
}


#include <iostream>
#include <math.h>
using namespace std;
const int N_MAX = 1e5;
struct punct
{
    double x, y;
}puncte[N_MAX + 1];
int n, b, ales;
double minimul = 1e18, minima = 1e18;
double pat(double t)
{
    return t * t;
}

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> puncte[i].x >> puncte[i].y;
        if(i != 1)
        {
            double dist = sqrt(pat(puncte[1].x - puncte[i].x) + pat(puncte[1].y - puncte[i].y));
            if(dist < minima)
            {
                minima = dist;
                b = i;
            }
        }
    }
    double dist = minima;
    for(int i = 2; i <= n; i++)
    {
        if(i == b || fabs((puncte[b].y - puncte[1].y) * puncte[i].x + (puncte[1].x - puncte[b].x) * puncte[i].y + puncte[1].y * puncte[b].x - puncte[1].x * puncte[b].y) < 1e-18)
            continue;
        double dist1 = sqrt(pat(puncte[i].x - puncte[1].x) + pat(puncte[i].y - puncte[1].y));
        double dist2 = sqrt(pat(puncte[i].x - puncte[b].x) + pat(puncte[i].y - puncte[b].y));
        double p = (dist + dist1 + dist2) / 2;
        double arie = sqrt(p * (p - dist) * (p - dist1) * (p - dist2));
        if(arie < minimul)
        {
            minimul = arie;
            ales = i;
        }
    }
    cout << "1 " << b << " " << ales;
}


#include <iostream>
#include <math.h>
using namespace std;
const int N_MAX = 1e5;
struct punct
{
    double x, y;
}puncte[N_MAX + 1];
int n, b, ales;
double minimul = 1e18, minima = 1e18;
double pat(double t)
{
    return t * t;
}

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> puncte[i].x >> puncte[i].y;
        if(i != 1)
        {
            double dist = sqrt(pat(puncte[1].x - puncte[i].x) + pat(puncte[1].y - puncte[i].y));
            if(dist < minima)
            {
                minima = dist;
                b = i;
            }
        }
    }
    double dist = minima;
    for(int i = 3; i <= n; i++)
    {
        if(fabs((puncte[b].y - puncte[1].y) * puncte[i].x + (puncte[1].x - puncte[b].x) * puncte[i].y + puncte[1].y * puncte[b].x - puncte[1].x * puncte[b].y) < 1e-8)
        {
            cout << i << " ";
            continue;
        }
        double dist1 = sqrt(pat(puncte[i].x - puncte[1].x) + pat(puncte[i].y - puncte[1].y));
        double dist2 = sqrt(pat(puncte[i].x - puncte[b].x) + pat(puncte[i].y - puncte[b].y));
        double p = (dist + dist1 + dist2) / 2;
        double arie = sqrt(p * (p - dist) * (p - dist1) * (p - dist2));
        if(arie < minimul)
        {
            minimul = arie;
            ales = i;
        }
    }
    cout << "1 2 " << ales;
}


#include <iostream>
#include <math.h>
using namespace std;
const int N_MAX = 1e5;
struct punct
{
    double x, y;
}puncte[N_MAX + 1];
int n, ales;
double minimul = 1e18;
double pat(double t)
{
    return t * t;
}

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
        cin >> puncte[i].x >> puncte[i].y;
    double dist = sqrt(pat(puncte[1].x - puncte[2].x) + pat(puncte[1].y - puncte[2].y));
    for(int i = 3; i <= n; i++)
    {
        double dist1 = sqrt(pat(puncte[i].x - puncte[1].x) + pat(puncte[i].y - puncte[1].y));
        double dist2 = sqrt(pat(puncte[i].x - puncte[2].x) + pat(puncte[i].y - puncte[2].y));
        double p = (dist + dist1 + dist2) / 2;
        double arie = sqrt(p * (p - dist) * (p - dist1) * (p - dist2));
        if(arie && arie < minimul)
        {
            minimul = arie;
            ales = i;
        }
    }
    cout << "1 2 " << ales;
}


#include <iostream>
#include <math.h>
using namespace std;
const int N_MAX = 1e5;
struct punct
{
    double x, y;
}puncte[N_MAX + 1];
int n, b, ales;
long double minimul = 1e19, minima = 1e19;
double pat(double t)
{
    return t * t;
}

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> puncte[i].x >> puncte[i].y;
        if(i != 1)
        {
            double dist = sqrt(pat(puncte[1].x - puncte[i].x) + pat(puncte[1].y - puncte[i].y));
            if(dist < minima)
            {
                minima = dist;
                b = i;
            }
        }
    }
    double dist = minima;
    for(int i = 2; i <= n; i++)
    {
        if(i == b || fabs((puncte[b].y - puncte[1].y) * puncte[i].x + (puncte[1].x - puncte[b].x) * puncte[i].y + puncte[1].y * puncte[b].x - puncte[1].x * puncte[b].y) < 1e-28)
            continue;
        double dist1 = sqrt(pat(puncte[i].x - puncte[1].x) + pat(puncte[i].y - puncte[1].y));
        double dist2 = sqrt(pat(puncte[i].x - puncte[b].x) + pat(puncte[i].y - puncte[b].y));
        double p = (dist + dist1 + dist2) / 2;
        double primul = p - dist;
        if(primul < 1e-19)
        	primul = 0;
        double doilea = p - dist1;
        if(doilea < 1e-19)
        	doilea = 0;
        double treilea = p - dist2;
        if(treilea < 1e-19)
        	treilea = 0;
        double arie = sqrt(p * primul * doilea * treilea);
        if(arie < minimul)
        {
            minimul = arie;
            ales = i;
        }
    }
    cout << "1 " << b << " " << ales;
}


#include <bits/stdc++.h>

#define f first
#define s second

using namespace std;

pair< pair<int, int>, int > a[100000];
pair <int, int> a1, a2;
int a3, n;
long long  sqr(int a){
    return static_cast<long long>(a)*a;
}
int main(){
    cin>>n;
    for(int i = 0; i<n; i++){
        cin>>a[i].f.f>>a[i].f.s;a[i].s =i;}

    sort(a, a+n);
    a1 = a[0].f; a2 = a[1].f;
    for(int i = 2; i<n; i++)
        if
            (sqr(a[i].f.f-a1.f) + sqr(a[i].f.s-a1.s)
		== sqr(a[i].f.f - a2.f) +sqr(a2.f-a1.f) +sqr(a[i].f.s - a2.s) +sqr(a2.s-a1.s)) continue;
             else{a3 = a[i].s;break;}
    cout<<a[0].s+1<<" "<<a[1].s+1<<" "<<a3+1;

    return 0;
}


#include <bits/stdc++.h>

#define f first
#define s second

using namespace std;

pair< pair<int, int>, int > a[100000];
pair <int, int> a1, a2;
int a3, n;
long long  sqr(int a){
    return static_cast<long long>(a)*a;
}
int main(){
    cin>>n;
    for(int i = 0; i<n; i++){
        cin>>a[i].f.f>>a[i].f.s;a[i].s =i;}

    sort(a, a+n);
    a1 = a[0].f; a2 = a[1].f;
    for(int i = 2; i<n; i++)
        if
            (sqr(a[i].f.f-a1.f) + sqr(a[i].f.s-a1.s)
		== sqr(a[i].f.f - a2.f) +sqr(a2.f-a1.f) +sqr(a[i].f.s - a2.s) +sqr(a2.s-a1.s)) continue;
             else{a3 = a[i].s;break;}
    cout<<a1.s+1<<" "<<a2.s+1<<" "<<a3+1;

    return 0;
}


#include <bits/stdc++.h>

#define f first
#define s second
#define ld long double

using namespace std;

pair< pair<long double,long double>, int > a[100000];
pair <ld, ld> a1, a2;
int a3, n;
ld  sqr(ld a){
    return static_cast<long long>(a)*a;
}

int main(){
    cin>>n;
    for(int i = 0; i<n; i++)
    {
        cin>>a[i].f.f>>a[i].f.s;
        a[i].s =i+1;
    }

    sort(a, a+n);

    a1 = a[0].f; a2 = a[1].f;

    for(int i = 2; i<n; i++)
        if (abs(sqrt(sqr(a[i].f.f-a1.f)+ sqr(a[i].f.s-a1.s)) -
                ( sqrt (sqr(a[i].f.f - a2.f) +sqr(a2.f-a1.f)) +
                  sqrt( sqr(a1.s - a2.s) +sqr(a2.f-a1.f) )))>1e-3)
                {a3 = a[i].s;break;}

    cout<<a[0].s<<" "<<a[1].s<<" "<<a3;

    return 0;
}


#include <bits/stdc++.h>

#define f first
#define s second
#define ld long double

using namespace std;

pair< pair<long double,long double>, int > a[100000];
pair <ld, ld> a1, a2;
int a3, n;
ld  sqr(ld a){
    return static_cast<long long>(a)*a;
}

int main(){
    cin>>n;
    for(int i = 0; i<n; i++)
    {
        cin>>a[i].f.f>>a[i].f.s;
        a[i].s =i+1;
    }

    sort(a, a+n);

    a1 = a[0].f; a2 = a[1].f;

    for(int i = 2; i<n; i++)
        if (abs(sqrt(sqr(a[i].f.f-a1.f)+ sqr(a[i].f.s-a1.s)) -
                ( sqrt (sqr(a[i].f.f - a2.f) +sqr(a2.f-a1.f)) +
                  sqrt( sqr(a1.s - a2.s) +sqr(a2.f-a1.f) )))>1e-12)
                {a3 = a[i].s;break;}

    cout<<a[0].s<<" "<<a[1].s<<" "<<a3;

    return 0;
}


#include <bits/stdc++.h>

#define f first
#define s second

using namespace std;

pair< pair<int, int>, int > a[100000];
pair <int, int> a1, a2;
int a3, n;
long long  sqr(int a){
    return static_cast<long long>(a)*a;
}
int main(){
    cin>>n;
    for(int i = 0; i<n; i++){
        cin>>a[i].f.f>>a[i].f.s;a[i].s =i;}

    sort(a, a+n);
    a1 = a[0].f; a2 = a[1].f;
    for(int i = 2; i<n; i++)
        if
            (sqr(a[i].f.f-a1.f) + sqr(a[i].f.s-a1.s)
		== sqr(a[i].f.f - a2.f) +sqr(a2.f-a1.f) +sqr(a[i].f.s - a2.s) +sqr(a2.s-a1.s)) continue;
             else{a3 = a[i].s;break;}
    cout<<a[0].s+1<<" "<<a[1]+1<<" "<<a3+1;

    return 0;
}


#include <bits/stdc++.h>

#define f first
#define s second

using namespace std;

pair< pair<int, int>, int > a[100000];
pair <int, int> a1, a2;
int a3, n;
unsigned long long mod(int a){
	return a<0?(-a):a;
}
long long  sqr(int a){
    return mod(a)*mod(a);
}
int main(){
    cin>>n;
    for(int i = 0; i<n; i++){
        cin>>a[i].f.f>>a[i].f.s;a[i].s =i;}

    sort(a, a+n);
    a1 = a[0].f; a2 = a[1].f;
    for(int i = 2; i<n; i++)
        if
            (sqr(a[i].f.f-a1.f) + sqr(a[i].f.s-a1.s)
		== sqr(a[i].f.f - a2.f) +sqr(a2.f-a1.f) +sqr(a[i].f.s - a2.s) +sqr(a2.s-a1.s)) continue;
    cout<<a[0].s+1<<" "<<a[1].s+1<<" "<<a3+1;
             else{a3 = a[i].s;break;}

    return 0;
}


#include <bits/stdc++.h>

#define f first
#define s second

using namespace std;

pair< pair<int, int>, int > a[100000];
pair <int, int> a1, a2;
int a3, n;
long long  sqr(int a){
    return static_cast<long long>(a)*a;
}
int main(){
    cin>>n;
    for(int i = 0; i<n; i++){
        cin>>a[i].f.f>>a[i].f.s;a[i].s =i;}

    sort(a, a+n);
    a1 = a[0].f; a2 = a[1].f;
    for(int i = 2; i<n; i++)
        if
            (sqr(a[i].f.f-a1.f) == sqr(a[i].f.f - a2.f) +sqr(a2.f-a1.f) &&
             (sqr(a[i].f.s-a1.s) == sqr(a[i].f.s - a2.s) +sqr(a2.s-a1.s) )) continue;
             else{a3 = a[i].s;break;}
    cout<<a1.s+1<<" "<<a2.s+1<<" "<<a3+1;

    return 0;
}


#include <bits/stdc++.h>

#define f first
#define s second
#define LL long long
using namespace std;

pair< pair<LL, LL>, LL > a[100000];
struct vec{
    LL x, y;
};

unsigned long long mod(LL a){
	return a<0?(-a):a;
}

long long  sqr(LL a){
    return mod(a)*mod(a);
}
int a3, n;
int main(){
    cin>>n;
    for(int i = 0; i<n; i++){
        cin>>a[i].f.f>>a[i].f.s;a[i].s =i;}

    sort(a, a+n);
    vec v;
    v.x = a[1].f.f-a[0].f.f;
    v.y = a[1].f.s-a[0].f.s;

    for(int i = 2; i<n; i++)
    {
        vec g;
        g.x = a[i].f.f-a[1].f.f;
        g.y = a[i].f.s-a[1].f.s;
        if (v.x*g.y != v.y*g.x) {a3 = a[i].s;break;}
    }

    cout<<a[0].s+1<<" "<<a[1].s+1<<" "<<a3+1;
    return 0;
}


#include <bits/stdc++.h>

#define f first
#define s second
#define ld long double

using namespace std;

pair< pair<long double,long double>, int > a[100000];
pair <ld, ld> a1, a2;
int a3, n;
ld  sqr(ld a){
    return static_cast<long long>(a)*a;
}

int main(){
    cin>>n;
    for(int i = 0; i<n; i++)
    {
        cin>>a[i].f.f>>a[i].f.s;
        a[i].s =i+1;
    }

    sort(a, a+n);

    a1 = a[0].f; a2 = a[1].f;

    for(int i = 2; i<n; i++)
        if (abs(sqrt(sqr(a[i].f.f-a1.f)+ sqr(a[i].f.s-a1.s)) -
                ( sqrt (sqr(a[i].f.f - a2.f) +sqr(a2.f-a1.f)) +
                  sqrt( sqr(a1.s - a2.s) +sqr(a2.f-a1.f) )))>1e-5)
                {a3 = a[i].s;break;}

    cout<<a[0].s<<" "<<a[1].s<<" "<<a3;

    return 0;
}


#include <bits/stdc++.h>

#define f first
#define s second
#define LL long long
using namespace std;

pair< pair<LL, LL>, LL > a[100000];
struct vec{
    LL x, y;
};

unsigned long long mod(LL a){
	return a<0?(-a):a;
}

long long  sqr(LL a){
    return mod(a)*mod(a);
}
int a3, n;
int main(){
    cin>>n;
    for(int i = 0; i<n; i++){
        cin>>a[i].f.f>>a[i].f.s;a[i].s =i;}

    sort(a, a+n);
    vec v;
    v.x = a[1].f.f-a[0].f.f;
    v.y = a[1].f.s-a[0].f.s;

    for(int i = 2; i<n; i++)
    {
        vec g;
        g.x = a[i].f.f-a[1].f.f;
        g.y = a[i].f.s-a[1].f.s;
        if (v.x*g.y != v.x*g.y) {a3 = a[i].s;break;}
    }

    cout<<a[0].s+1<<" "<<a[1].s+1<<" "<<a3+1;
    return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<stdlib.h>

typedef struct palnet
{
	double angel;
	double dis;
	int no;
}p;

double dis();
double angle();
int cmp(const void *a,const void *b);
p s[100005];
long long int x, y, xs, ys;
double dismin=99999999999999;

int main()
{
	int n, i, an1,an2,flag=0;
	double am;
	scanf("%d", &n);
	scanf("%I64d%I64d", &x, &y);
	for (i = 1; i < n;i++)
	{
		scanf("%I64d%I64d", &xs, &ys);
		s[i].angel = angle();
		s[i].dis = dis();
		s[i].no = i;
	}
	qsort(s+1,n-1,sizeof(p), cmp);
	if (n == 100000)
	{
		printf("%lf %lf\n",s[1].angel, s[1].dis);
	}
	for (i = 2; i < n; i++)
	{
		if (n == 100000)
		{
			printf("%lf %lf\n", s[i].angel, s[i].dis);
			printf("%d\n", i);
		}
		if (s[i].angel != s[1].angel)
		{
			printf("1 %d %d\n", s[1].no + 1, s[i].no + 1);
			return 0;
		}
	}
}

double dis()
{
	return sqrt((double)(xs - x)*(xs - x) + (double)(ys - y)*(ys - y));
}

double angle()
{
	return atan((double)(ys - y) / (double)(xs - x));
}

int cmp(const void *a, const void *b)
{
	p *x = (p*)a;
	p *y = (p*)b;
	if (x->dis > y->dis)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}


#define _CRT_SECURE_NO_WARNINGS
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;

typedef struct palnet
{
	long long int x;
	long long int y;
}p;

float dis(p a, p b);
p s[100005];

int main()
{
	int n, a = 0, i, i1, i2, i3, an[2];
	double min=9999999999;

	scanf("%d", &n);
	for (i = 0; i < n;i++)
	{
		scanf("%I64d%I64d", &s[i].x, &s[i].y);
	}
	for (i2 = 1; i2 < n-1; i2++)
	{
		for (i3 = i2 + 1; i3 < n; i3++)
		{
			if (dis(s[0], s[i2]) + dis(s[0], s[i3]) - dis(s[i2], s[i3]) >= 0.0000001)
			{
				if (dis(s[0], s[i2]) + dis(s[0], s[i3]) + dis(s[i2], s[i3]) < min)
				{
					an[0] = i2;
					an[1] = i3;
					min = dis(s[0], s[i2]) + dis(s[0], s[i3]) + dis(s[i2], s[i3]);
				}
			}
		}
	}
	printf("1 %d %d\n", an[0]+1, an[1]+1);
}

float dis(p a, p b)
{
	return sqrt((a.y - b.y)*(a.y - b.y) + (a.x - b.x)*(a.x - b.x));
}


#include<bits/stdc++.h>
#define f first
#define s second
typedef long long ll;
using namespace std;
ll n;
pair<pair<ll, ll>, ll>a[100005];

int main()
{
	ll i, j, k;
	scanf("%I64d", &n);
	for (i = 0; i<n; i++) {
		scanf("%I64d%I64d", &a[i].f.f, &a[i].f.s);
		a[i].s = i + 1;
	}
	sort(a, a + n);
	for (i = 2; i<n; i++) {
		if ((a[0].f.f - a[1].f.f)*(a[1].f.s - a[i].f.s) != (a[1].f.f - a[i].f.f)*(a[0].f.s - a[1].f.s)) {
			printf("%I64d %I64d %I64d", a[0].s, a[1].s, a[i].s);
			return 0;
		}
	}
}


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<stdlib.h>

typedef struct palnet
{
	double angel;
	double dis;
	int no;
}p;

double dis();
double angle();
int cmp(const void *a,const void *b);
p s[100005];
long long int x, y, xs, ys;
double dismin=99999999999999;

int main()
{
	int n, i, an1,an2,flag=0;
	double am;
	scanf("%d", &n);
	scanf("%I64d%I64d", &x, &y);
	for (i = 1; i < n;i++)
	{
		scanf("%I64d%I64d", &xs, &ys);
		s[i].angel = angle();
		s[i].dis = dis();
		s[i].no = i;
	}
	qsort(s,1,n - 1, cmp);
	am = s[1].angel;
	for (i = 1; i < n; i++)
	{
		if (s[i].angel - am <= -0.00000001 || s[i].angel - am >= 0.00000001)
		{
			if (flag)
			{
				break;
			}
			an2 = an1;
			am = s[i].angel;
			dismin = 99999999999999;
			flag = 1;
		}
		if (s[i].angel - am >= -0.00000001&&s[i].angel - am <= 0.00000001)
		{
			if (s[i].dis < dismin)
			{
				dismin = s[i].dis;
				an1 = s[i].no;
			}
		}
	}
	printf("1 %d %d\n", an2 + 1, an1 + 1);
}

double dis()
{
	return sqrt((double)(xs - x)*(xs - x) + (double)(ys - y)*(ys - y));
}

double angle()
{
	return atan((double)(ys - y) / (double)(xs - x));
}

int cmp(const void *a, const void *b)
{
	p *x = (p*)a;
	p *y = (p*)b;
	if (x->angel > y->angel)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<stdlib.h>

typedef struct palnet
{
	double angel;
	double dis;
	int no;
}p;

double dis();
double angle();
int cmp(const void *a,const void *b);
p s[100005];
long long int x, y, xs, ys;
double dismin=99999999999999;

int main()
{
	int n, i, an1,an2,flag=0;
	double am;
	scanf("%d", &n);
	scanf("%I64d%I64d", &x, &y);
	for (i = 1; i < n;i++)
	{
		scanf("%I64d%I64d", &xs, &ys);
		s[i].angel = angle();
		s[i].dis = dis();
		s[i].no = i;
	}
	qsort(s+1,n-1,sizeof(p), cmp);
	if (n == 100000)
	{
		printf("%lf %lf\n",s[1].angel, s[1].dis);
	}
	for (i = 2; i < n; i++)
	{
		if (s[i].angel != s[1].angel)
		{
			printf("1 %d %d\n", s[1].no + 1, s[i].no + 1);
			return 0;
		}
	}
}

double dis()
{
	return sqrt((double)(xs - x)*(xs - x) + (double)(ys - y)*(ys - y));
}

double angle()
{
	return atan((double)(ys - y) / (double)(xs - x));
}

int cmp(const void *a, const void *b)
{
	p *x = (p*)a;
	p *y = (p*)b;
	if (x->dis > y->dis)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}


#define _CRT_SECURE_NO_WARNINGS
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;

typedef struct palnet
{
	int x;
	int y;
}p;

float dis(p a, p b);

int main()
{
	int n, a = 0, i, i1, i2, i3, an[2];
	float min=99999999;
	p s[100005];
	scanf("%d", &n);
	for (i = 0; i < n;i++)
	{
		scanf("%d%d", &s[i].x, &s[i].y);
	}
	for (i2 = 1; i2 < n-1; i2++)
	{
		for (i3 = i2 + 1; i3 < n; i3++)
		{
			if (dis(s[0], s[i2]) + dis(s[0], s[i3]) - dis(s[i2], s[i3]) >= 0.000001)
			{
				if (dis(s[0], s[i2]) + dis(s[0], s[i3]) + dis(s[i2], s[i3]) < min)
				{
					an[0] = i2;
					an[1] = i3;
					min = dis(s[0], s[i2]) + dis(s[0], s[i3]) + dis(s[i2], s[i3]);
				}
			}
		}
	}
	printf("1 %d %d\n", an[0]+1, an[1]+1);
}

float dis(p a, p b)
{
	return sqrt((a.y - b.y)*(a.y - b.y) + (a.x - b.x)*(a.x - b.x));
}


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<stdlib.h>

typedef struct palnet
{
	double angel;
	double dis;
	int no;
}p;

double dis();
double angle();
int cmp(const void *a,const void *b);
p s[100005];
long long int x, y, xs, ys;
double dismin=99999999999999;

int main()
{
	int n, i, an1,an2,flag=0;
	double am;
	scanf("%d", &n);
	scanf("%I64d%I64d", &x, &y);
	for (i = 1; i < n;i++)
	{
		scanf("%I64d%I64d", &xs, &ys);
		s[i].angel = angle();
		s[i].dis = dis();
		s[i].no = i;
	}
	qsort(s+1,n-1,sizeof(p), cmp);
	if (n == 100000)
	{
		printf("%d %d\n",s[99999].angel, s[99999].dis);
	}
	for (i = 2; i < n; i++)
	{
		if (s[i].angel != s[1].angel)
		{
			printf("1 %d %d\n", s[1].no + 1, s[i].no + 1);
			return 0;
		}
	}
}

double dis()
{
	return sqrt((double)(xs - x)*(xs - x) + (double)(ys - y)*(ys - y));
}

double angle()
{
	return atan((double)(ys - y) / (double)(xs - x));
}

int cmp(const void *a, const void *b)
{
	p *x = (p*)a;
	p *y = (p*)b;
	if (x->dis > y->dis)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}


#define _CRT_SECURE_NO_WARNINGS
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;

typedef struct palnet
{
	int x;
	int y;
}p;

float dis(p a, p b);

int main()
{
	int n, a = 0, i, i1, i2, i3, an[2];
	float min=99999999;
	p s[100005];
	scanf("%d", &n);
	for (i = 0; i < n;i++)
	{
		scanf("%d%d", &s[i].x, &s[i].y);
	}
	for (i2 = 1; i2 < n-1; i2++)
	{
		for (i3 = i2 + 1; i3 < n; i3++)
		{
			if (dis(s[0], s[i2]) + dis(s[0], s[i3]) - dis(s[0], s[i3]) >= 0.000001)
			{
				if (dis(s[0], s[i2]) + dis(s[0], s[i3]) + dis(s[0], s[i3]) < min)
				{
					an[0] = i2;
					an[1] = i3;
					min = dis(s[0], s[i2]) + dis(s[0], s[i3]) + dis(s[0], s[i3]);
				}
			}
		}
	}
	printf("1 %d %d", an[0]+1, an[1]+1);
}

float dis(p a, p b)
{
	return sqrt((a.y - b.y)*(a.y - b.y) + (a.x - b.x)*(a.x - b.x));
}


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<stdlib.h>

typedef struct palnet
{
	double angel;
	double dis;
	int no;
}p;

double dis();
double angle();
int cmp(const void *a,const void *b);
p s[100005];
long long int x, y, xs, ys;
double dismin=99999999999999;

int main()
{
	int n, i, an1,an2,flag=0;
	double am;
	scanf("%d", &n);
	scanf("%I64d%I64d", &x, &y);
	for (i = 1; i < n;i++)
	{
		scanf("%I64d%I64d", &xs, &ys);
		s[i].angel = angle();
		s[i].dis = dis();
		s[i].no = i;
	}
	qsort(s+1,n-1,sizeof(p), cmp);
	for (i = 2; i < n; i++)
	{
		if (s[i].angel != s[1].angel)
		{
			printf("1 %d %d\n", s[1].no + 1, s[i].no + 1);
			return 0;
		}
	}
}

double dis()
{
	return sqrt((double)(xs - x)*(xs - x) + (double)(ys - y)*(ys - y));
}

double angle()
{
	return atan((double)(ys - y) / (double)(xs - x));
}

int cmp(const void *a, const void *b)
{
	p *x = (p*)a;
	p *y = (p*)b;
	if (x->dis > y->dis)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}


#define _CRT_SECURE_NO_WARNINGS
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;

typedef struct palnet
{
	long long int x;
	long long int y;
}p;

float dis(p a, p b);
p s[100005];

int main()
{
	int n, a = 0, i, i1, i2, i3, an[2];
	float min=99999999;

	scanf("%d", &n);
	for (i = 0; i < n;i++)
	{
		scanf("%I64d%I64d", &s[i].x, &s[i].y);
	}
	for (i2 = 1; i2 < n-1; i2++)
	{
		for (i3 = i2 + 1; i3 < n; i3++)
		{
			if (dis(s[0], s[i2]) + dis(s[0], s[i3]) - dis(s[i2], s[i3]) >= 0.000001)
			{
				if (dis(s[0], s[i2]) + dis(s[0], s[i3]) + dis(s[i2], s[i3]) < min)
				{
					an[0] = i2;
					an[1] = i3;
					min = dis(s[0], s[i2]) + dis(s[0], s[i3]) + dis(s[i2], s[i3]);
				}
			}
		}
	}
	printf("1 %d %d\n", an[0]+1, an[1]+1);
}

float dis(p a, p b)
{
	return sqrt((a.y - b.y)*(a.y - b.y) + (a.x - b.x)*(a.x - b.x));
}


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<stdlib.h>

typedef struct palnet
{
	double angel;
	double dis;
	int no;
}p;

double dis();
double angle();
int cmp(const void *a,const void *b);
p s[100005];
long long int x, y, xs, ys;
double dismin=99999999999999;

int main()
{
	int n, i, an1,an2,flag=0;
	double am;
	scanf("%d", &n);
	scanf("%I64d%I64d", &x, &y);
	for (i = 1; i < n;i++)
	{
		scanf("%I64d%I64d", &xs, &ys);
		s[i].angel = angle();
		s[i].dis = dis();
		s[i].no = i;
	}
	qsort(s+1,n-1,sizeof(p), cmp);
	am = s[1].angel;
	for (i = 1; i < n; i++)
	{
		if (s[i].angel - am <= -0.00000001 || s[i].angel - am >= 0.00000001)
		{
			if (flag)
			{
				break;
			}
			an2 = an1;
			am = s[i].angel;
			dismin = 99999999999999;
			flag = 1;
		}
		if (s[i].angel - am >= -0.00000001&&s[i].angel - am <= 0.00000001)
		{
			if (s[i].dis < dismin)
			{
				dismin = s[i].dis;
				an1 = s[i].no;
			}
		}
	}
	printf("1 %d %d\n", an2 + 1, an1 + 1);
}

double dis()
{
	return sqrt((double)(xs - x)*(xs - x) + (double)(ys - y)*(ys - y));
}

double angle()
{
	return atan((double)(ys - y) / (double)(xs - x));
}

int cmp(const void *a, const void *b)
{
	p *x = (p*)a;
	p *y = (p*)b;
	if (x->angel > y->angel)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<stdlib.h>

typedef struct palnet
{
	double angel;
	double dis;
	int no;
}p;

double dis();
double angle();
int cmp(const void *a,const void *b);
p s[100005];
long long int x, y, xs, ys;
double dismin=99999999999999;

int main()
{
	int n, i, an1,an2,flag=0;
	double am;
	scanf("%d", &n);
	scanf("%I64d%I64d", &x, &y);
	for (i = 1; i < n;i++)
	{
		scanf("%I64d%I64d", &xs, &ys);
		s[i].angel = angle();
		s[i].dis = dis();
		s[i].no = i;
	}
	qsort(s+1,n-1,sizeof(p), cmp);
	if (n == 100000)
	{
		printf("%lf %lf\n",s[99999].angel, s[99999].dis);
	}
	for (i = 2; i < n; i++)
	{
		if (s[i].angel != s[1].angel)
		{
			printf("1 %d %d\n", s[1].no + 1, s[i].no + 1);
			return 0;
		}
	}
}

double dis()
{
	return sqrt((double)(xs - x)*(xs - x) + (double)(ys - y)*(ys - y));
}

double angle()
{
	return atan((double)(ys - y) / (double)(xs - x));
}

int cmp(const void *a, const void *b)
{
	p *x = (p*)a;
	p *y = (p*)b;
	if (x->dis > y->dis)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<stdlib.h>

typedef struct palnet
{
	double angel;
	double dis;
	int no;
}p;

double dis();
double angle();
int cmp(const void *a,const void *b);
p s[100005];
long long int x, y, xs, ys;
double dismin=99999999999999;

int main()
{
	int n, i, an1,an2,flag=0;
	double am;
	scanf("%d", &n);
	scanf("%I64d%I64d", &x, &y);
	for (i = 1; i < n;i++)
	{
		scanf("%I64d%I64d", &xs, &ys);
		s[i].angel = angle();
		s[i].dis = dis();
		s[i].no = i;
	}
	qsort(s+1,n-1,sizeof(p), cmp);
	if (n == 100000)
	{
		printf("%lf %lf\n",s[1].angel, s[1].dis);
	}
	for (i = 2; i < n; i++)
	{
		if (s[i].angel != s[1].angel)
		{
			if (n == 100000)
			printf("%lf %lf\n", s[i].angel, s[i].dis);
			printf("1 %d %d\n", s[1].no + 1, s[i].no + 1);
			return 0;
		}
	}
}

double dis()
{
	return sqrt((double)(xs - x)*(xs - x) + (double)(ys - y)*(ys - y));
}

double angle()
{
	return atan((double)(ys - y) / (double)(xs - x));
}

int cmp(const void *a, const void *b)
{
	p *x = (p*)a;
	p *y = (p*)b;
	if (x->dis > y->dis)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<stdlib.h>

typedef struct palnet
{
	double angel;
	double dis;
	int no;
}p;

double dis();
double angle();
int cmp(const void *a,const void *b);
p s[100005];
long long int x, y, xs, ys;
double dismin=99999999999999;

int main()
{
	int n, i, an1,an2,flag=0;
	double am;
	scanf("%d", &n);
	scanf("%I64d%I64d", &x, &y);
	for (i = 1; i < n;i++)
	{
		scanf("%I64d%I64d", &xs, &ys);
		s[i].angel = angle();
		s[i].dis = dis();
		s[i].no = i;
	}
	qsort(s+1,n-1,sizeof(p), cmp);
	if (n == 100000)
	{
		printf("%lf %lf\n",s[1].angel, s[1].dis);
	}
	for (i = 2; i < n; i++)
	{
		if (s[i].angel != s[1].angel)
		{
			printf("%lf %lf\n", s[i].angel, s[i].dis);
			printf("1 %d %d\n", s[1].no + 1, s[i].no + 1);
			return 0;
		}
	}
}

double dis()
{
	return sqrt((double)(xs - x)*(xs - x) + (double)(ys - y)*(ys - y));
}

double angle()
{
	return atan((double)(ys - y) / (double)(xs - x));
}

int cmp(const void *a, const void *b)
{
	p *x = (p*)a;
	p *y = (p*)b;
	if (x->dis > y->dis)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<stdlib.h>

typedef struct palnet
{
	double angel;
	double dis;
	int no;
}p;

double dis();
double angle();
int cmp(const void *a,const void *b);
p s[100005];
long long int x, y, xs, ys;
double dismin=99999999999999;

int main()
{
	int n, i, an1,an2,flag=0;
	double am;
	scanf("%d", &n);
	scanf("%I64d%I64d", &x, &y);
	for (i = 1; i < n;i++)
	{
		scanf("%I64d%I64d", &xs, &ys);
		s[i].angel = angle();
		s[i].dis = dis();
		s[i].no = i;
	}
	qsort(s+1,n-1,sizeof(p), cmp);
	if (n == 100000)
	{
		printf("%lf %lf\n",s[1].angel, s[1].dis);
	}
	for (i = 2; i < n; i++)
	{
		if (n == 100000)
			printf("%lf %lf\n", s[i].angel, s[i].dis);
		if (s[i].angel != s[1].angel)
		{
			printf("1 %d %d\n", s[1].no + 1, s[i].no + 1);
			return 0;
		}
	}
}

double dis()
{
	return sqrt((double)(xs - x)*(xs - x) + (double)(ys - y)*(ys - y));
}

double angle()
{
	return atan((double)(ys - y) / (double)(xs - x));
}

int cmp(const void *a, const void *b)
{
	p *x = (p*)a;
	p *y = (p*)b;
	if (x->dis > y->dis)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}


#pragma warning (disable : 4996)
#pragma comment(linker, "/STACK:36777216")

#include <stdlib.h>
#include <iostream>
#include <vector>
#include <string>
#include <assert.h>
#include <stack>
#include <algorithm>
#include <ios>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <queue>
#include <set>
#include <functional>
#include <cmath>
#include <sstream>
#include <map>
#include <memory.h>
#include <stdio.h>
#include <cassert>
#include <string.h>
#include <deque>
#include <ctime>
#include <list>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
#define sqr(x) ((x) * (x))

const ll INF = 1e17 + 7;
const ll MOD = 1e9 + 7;

ll v_prod(pll &a, pll &b){
	return a.first * b.second - a.second * b.first;
}

pll operator - (pll& a, pll& b){
	return{ a.first - b.first, a.second - b.second };
}

bool operator == (pll a, pll b){
	return a.first == b.first && a.second == b.second;
}

ll d_dist(pll a, pll b){
	return sqr(a.first - b.first) + sqr(a.second - b.second);
}

ll sssgn(ll x){
	if (x < 0) return 0;
	return 1;
}

bool is_into(pll a, pll b, pll c, pll d){
	if (sssgn(v_prod(b - a, d - a)) == sssgn(v_prod(c - b, d - b)) &&
		sssgn(v_prod(b - a, d - a)) == sssgn(v_prod(a - c, d - c)))
		return true;
	if (v_prod(c - a, d - a) == 0 && d_dist(d, a) < d_dist(c, a))
		return true;
	if (v_prod(c - a, d - b) == 0 && d_dist(d, b) < d_dist(c, b))
		return true;
	return false;
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout << fixed << setprecision(14);
#ifdef DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#else
	//freopen(CONTEST ".in", "r", stdin);
	//freopen(CONTEST ".out", "w", stdout);
#endif

	int n;
	cin >> n;
	vector<pair<ll, ll>> v;
	for (int i = 0; i < n; ++i){
		int x, y;
		cin >> x >> y;
		v.push_back({ x, y });
	}

	pair<ll, ll> a = v[0], b = v[1];
	int ia = 0, ib = 1, ic = 2;
	for (int i = 2; i < n; ++i){
		pll c = v[i];
		if (v_prod(c - a, b - a) == 0ll){
			if (d_dist(a, c) < d_dist(b, c)){
				b = c;
				ib = i;
			}
		}
	}
	pll c;
	for (int i = 0; i < n; ++i){
		c = v[i];
		ic = i;
		if (v_prod(b - a, c - a) != 0)
			break;
	}
	for (int i = 0; i < n; ++i){
		pll d = v[i];
		if (d == a || d == b || d == c)
			continue;
		if (is_into(a, b, c, d)){
			c = d;
			ic = i;
		}
	}
	cout << ia + 1 << ' ' << ib + 1 << ' ' << ic + 1 << endl;

	return 0;
};