import std.algorithm;
import std.array;
import std.ascii;
import std.container;
import std.conv;
import std.math;
import std.numeric;
import std.range;
import std.stdio;
import std.string;
import std.typecons;

void log(A...)(A arg) {
    stderr.writeln(arg);
}
int size(T)(in T s) {
    return cast(int)s.length;
}

real dot(T)(in T[] a, in T[] b) {
    assert(a.length == b.length);
    return reduce!((sum, i) => sum + a[i] * b[i])(cast(T)0, iota(0, a.length, 1));
}
class Matrix(T) {
    int H, W;
    T[] data;
    this(int H, int W) {
        this.H = H;
        this.W = W;
        this.data = new T[H * W];
    }
    this(int H, int W, T init) {
        this(H, W);
        foreach (i; 0 .. H) foreach (j; 0 .. W) at(i, j) = init;
    }
    this(int H, int W, T delegate(int, int) init) {
        this(H, W);
        foreach (i; 0 .. H) foreach (j; 0 .. W) at(i, j) = init(i, j);
    }
    this(in Matrix A) {
        this.H = A.H;
        this.W = A.W;
        this.data = A.data.dup;
    }
        ref T at(int i, int j) { return data[i * W + j]; }
        T get(int i, int j) const { return data[i * W + j]; }
        const(T[]) get(int i) const { return data[i * W .. (i + 1) * W]; }
    Matrix swapRows(int i, int j) { foreach (k; 0 .. W) swap(at(i, k), at(j, k)); return this; }
    Matrix swapCols(int i, int j) { foreach (k; 0 .. H) swap(at(k, i), at(k, j)); return this; }
    Matrix transpose() const { return new Matrix(H, W, (i, j) => get(j, i)); }
    Matrix opBinary(string op)(in Matrix B) const if (op == "+" || op == "-") {
        assert(H == B.H && W == B.W);
        return new Matrix(H, W, (i, j) => mixin("get(i, j) " ~ op ~ " B.get(i, j)"));
    }
    Matrix opBinary(string op)(in Matrix B) const if (op == "*") {
        assert(W == B.H);
        auto X = B.transpose;
        auto A = new Matrix(H, B.W, 0);
        foreach (i; 0 .. H) foreach (j; 0 .. X.H) {
            foreach (k; 0 .. W) {
                A.at(i, j) += get(i, k) * X.get(j, k);
            }
        }
        return A;
    }
    T[] opBinary(string op)(in T[] b) const if (op == "*") {
        auto y = new T[b.length];
        foreach (i; 0 .. H) y[i] = dot(get(i), b);
        return y;
    }
    override string toString() const { return to!string(iota(0, H, 1).map!((i) => data[i * W .. (i + 1) * W]).array); }
}

immutable EPS = 1e-4;
bool EQ(real a, real b) { return abs(a - b) < EPS; }
struct LU_Info { Matrix!real L, U, P; }
/*
   LU????????§??£.
   LU = PM ?????¨????????§???L, U, P)??§????????????. ???????????????, U???????????´???????§?????????? ????´?????????§????????????, P??????????????????????¬?????????§????????????????????\??§????????¨?????§???????????£????????????(ex. [[0, 1, 0], [1, 0, 0], [0, 0, 1]])
   A????¢?????±???£??????????????¨assert(! EQ(A.get(p, i), 0)) ?????§???????????? ?????§??????????????§???
 */
LU_Info LU_decomposition(Matrix!real A) {
    assert(A.H == A.W);
    int N = A.H;
    auto L = new Matrix!real(N, N, 0);
    auto P = new Matrix!real(N, N, 0);
    auto used = new bool[N];
    for (int i = 0; i < N; i++) {
        int p = -1;
        for (int j = 0; j < N; j++) {
            if (used[j]) continue;
            if (p < 0 || abs(A.get(j, i)) > abs(A.get(p, i))) p = j;
        }
        assert(0 <= p && p < N);
        if (EQ(A.get(p, i), 0)) throw(new Exception("not regular"));
        P.at(i, p) = 1;
        L.at(p, i) = 1;
        used[p] = true;
        real x = A.get(p, i);
        for (int k = 0; k < N; k++) {
            if (used[k]) continue;
            real y = A.get(k, i) / x;
            L.at(k, i) = y;
            for (int l = i; l < N; l++) {
                A.at(k, l) -= y * A.get(p, l);
            }
        }
    }
    return LU_Info(P * L, P * A, P);
}

/*
   LU????????§??£?????§?????±???LU_Info??§???????????¨???????????±???, ?¨???£??¶???????????\??????Ax = b ??§?????§??£??????
 */
real[] LU_backwardSubstitution(in LU_Info info, in real[] b) {
    auto L = info.L, U = info.U, P = info.P;
    auto N = L.H;
    auto c = P * b;
    auto y = new real[N];
    foreach (j; 0 .. N) {
        y[j] = c[j];
        foreach (i; j + 1 .. N) {
            c[i] -= L.get(i, j) * y[j];
        }
    }
    auto x = new real[N];
    foreach_reverse (j; 0 .. N) {
        auto k = U.get(j, j);
        x[j] = y[j] / k;
        foreach (i; 0 .. j) {
            y[i] -= U.get(i, j) * x[j];
        }
    }
    return x;
}

void main() {
    real x0, y0, z0; readf("%s %s %s\n", &x0, &y0, &z0);
    real x1, y1, z1; readf("%s %s %s\n", &x1, &y1, &z1);
    real xa, ya, za; readf("%s %s %s\n", &xa, &ya, &za);
    real xb, yb, zb; readf("%s %s %s\n", &xb, &yb, &zb);
    real xc, yc, zc; readf("%s %s %s\n", &xc, &yc, &zc);
    auto A = new Matrix!real(3, 3);
    A.at(0, 0) = xb - xa; A.at(0, 1) = xc - xa; A.at(0, 2) = x0 - x1;
    A.at(1, 0) = yb - ya; A.at(1, 1) = yc - ya; A.at(1, 2) = y0 - y1;
    A.at(2, 0) = zb - za; A.at(2, 1) = zc - za; A.at(2, 2) = z0 - z1;
    try {
        auto LU = LU_decomposition(A);
        auto y = LU_backwardSubstitution(LU, [x0 - xa, y0 - ya, z0 - za]);
        auto s = y[0], t = y[1], u = y[2];
        if (-EPS <= s && s <= 1 + EPS && -EPS <= t && t <= 1 + EPS && -EPS <= u && u <= 1 + EPS && s + t <= 1 + EPS) {
            writeln("MISS");
        } else {
            writeln("HIT");
        }
    } catch (Exception e) {
        writeln("HIT");
    }
}

Measured memory_bytes: 2560