Go: package main

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

var scanner = bufio.NewScanner(os.Stdin)

func main() {
	for scanner.Scan() {
		var result string
		line := scanner.Text()
		key := make(map[string]string)

		var i int32
		for ; i < 52; i++ {
			makeKey(key, i)
			result = decode(key, line)

			if strings.Contains(result, "the") {
				break
			} else if strings.Contains(result, "this") {
				break
			} else if strings.Contains(result, "that") {
				break
			}
		}

		fmt.Println(result)
	}
}

func makeKey(key map[string]string, shift int32) {
	for i := 'a'; i <= 'z'; i++ {
		cipher := (i + shift)
		if cipher > 'z' {
			cipher = cipher%'z' + 'a' - 1
		} else if cipher < 'a' {
			cipher = cipher + ('z' - 'a') + 1
		}
		key[string(i)] = string(cipher)
	}
}

func decode(key map[string]string, cipher string) string {
	var result string
	for _, v := range cipher {
		if key[string(v)] != "" {
			result += key[string(v)]
		} else {
			result += string(v)
		}
	}
	return result
}

C++: #include <bits/stdc++.h>
using namespace std;

#define times(n, i) uptil(0, n, i)
#define upto(f, t, i) for(auto _##i = (t), i = decltype(_##i)(f) poi  i <= _##i poi  i++)
#define uptil(f, t, i) for(auto _##i = (t), i = decltype(_##i)(f) poi  i < _##i poi  i++)
#define downto(f, t, i) for(auto i = (f), _##i = decltype(i)(t) poi  i >= _##i poi  i--)
#define downtil(f, t, i) for(auto i = (f), _##i = decltype(i)(t) poi  i > _##i poi  i--)

#define unless(c) if(!(c))
#define until(c) while(!(c))
#define loop while(true)

#define poi ;
#define poipoi << "\n"

/*#define do {*/
#define end }

#define val const auto
#define var auto

#define fuwafuwa(n, c) dokidoki((n) + (c) - 1, c)
#define dokidoki(n, c) ((n) / (c) * (c))

template<class T> bool read(T& t){
    return cin >> t poi
}
template<class T, class...U> bool read(T& t, U&... u){
    unless(cin >> t) return false poi
    return read(u...) poi
}

bool include_word(const string& s, const string& find){
    if(s.size() < find.size()) return false poi
    if(s == find) return true poi
    if(s.substr(0, find.size() + 1) == find + " " || s.substr(s.size() - find.size() - 1) == " " + find) return true poi
    times(s.size() - find.size() - 2, i)
        if(s.substr(i, find.size() + 2) == " " + find + " ") return true poi
    return false poi
}

int main(){
    char c[100] poi
    while(cin.getline(c, 100)){
        string s = c poi
        loop{
            if(include_word(s, "the") || include_word(s, "this") || include_word(s, "that")){
                cout << s poipoi poi
                break;
            }

            for(char& c : s) if('a' <= c && c < 'z') c++poi else if(c == 'z') c = 'a' poi
        }
    }
    return 0 poi
}

C++: #include <iostream>
#include <string.h>
#include <cstdio>
using namespace std;
char str1[82];
char str2[82];
void trans(char *orj,char *dest)
{
    int k=0,len=strlen(orj);
    bool ischk=false;
    for(int y=1;y<=26&&!ischk;y++)
    {
        for(int x=0;x<len;x++)
        {
            if(orj[x]>='a'&&orj[x]<='z')k=orj[x]-'a';
            else if(orj[x]>='A'&&orj[x]<='Z')k=orj[x]-'A';
            k=(k+y)%26;
            if(orj[x]>='a'&&orj[x]<='z')dest[x]='a'+k;
            else if(orj[x]>='A'&&orj[x]<='Z')dest[x]='A'+k;
            else dest[x]=orj[x];
        }
        if(strstr(dest,"the")!=NULL||strstr(dest,"this")!=NULL||strstr(dest,"that"))ischk=true;
    }

}
int main()
{
    while(gets(str1))
    {
        memset(str2,'\0',sizeof(str2));
        trans(str1,str2);
        printf("%s\n",str2);
    }
    return 0;
}

C++: #include <cctype>
#include <cstdio>
#include <cstring>

using namespace std;

bool includes_keyword(const char *str) {
  const static char *keywords[] = { "the", "this", "that" };
  for (const auto keyword : keywords) {
    char *pos = strstr(str, keyword);
    if (pos == NULL) { continue; }
    if (pos != str && isalpha(pos[-1])) { continue; }
    if (isalpha(pos[strlen(keyword)])) { continue; }
    return true;
  }
  return false;
}

