Go: package main

import (
	"bufio"
	"os"
	"strings"
	"fmt"
)

var scanner = bufio.NewScanner(os.Stdin)

func nextString() string {
	scanner.Scan()
	return scanner.Text()
}

func cipher(text string, direction int, int_shift int) string {
	shift, offset := rune(int_shift), rune(26)
	runes := []rune(text)
	for index, char := range runes {
		switch direction {
		case 1:
			if char >= 'a' && char <= 'z'-shift || char >= 'A' && char <= 'Z'-shift {
				char = char + shift
			} else if char > 'z'-shift && char <= 'z' || char > 'Z'-shift && char <= 'Z' {
				char = char + shift - offset
			}
		case -1:
			if char >= 'a'+shift && char <= 'z' || char >= 'A'+shift && char <= 'Z' {
				char = char - shift
			} else if char >= 'a' && char < 'a'+shift || char >= 'A' && char < 'A'+shift {
				char = char - shift + offset
			}
		}
		runes[index] = char
	}
	return string(runes)
}

func main() {
	for {
		infos := strings.Split(nextString(), " ")
		plain := make([]string, len(infos))
		if len(infos) == 0 {
			break
		}
		// println(infos)
		Decryption:
			for i := 0; i < 26; i++ {
				for j := range infos {
					plain[j] = cipher(infos[j], 1, i)
				}
				for j := range plain {
					if plain[j] == "this" || plain[j] == "that" || plain[j] == "the" {
						break Decryption
					}
				}
			}
			fmt.Println(strings.Join(plain, " "))
	}
}

C++: #include <iostream>
#include <string>
#include <cstdio>

using namespace std;

bool tJudge(string text);
void tShift(string &text);

int main(void) {
	string text;
	
	getline(cin, text);
	
	while(1) {
		if( tJudge(text) ) {
			cout << text << endl;
			break;
		} else {
			tShift(text);
		}
	}
	
	return 0;
}

bool tJudge(string text) {
	string word[3] = {"the", "this", "that"};
	for(int i = 0; i < 3; i++) {
		if(text.find(word[i], 0) != string::npos) {
			return true;
		} else {
			return false;
		}
	}
}

void tShift(string &text) {
	for(unsigned int i = 0; i < text.size(); i++) {
		if ( text[i] >= 'a' && text[i] < 'z') {
			text[i]++;
		} else if (text[i] == 'z') {
			text[i] = 'a';
		}
	}
}

C++: #include <iostream>
#include <cstring>
using namespace std;

int main(){
	string str[100];
	int k = 0;
	int zure[100];
	bool flag[100] = {false};
	while(getline(cin, str[k])){
		for(int j = 0; j < 26; j++){
			for(int i = 0; i < str[k].size()-2; i++){
				if(str[k][i] == 't'+j && str[k][i+1] == 'h'+j && str[k][i+2] == 'e'+j){
					zure[k] = j;
					flag[k] = true;
					break;
				}
			}
			if(flag[k] == true){
				k++;
				break;
			}
			for(int i = 0; i < str[k].size()-3; i++){
				if(str[k][i] == 't'+j && str[k][i+1] == 'h'+j && str[k][i+2] == 'i'+j && str[k][i+3] == 's'+j){
					zure[k] = j;
					flag[k] = true;
					break;
				}
			}
			if(flag[k] == true){
				k++;
				break;
			}
			for(int i = 0; i < str[k].size()-3; i++){
				if(str[k][i] == 't'+j && str[k][i+1] == 'h'+j && str[k][i+2] == 'a'+j && str[k][i+3] == 't'+j){
					zure[k] = j;
					flag[k] = true;
					break;
				}
			}
			if(flag[k] == true){
				k++;
				break;
			}
		}
		k++;
	}
	for(int j = 0; j < k; j++){
		for(int i = 0; i < str[j].size(); i++){
			if(str[j][i] >= 'a' && str[j][i] <= 'z'){
				str[j][i] = str[j][i]-zure[j];
				if(str[j][i] < 'a'){
					str[j][i] = str[j][i]+26;
				}
			}
		}
		cout << str[j] << endl;
	}
}

C++: #define _USE_MATH_DEFINES
#include <iostream>
#include <sstream>
#include <cmath>
#include <algorithm>
#include <queue>
#include <stack>

using namespace std;

