/* ========================================================================
   $File: $
   $Date: $
   $Revision: $
   $Creator: Creative GP $
   $Notice: (C) Copyright 2018 by Creative GP. All Rights Reserved. $
   ======================================================================== */

#pragma warning(disable:4786)
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>

#include <cstdlib>
#include <cmath>

#include <iterator>
#include <algorithm>
#include <utility>
#include <set>
#include <unordered_set>
#include <vector>
#include <map>
#include <stack>
#include <queue>
#include <numeric>
#include <climits>
using namespace std;

template<class X, class Y> bool operator==(pair<X,Y>& lhs, pair<X,Y>& rhs) {
    return lhs.first == rhs.first && lhs.second == rhs.second;
}

template<class X, class Y> ostream& operator<<(ostream& os, pair<X,Y>& val) {
    os << "(" << val.first << ", " << val.second << ")";
    return os;
}

template<class X> ostream& operator<<(ostream& os, vector<X>& val) {
    os << "{";
    for (X e : val)
        os << e << " ";
    os << "}" << endl;
    return os;
}

template<class T> void SetPrint(set<T> rseti) {
    for (typename set<T>::iterator iti = rseti.begin(); iti != rseti.end(); iti++)
    { printf("%3d ", *iti); }
    printf("\n");
}

template<class T> void VectorPrint(vector<T>& vi) {
    cout << "{";
    for (T e : vi)
        cout << e << " ";
    cout << "}" << endl;
}

#define v__print VectorPrint 
#define s__print SetPrint

template<class T> bool contains(const vector<T>& vec, const T& val) {
    return find(vec.begin(), vec.end(), val) != vec.end();
}

// 和集合の計算
template<class T> set<T> Union(set<T>& rsettA, set<T>&rsettB) {
    set<T> settUnion(rsettA);
    for (auto itt : rsettB) {
        settUnion.insert(itt);
    }
    return settUnion;
}
// 積集合の計算
template<class T> set<T> Product(set<T>& rsettA, set<T>&rsettB) {
    set<T> settProduct;
    for (auto itt : rsettB) {
        if (rsettA.find(itt) != rsettA.end()) {
            settProduct.insert(itt);
        }
    }
    return settProduct;
}
// 補集合の計算
template<class T> set<T> Complement(set<T>& rsettA, set<T>&rsettB) {
    set<T> settComplement(rsettA);
    for (auto itt : rsettB) {
        settComplement.erase(itt);
    }
    return settComplement;
}

typedef long ll;
typedef unsigned long long ull;

#define gt(a, b) (((a)>(b))?(a):(b))
#define ls(a, b) (((a)<(b))?(a):(b))


#define rep(i, n) for(ll i = 0; i < (ll)(n); i++)

#define val(a) (a).begin(), (a).end()
#define uniq(a) sort(val(a)); a.erase(unique(val(a)), a.end() );
#define rm_byval(a, b) a.erase(remove(a.begin(), a.end(), b), a.end());

vector<vector<ll>> dupp(ll len, ll mag) {
    vector<ll> idx(len, 1);
    vector<vector<ll>> ans;
    ll maxi = pow(mag, len);
    ll counti = 0;
    while (count(idx.begin(), idx.end(), mag) != len) {
        ans.push_back(idx);

        if (idx.back() == mag) {
            for (ll i = len-1; len >= 0; --i) {
                if (idx[i] == mag) {
                    idx[i] = i==len-1 ? 0 : 1;
                } else {
                    ++idx[i];
                    break;
                }
            }
        }

        ++idx[idx.size()-1];
        ++counti;
    }
    ans.push_back(idx);
    return ans;


}

// #define DEBUG

#define LL(x) ll x = 0
#define LLI(x) LL(x); cin >> x
#define STR(x) string x = ""

// inline ll aS(int x1, int y1) {
//     if (y1 < 0 || x1 < 0) return 0; 
//     return As[(y1)*W + (x1)];
// }

// inline ll dS(int x, int y, int w, int h) {
//     return (aS(x+w-1, y+h-1)
//             + aS(x-1, y-1)
//             - aS(x+w-1, y-1)
//             - aS(x-1, y+h-1)
//             );
// }

/*
  solve x =
  x == 0 ? 0
  loop xで乗れる車 as car:
      max = max 1/car.velocity
  solve (x-1) + max
 */

#define x fi
#define v se.fi
#define d se.se

int main () {
    string s; cin >> s;

    bool ans = true;
  
  	if (s.length() < 2)
{
            cout << "No" << endl;
            return 0;
        }
      
    for (int i = 0; i < s.length(); ++i) {
        if (s.length() <= i+1) {
            cout << "No" << endl;
            return 0;
        }
        
        if (s[i] == 'h' && s[i+1] == 'i') {
            i++;
            continue;
        } else {
            cout << "No" << endl;
            return 0;
        }
        
    }

    cout << "Yes" << endl;
    
    return 0;
}



Measured memory_bytes: 256