#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 7;
int n, m, k, t, f[N], w1[N], w2[N], f1[N], f2[N], f3[N];
vector<int> v1[N], v2[N];
struct node {
  int a, b, c, d;
} e[N], g[N];
inline int read() {
  int num = 0;
  char g = getchar();
  while (g < 48 || 57 < g) g = getchar();
  while (47 < g && g < 58)
    num = (num << 1) + (num << 3) + g - 48, g = getchar();
  return num;
}
inline int getpos1(int v) {
  int l = 1, r = w1[0], p = 0;
  while (l <= r) {
    int d = (l + r) >> 1;
    if (w1[d] >= v)
      p = d, r = d - 1;
    else
      l = d + 1;
  }
  return p;
}
inline int getpos2(int v) {
  int l = 1, r = w2[0], p = 0;
  while (l <= r) {
    int d = (l + r) >> 1;
    if (w2[d] >= v)
      p = d, r = d - 1;
    else
      l = d + 1;
  }
  return p;
}
inline int getpos3(int v) {
  int l = 1, r = w1[0], p = 0;
  while (l <= r) {
    int d = (l + r) >> 1;
    if (w1[d] <= v)
      p = d, l = d + 1;
    else
      r = d - 1;
  }
  return p;
}
inline int getpos4(int v) {
  int l = 1, r = w2[0], p = 0;
  while (l <= r) {
    int d = (l + r) >> 1;
    if (w2[d] <= v)
      p = d, l = d + 1;
    else
      r = d - 1;
  }
  return p;
}
inline int getans(int l, int r) {
  if (l >= r) return 0;
  return (r / k - l / k);
}
inline void pushdown(int t) {
  f1[t << 1] += f2[t], f1[t << 1 | 1] += f2[t], f2[t << 1] += f2[t],
      f2[t << 1 | 1] += f2[t], f2[t] = 0;
}
inline void build(int l, int r, int t) {
  f1[t] = f2[t] = 0;
  if (l == r) {
    f3[t] = getans(w1[l - 1], w1[l]);
    return;
  }
  int d = (l + r) >> 1;
  build(l, d, t << 1), build(d + 1, r, t << 1 | 1);
  f1[t] = min(f1[t << 1], f1[t << 1 | 1]), f3[t] = 0;
  if (f1[t] == f1[t << 1]) f3[t] ^= f3[t << 1];
  if (f1[t] == f1[t << 1 | 1]) f3[t] ^= f3[t << 1 | 1];
}
inline void addsum(int l, int r, int t, int ql, int qr, int c) {
  if (l == ql && r == qr) {
    f1[t] += c, f2[t] += c;
    return;
  }
  int d = (l + r) >> 1;
  pushdown(t);
  if (ql <= d) addsum(l, d, t << 1, ql, min(d, qr), c);
  if (d + 1 <= qr) addsum(d + 1, r, t << 1 | 1, max(d + 1, ql), qr, c);
  f1[t] = min(f1[t << 1], f1[t << 1 | 1]), f3[t] = 0;
  if (f1[t] == f1[t << 1]) f3[t] ^= f3[t << 1];
  if (f1[t] == f1[t << 1 | 1]) f3[t] ^= f3[t << 1 | 1];
}
inline bool solve(int d) {
  w1[0] = 0, w2[0] = 0, w1[++w1[0]] = 0, w1[++w1[0]] = n, w2[++w2[0]] = 0,
  w2[++w2[0]] = n, k = d;
  for (int i = 1; i <= m * 2 + 2; i++) v1[i].resize(0), v2[i].resize(0);
  for (int i = 1; i <= m; i++)
    g[i].a = e[i].a - 1, g[i].b = e[i].b - 1, g[i].c = e[i].c, g[i].d = e[i].d;
  for (int i = 1; i <= m; i++)
    w1[++w1[0]] = g[i].a, w1[++w1[0]] = g[i].c, w2[++w2[0]] = g[i].b,
    w2[++w2[0]] = g[i].d;
  sort(w1 + 1, w1 + w1[0] + 1), sort(w2 + 1, w2 + w2[0] + 1);
  int ans = 0;
  for (int i = 1; i <= m; i++) {
    g[i].a = getpos3(g[i].a) + 1, g[i].b = getpos4(g[i].b) + 1,
    g[i].c = getpos1(g[i].c), g[i].d = getpos2(g[i].d);
    v1[g[i].b].push_back(i), v2[g[i].d].push_back(i);
  }
  build(1, 2 * m + 2, 1);
  for (int i = 1; i <= 2 * m + 2; i++) {
    for (int j = 0; j < v1[i].size(); j++)
      addsum(1, 2 * m + 2, 1, g[v1[i][j]].a, g[v1[i][j]].c, 1);
    ans ^= (getans(w2[i - 1], w2[i]) & 1) * (f3[1] ^ (n / k));
    for (int j = 0; j < v2[i].size(); j++)
      addsum(1, 2 * m + 2, 1, g[v2[i][j]].a, g[v2[i][j]].c, -1);
  }
  return (ans & 1);
}
int main() {
  cin >> n >> m >> k;
  while ((1 << (t + 1)) <= k) t++;
  int res = 0;
  for (int i = 1; i <= m; i++)
    e[i].a = read(), e[i].b = read(), e[i].c = read(), e[i].d = read();
  for (int i = 0; i <= t; i++) {
    res ^= solve(1 << i);
    if (res) {
      puts("Hamed");
      return 0;
    }
  }
  puts("Malek");
  return 0;
}