int main()
{
	string str;
	//while(getline(cin,str)){
	cin >> str;
		for(int rot = 0;rot< 'z' - 'a' + 1;rot++){
			string tmp = str;
			for(int i=0; i<str.size() - 1; i++){
				if(tmp[i] == ' ') continue;
				tmp[i] = (rot + tmp[i]-'a') % ('z' - 'a' + 1) + 'a';
			}
			//cout << tmp << endl;
			if(tmp.find("the") != string::npos
				|| tmp.find("this") != string::npos
				|| tmp.find("that") != string::npos)
			{
				cout << tmp << endl;
			}
		}
	//}
	return 0;
}

C++: #include <iostream>
#include <string>

using namespace std;

int main()
{
    string s;

    while (getline(cin, s)) {
        while (s.find("the") == s.npos &&
                    s.find("this") == s.npos &&
                    s.find("that") == s.npos) {
            for (int i = 0; i < s.size(); i++) {
                if (s[i] >= 'a' || 'y' >= s[i]) {
                    s[i]++;
                } else {
                    s[i] = 'a';
                }
            }
        }
        cout << s << endl;
    }

    return 0;
}

C++: # include <iostream>
# include <algorithm>
# include <vector>
# include <string>
# include <set>
# include <map>
# include <cmath>
# include <iomanip>
# include <functional>
# include <utility>
# include <stack>
# include <queue>
# include <list>
# include <bitset>
# include <complex>
# include <numeric>
using namespace std;
using LL = long long;
using ULL = unsigned long long;
constexpr long long MOD = 1000000000 + 7;
constexpr int INF = 2000000000;
constexpr int HINF = INF / 2;
constexpr double DINF = 100000000000000000.0;
constexpr long long LINF = 9223372036854775807;
constexpr long long HLINF = 4500000000000000000;
const double PI = acos(-1);

int main() {
	string s;
	while (getline(cin, s)) {
		bool update = true;
		while (update) {
			for (int i = 0; i < s.size(); i++) {
				if (s.substr(i, 3) == "the") {
					cout << s << endl;
					update = false;
					break;
				}
				if (s.substr(i, 4) == "this") {
					cout << s << endl;
					update = false;
					break;
				}
				if (s.substr(i, 4) == "that") {
					cout << s << endl;
					update = false;
					break;
				}
			}
			for (int i = 0; i < s.size(); i++) {
				if (!('a' <= s[i] && s[i] <= 'z')) {
					continue;
				}
				if (s[i] == 'z')s[i] = 'a';
				else s[i] = char(s[i] + 1);
			}
			//cout << s << endl;
		}
	}
}

C++: #include <iostream>
#include <string>

using namespace std;

void solve()
{
	string s;
	while(getline(cin, s))
	{
		for(int i = 0; i < 26; ++i)
		{
			for(int j = 0; j < s.size(); ++j)
			{
				if('a' <= s[j] && s[j] <= 'z')
				{
					if(s[j] == 'z')
					{
						s[j] = 'a';
					}
					else
					{
						++s[j];
					}
				}
			}
			if(s.find("this") != string::npos || s.find("that") != string::npos || s.find("the") != string::npos)
			{
				cout << s << endl;
				break;
			}
		}
	}
}

int main()
{
	solve();
	return(0);
}

C++: #include<iostream>
#include<string>

using namespace std;

string thi[100],tha[100],the[100];

string change_str(string ch,int mov);
int set(void);

int main()
{
	int i,j;
	char ch[100];
	
	set();
	for(;cin.getline(ch,81);)
	{
		for(i=0;i<27;i++)
		{
			int se;
			se=string(ch).find(thi[i],0);
			if(se!=string::npos)
				break;
			se=string(ch).find(tha[i],0);
			if(se!=string::npos)
				break;
			se=string(ch).find(the[i],0);
			if(se!=string::npos)
				break;
		}
		
		string ans;
		
		ans=change_str(string(ch),26-i);
		
		cout << ans << endl;
		
		string(ch)="";
	}
}

int set(void)
{
	int i,j;
	thi[0]="this";
	tha[0]="that";
	the[0]="the";
	
	for(i=1;i<27;i++)
	{
		int a,b,c;
		thi[0]=change_str(thi[0],1);
		tha[0]=change_str(tha[0],1);
		the[0]=change_str(the[0],1);
		
		thi[i]=thi[0];
		tha[i]=tha[0];
		the[i]=the[0];
	}
	return 0;
}

string change_str(string change,int mov)
{
	for(int i=0;i<mov;i++)
	{
		for(int j=0;j<change.size();j++)
		{
			int a;
			a=int(change[j]);
			if(a>95 && a<123)
			{
				change[j]++;
				if(a==122)
					change[j]-=26;
			}
		}
	}
	return change;
}