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>
using namespace std;

int main(void)
{
	string str;
	
	while (getline(cin, str)){
		string res;
		for (int i = 0; i < 26; i++){
			for (int j = 0; j < str.size(); j++){
				if (str[j] != ' ' && str[j] != '.') res += (str[j] -'a' + i ) % 26 + 'a';
				else res += str[j];
			}
//			cout << i + 1 << " " << res << endl;
			if (res.find("this") != -1){
				cout << res << endl;
				break;
			}
			if (res.find("the") != -1){
				cout << res << endl;
				break;
			}
			if (res.find("that") != -1){
				cout << res << endl;
				break;
			}
			res.clear();
		}
	}
	
	return 0;
}

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

typedef long long int ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<pair<int, int> > vii;
#define rrep(i, m, n) for(int (i)=(m); (i)<(n);  (i)++)
#define erep(i, m, n) for(int (i)=(m); (i)<=(n); (i)++)
#define  rep(i, n)    for(int (i)=0; (i)<(n);  (i)++)
#define rrev(i, m, n) for(int (i)=(n)-1; (i)>=(m); (i)--)
#define erev(i, m, n) for(int (i)=(n); (i)>=(m); (i)--)
#define  rev(i, n)    for(int (i)=(n)-1; (i)>=0; (i)--)
#define vrep(i, c)    for(__typeof((c).begin())i=(c).begin(); i!=(c).end(); i++)
#define  ALL(v)       (v).begin(), (v).end()
#define mp            make_pair
#define pb            push_back
template<class T, class S> inline bool minup(T& m, S x){ return m>(T)x ? (m=(T)x, true) : false; }
template<class T, class S> inline bool maxup(T& m, S x){ return m<(T)x ? (m=(T)x, true) : false; }

const int    INF = 1000000000;
const ll     MOD = 1000000007LL;
const double EPS = 1E-12;

template<typename T> ostream& operator << (ostream& r, const vector<T> t){vrep(v,t)r<<*v<<(v+1==t.end()?"":" ");return r;}
template<typename T> ostream& operator << (ostream& r, const pair<vector<T>, int> p){int n=p.second;minup(n,p.first.size());rep(i,n-1)r<<p.first[i]<<' ';r<<p.first[n-1];return r;}
template<typename T> ostream& operator << (ostream& r, const pair<T*, int> p){int n=p.second-1;rep(i,n)r<<p.first[i]<<' ';return r<<p.first[n];}
template<typename T, size_t S> ostream& operator << (ostream& r, const T (&a)[S]){rep(i,S-1)r<<a[i]<<' ';return r<<a[S-1];}

string str;

int main()
{
  while(getline(cin, str)){
    vector<string> s;
    istringstream stream(str);
    while(getline(stream, str, ' ')) s.pb(str);
    bool ok = false;
    rep(k, 26){
      vrep(v, s) rep(i, v->size()) if((*v)[i] >= 'A' && (*v)[i] <= 'z') (*v)[i] = 'a' + ((*v)[i] + 1) % 26;
      vrep(v, s) if(*v == "the" || *v == "this" || *v == "that") ok = true;
      if(ok){
        cout << s << endl;
        break;
      }
    }
  }

 return 0;
}

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

using namespace std;

int main(){
	
	char c[2000];
	
	bool checker;
	
	while(true){
		
		gets(c);
		
		if(c[0] == EOF){
			break;
		}
		
		for(int i = 0; i < 26; i++){
			for(int j = 0; j < 2000; j++){
				if(c[j] == '\0'){
					break;
				}else if(c[j] == 'z'){
					c[j] = 'a';
				}else if(c[j] == ' '){
					c[j] = ' ';
				}else if(c[j] == '.'){
					c[j] = '.';
				}else{
					c[j]++;
				}
			}
			
			checker = false;
			
			for(int j = 0; j < 2000; j++){
				if(c[j] == '\0'){
					break;
				}
				if(c[j] == 't' && c[j + 1] == 'h'){
					if(c[j + 2] == 'e'){
						checker = true;
						break;
					}else if(c[j + 2] == 'i' && c[j + 3] == 's'){
						checker = true;
						break;
					}else if(c[j + 2] == 'a' && c[j + 3] == 't'){
						checker = true;
						break;
					}
				}
			}
			
			if(checker){
				break;
			}
		}
		
		for(int i = 0; i < 2000; i++){
			if(c[i] == '\0'){
				break;
			}
			cout << c[i];
		}
		cout << endl;
	}
	
	return 0;
}

C++: //Vol0 0017
#include<stdio.h>
#include<string.h>
#include<ctype.h>
int main()
{
	char s[128];
	int i,j,k;
	int c;
	while((gets(s))!=NULL){
		c=1;
		for(i=0;i<26;i++){
			for(j=0;j<strlen(s);j++){
				if(isalpha(s[j])){
					if(s[j]=='z'){
						s[j]='a';
					}else{
						s[j]++;
					}
				}
			}
			for(k=0;k<strlen(s)-1;k++){
				if((s[k]=='t')&&(s[k+1]=='h')){
					if(c){
						c=0;
						printf("%s\n",s);
					}
				}
			}
		}
	}
	return 0;
}

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

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

C++: #include<stdio.h>
#include<string.h>

int main(){
	char s[85];
	int i;
	memset(s,'0',sizeof(s));
	while(fgets(s,83,stdin)){

		while(1){
			for(i=0;i<81;i++){
				switch(s[i]){
				case '.':
				case ' ':
				case '0':
				case '\0':
				case 10:
				case 13:
					continue;
				}
				s[i]='a'+(s[i]-'a'+1)%26;
			}
			if((NULL!=strstr(s,"the")) || (NULL!=strstr(s,"this")) || (NULL!=strstr(s,"that"))){
				printf("%s",s);
				memset(s,'0',sizeof(s));
				break;
			}
		}
	}
	return 0;
}

C++: #include <bits/stdc++.h>

using namespace std;

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

C++: #include <bits/stdc++.h>

using namespace std;

void f(string &s)
{
    for (char &c : s) {
        if ('a' <= c && c <= 'z') c = (c - 'a' + 25) % 26 + 'a';
    }
}

int main()
{
    string s;

    while (getline(cin, s)) {
        if (s.empty()) break;
        while (s.find("the") == string::npos && s.find("this") == string::npos && s.find("that") == string::npos) f(s);
        cout << s << endl;
    }
}