Go: package main

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

var scanner = bufio.NewScanner(os.Stdin)

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 scanner.Scan() {
		infos := strings.Split(scanner.Text(), " ")
		plain := make([]string, len(infos))
		// fmt.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 <algorithm>
#include <math.h>
#include <vector>
#include <set>

using namespace std;
typedef long long LL;
static const double EPS = 1e-9;

#define FOR(i,k,n) for (int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n) 
void decode(vector<string> &words)
{
  int s=0;
  REP(i,words.size()){
    REP(j,26){
      REP(k,words[i].size()){
        if(words[i][k] >= 'a' && words[i][k] <= 'z' )
        words[i].replace(k, 1, 1,
              'a' + ( words[i][k] + 1 - 'a')%26 );
        
        if(words[i] == "the"||words[i] == "this" || words[i] == "that" ||
           words[i] == "the." || words[i] == "this." || words[i] == "that." )
          s = j;
      }
    }
  }
  REP(i,words.size())
    REP(j,words[i].size())
      if(words[i][j] >= 'a' && words[i][j] <= 'z' )
        words[i].replace(j, 1, 1, 'a' + (words[i][j] + s+1 - 'a')%26 );
}

int main(void){  
  vector<string> words;
  string bf;

  while(true){
    if(!(cin >> bf)) break;
    words.push_back(bf);
    int c = getchar();
    if(c=='\n'){
      decode(words);
      cout << words[0];
      FOR(i,1,words.size())
        cout << " " << words[i];
      cout << endl;
      words.clear();
    }
  }
  return 0;
}

C++: #include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main(void){
        string a;

        while(getline(cin,a)){

            for(int i=0;i<26;i++){
                if(a.find("the")!=string::npos||a.find("this")!=string::npos||a.find("that")!=string::npos){
                    cout<<a<<endl;break;
                }
                else
                    for(int i=0;i<a.length();i++){
                        if(a[i]>='a'&&a[i]<='y')a[i]++;
                        else if(a[i]=='z')a[i]='a';
                    }
            }
        }
    return 0;
}

C++: #include<cstdio>
#include<cctype>
#include<cstring>
char str[1000000] = {0};
using namespace std;
int main(){
    int f = 0;
    while(scanf("%[^\n]",str)!=EOF){
        getchar();
        for(int i = 0;i <= 25; i++){
            for(int j = 0;j < strlen(str); j++){
                if(str[j] == ' ' || str[j] == '.')continue;
                str[j]++;
                if(str[j] > 122)str[j] = str[j]-26;
            }
            for(int j = 0;j < strlen(str); j++){
                if(str[j] == 't' && str[j+1] == 'h' && str[j+2] == 'e')goto hoge;
                if(str[j] == 't' && str[j+1] == 'h' && str[j+2] == 'i' && str[j+3] == 's')goto hoge;
                if(str[j] == 't' && str[j+1] == 'h' && str[j+2] == 'a' && str[j+3] == 't')goto hoge;
            }
        }
        for(int i = 0;i < strlen(str); i++){
            if(str[i] == ' ' || str[i] == '.')continue;
            str[i] -= 25;
        }
        for(int i = 0;i <= 25; i++){
            for(int j = 0;j < strlen(str); j++){
                if(str[j] == ' ' || str[j] == '.')continue;
                str[j]--;
                if(str[j] < 97)str[j] = str[j]+25;
            }
            for(int j = 0;j < strlen(str); j++){
                if(str[j] == 't' && str[j+1] == 'h' && str[j+2] == 'e')goto hoge;
                if(str[j] == 't' && str[j+1] == 'h' && str[j+2] == 'i' && str[j+3] == 's')goto hoge;
                if(str[j] == 't' && str[j+1] == 'h' && str[j+2] == 'a' && str[j+3] == 't')goto hoge;
            }
        }
        hoge:
        printf("%s\n",str);
        memset(str,0,sizeof(str));
    }
    return 0;
}

C++: #include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <string>
#include <algorithm>
#include <string>
#include <climits>
#include <iomanip>
#include <utility>

#define REP(i, n) for (int (i) = 0; (i) < (int)(n); (i)++)
#define REG(i, a, b) for (int (i) = ((int)(a)); (i) < ((int)(b)); i++)
#define ALL(V) (V).begin(), (V).end()
#define PRINT(STR) cout << (STR) << endl
#define DEBUG(X) cerr << X << " (" << __LINE__ << ", " << __func__ << " )" << endl;

typedef long long ll;
using namespace std;

int main() {
	cin.tie(0); //?????±?????????????????????
	ios::sync_with_stdio(false); //printf??¨??±??????????????????
	string str;
	while (getline(cin, str)) {
		for (int i = 0; i <= 26; i++) {
			string newstr = str;
			for (int j = 0; j < str.size(); j++) {
				if ('a' <= newstr[j] && newstr[j] <= 'z') {
					newstr[j] = str[j] + i;
					if (newstr[j] > 'z') {
						newstr[j] -= 'z';
						newstr[j] += 'a';
					}
				}
			}
			//cerr << newstr << endl;
			if (newstr.find("the", 0) != string::npos ||
					newstr.find("this", 0) != string::npos ||
					newstr.find("that", 0) != string::npos) {
				cout << newstr << endl;
				break;
			}
		}
	}
	return 0;
}

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

bool find(string str, string can) {
  string tmp_can = ' ' + can + ' ';
  string tmp_str = ' ' + str + ' ';
  for (int i = 0; i < tmp_str.length(); ++i) {
    if (string::npos != tmp_str.find(tmp_can, i)) {
      return true;
    }
  }
  return false;
}

int main() {
  string str;
  string candies[] = {"this", "the", "that"};
  while(getline(cin, str)) {
  for (int m = 0; m < 25; ++m) {
    for (int i = 0; i < str.length(); ++i) {
      if (str[i] == ' ') {
        continue;
      }
      if (str[i] == ',' || str[i] == '.') {
        str[i] = ' ';
        continue;
      }
      int char_id = static_cast<int>(str[i]) - 97;
      int shifted = static_cast<int>(char_id + 1);
      str[i] = static_cast<char>(shifted % 26 + 97);
    }
    cout << str << endl;
    for (int i = 0; i < sizeof(candies) / sizeof(candies[0]); ++i) {
      if (find(str, candies[i])) {
        cout << "!!!" << endl;
        break;
      }
    }
  }
  }
  return 0;
}

C++: #include<string>
#include<vector>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<sstream>
#include<functional>
#include<map>
#include<stack>
#include<set>
#include<cmath>

#define REP(i,s,e) for(int i=int(s);i<=int(e);i++)
#define rep(i,n) for(int i=0;i<int(n);i++)

#define EPS 1e-6

using namespace std;

bool f(string a){

	string::size_type p=a.find("the");
	string::size_type q=a.find("this");
	string::size_type r=a.find("that");
	if(p!=string::npos || q!=string::npos || r!=string::npos)
	return true;
	else return false;

	}

int main(){

   string s,s1;

   while(getline(cin,s)){


	int n=s.size();

	rep(k,26){
	s1=s;
	rep(i,n){

	if('a'<=s1[i] && s1[i]<='z'-k) s1[i]+=k;
	if(k!=0 && 'z'+1-k<=s1[i] && s1[i]<='z') s1[i]+=k-26;
	}

	if(f(s1)){ cout << s1 << endl; break; }

	}


	}


    return 0;
}