#include <bits/stdc++.h>
using namespace std;
template <class T>
bool uin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
bool uax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
const int MAXN = 100000;
int a[MAXN], b[MAXN], c[MAXN], d[MAXN];
struct TResult {
  int minx, qx;
  TResult(int minx = 0, int qx = 0) : minx(minx), qx(qx) {}
  TResult operator+(const TResult &r) const {
    TResult res(min(minx, r.minx));
    if (minx == res.minx) res.qx += qx;
    if (r.minx == res.minx) res.qx += r.qx;
    return res;
  }
};
struct TNode {
  int L, R;
  int left, right;
  int val;
  TResult res;
  TNode(int L = 0, int R = 0)
      : L(L), R(R), left(-1), right(-1), val(0), res() {}
};
int len[2 * MAXN];
TNode t[5 * MAXN];
int tc = 0;
int buildTree(int L, int R) {
  int node = tc++;
  t[node] = TNode(L, R);
  t[node].res = TResult(0, len[R] - len[L]);
  if (R - L == 1) return node;
  int M = (L + R) / 2;
  t[node].left = buildTree(L, M);
  t[node].right = buildTree(M, R);
  return node;
}
void addx(int node, int x) {
  t[node].val += x;
  t[node].res.minx += x;
}
void push(int node) {
  int x = t[node].val;
  addx(t[node].left, x);
  addx(t[node].right, x);
  t[node].val = 0;
}
void addSeg(int node, int L, int R, int x) {
  if (max(L, t[node].L) >= min(R, t[node].R)) return;
  if (L <= t[node].L && t[node].R <= R) {
    addx(node, x);
    return;
  }
  push(node);
  addSeg(t[node].left, L, R, x);
  addSeg(t[node].right, L, R, x);
  t[node].res = t[t[node].left].res + t[t[node].right].res;
}
struct TEvent {
  int x, l, r, t;
  TEvent(int x = 0, int l = 0, int r = 0, int t = 0) : x(x), l(l), r(r), t(t) {}
  bool operator<(const TEvent &ev) const { return x < ev.x; }
};
int main() {
  ios::sync_with_stdio(false);
  cout.precision(10);
  cout << fixed;
  int N, M, K;
  cin >> N >> M >> K;
  for (int i = 0; i < (int)(M); ++i) {
    cin >> a[i] >> b[i] >> c[i] >> d[i];
    --a[i];
    --b[i];
  }
  bool win = false;
  for (int tt = 1; !win && tt <= K; tt *= 2) {
    tc = 0;
    vector<int> x, y;
    map<int, int> rx, ry;
    for (int i = 0; i < (int)(M); ++i) {
      x.push_back(a[i] / tt);
      y.push_back(b[i] / tt);
      x.push_back(c[i] / tt);
      y.push_back(d[i] / tt);
    }
    x.push_back(0);
    x.push_back(N / tt);
    y.push_back(0);
    y.push_back(N / tt);
    sort((x).begin(), (x).end());
    sort((y).begin(), (y).end());
    x.erase(unique((x).begin(), (x).end()), x.end());
    y.erase(unique((y).begin(), (y).end()), y.end());
    for (int i = 0; i < (int)(x.size()); ++i) rx[x[i]] = i;
    for (int i = 0; i < (int)(y.size()); ++i) ry[y[i]] = i;
    for (int i = 0; i < (int)(y.size()); ++i) len[i] = y[i];
    int root = buildTree(0, y.size() - 1);
    vector<TEvent> evs;
    for (int i = 0; i < (int)(M); ++i) {
      evs.push_back(TEvent(rx[a[i] / tt], ry[b[i] / tt], ry[d[i] / tt], 1));
      evs.push_back(TEvent(rx[c[i] / tt], ry[b[i] / tt], ry[d[i] / tt], -1));
    }
    sort((evs).begin(), (evs).end());
    long long ans = 0;
    int px = 0;
    for (TEvent ev : evs) {
      TResult res = t[root].res;
      if (res.minx == 0)
        ans += 1LL * (x[ev.x] - x[px]) * (N / tt - res.qx);
      else
        ans += (x[ev.x] - x[px]) * (N / tt);
      addSeg(root, ev.l, ev.r, ev.t);
      px = ev.x;
    }
    win |= ans & 1;
  }
  cout << (win ? "Hamed" : "Malek") << '\n';
  return 0;
}