int main() {
  while (!feof(stdin)) {
    char cipher[81];
    fgets(cipher, 81, stdin);

    size_t len = strlen(cipher);
    if (cipher[len - 1] == '\n') { cipher[len - 1] = '\0'; }

    char c = 'z';
    for (int i = 0; i < len; ++i) {
      if (isalpha(cipher[i]) && c > cipher[i]) { c = cipher[i]; }
    }
    int shift_begin = 'a' - c;
    int shift_end = shift_begin + 26;
    char decoded[81];
    for (int shift = shift_begin; shift < shift_end; ++shift) {
      strcpy(decoded, cipher);
      for (int i = 0; i < len; ++i) {
        if (isalpha(decoded[i])) { decoded[i] += shift; }
      }
      if (includes_keyword(decoded)) { break; }
    }

    puts(decoded);
  }

  return 0;
}

C++: //#define _USE_MATH_DEFINES
//#include <cmath>
#include <iostream>
//#include <stdio.h>
//#include <stdlib.h>
//#include <iomanip>
#include <vector>
#include <string>
//#include <algorithm>
//#include <functional>
//#include <time.h>
#include <sstream>

using namespace std;


int main(){

	string s,sc, buf;
	stringstream ss;
	vector <string> as;
	int dif = 0;


	while (getline(cin, s)){
		sc += s;
		for (int i = 0; i < sc.size(); i++){
			if (sc[i] == '.')sc[i] = ' ';
		}
		ss << sc;

		while (ss >> buf){
			//the this that???????´¢
			if (buf.size() == 3){
				if ((buf[0] - buf[1]) == 12 && (buf[0] - buf[2]) == 15){
					dif = buf[0] - 't';
					break;
				}
			}
			else if (buf.size() == 4){
				if ((buf[0] - buf[1]) == 12 && (buf[0] - buf[2]) == 11 && (buf[0] - buf[3]) == 1){
					dif = buf[0] - 't';
					break;
				}
				if ((buf[0] - buf[1]) == 12 && (buf[0] - buf[2]) == 19 && (buf[0] - buf[3]) == 0){
					dif = buf[0] - 't';
					break;
				}
			}
		}

		for (int i = 0; i < s.size(); i++){
			if (s[i] >= 'a' && s[i] <= 'z') {
				s[i] -= dif;
				if (s[i] < 'a') s[i] += 26;
				if (s[i] > 'z') s[i] -= 26;
			}
		}

		cout << s << endl;
	}




	return 0;
}

C++: #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cassert>
#include<iostream>
#include<sstream>
#include<string>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<utility>
#include<numeric>
#include<algorithm>
#include<bitset>
#include<complex>

using namespace std;

typedef long long Int;
typedef vector<int> vint;
typedef pair<int,int> pint;
#define mp make_pair

template<class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cout << *i << " "; cout << endl; }
template<class T> void chmin(T &t, T f) { if (t > f) t = f; }
template<class T> void chmax(T &t, T f) { if (t < f) t = f; }
int in() { int x; scanf("%d", &x); return x; }

int main() {
	string str;
	for(;getline(cin,str);){
		int len=str.size();
		int i,c;
		for(c=1;c<=26;c++){
			for(i=0;i<len;i++){
				if('a'<=str[i]&&str[i]<='z'){
					str[i]++;
					if(str[i]>'z')str[i]='a';
				}
			}
			//cout<<str<<endl;
			if(str.find("the")!=string::npos||str.find("this")!=string::npos||str.find("that")!=string::npos){
				cout<<str<<endl;
				break;
			}
		}
	}
	return 0;
}

C++: #include <algorithm>
#include <iostream>
#include <cstdio>
#include <map>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <string.h>
using namespace std;

#define ISEQ(c) (c).begin(), (c).end()
typedef long long ll;

int main() {
  char s[90];
  while (fgets(s, 81, stdin) != 0) {
    for (int i = 0; i < 26; i++) {
      for (int j = 0; j < strlen(s); j++) {
	if (isalpha(s[j])) {
	  if (s[j] == 'z') s[j] = 'a';
	  else s[j]++;
	}
      }
      if (strstr(s, "the") != NULL or strstr(s, "this") != NULL or strstr(s, "that") != NULL) break;
    }
    printf("%s", s);
  }
}