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++: #define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdio.h>
#include <string>
#include <vector>
using namespace std;

int main() {
	char s[100] = {};
	while (fgets(s,sizeof(s),stdin)) {
		int start = 0, ofs=0,ofs2,chk=1;
		char buf;
		for (int i = 0; s[i] != '\n'; i++) {
			if (s[i] == ' ' || s[i] == '.') {
				if (i - start == 3) {
					chk = 1;
					ofs2 = (int)'t' - (int)s[start];
					for (int j = 1; j < 3; j++) {
						buf = s[start + j] + ofs2;
						if (buf > 'z')
							buf -= 26;
						if (buf < 'a')
							buf += 26;
						if (j == 1 && buf != 'h') {
							chk = 0;
							break;
						}
						if (j == 2 && buf != 'e')
							chk = 0;
					}
					if (chk == 1) {
						ofs = ofs2;
						break;
					}
				}
				if (i - start == 4){
					chk = 1	;
					ofs2 = (int)'t' - (int)s[start];
					for (int j = 1; j < 4; j++) {
						buf = s[start + j] + ofs2;
						if (buf > 'z')
							buf -= 26;
						if (buf < 'a')
							buf += 26;
						if (j == 1 && buf != 'h') {
							chk = 0;
							break;
						}
						if (j == 2 && buf == 'a')
							chk = 2;
						if (j == 2 && buf == 'i')
							chk = 3;
						if (j == 2 && buf != 'i'&&buf != 'a') {
							chk = 0;
							break;
						}
						if (j == 3 && chk == 2) {
							if (buf == 't')
								chk = 1;
							else {
								chk = 0;
								break;
							}
						}
						if (j == 3 && chk == 3) {
							if (buf == 's')
								chk = 1;
							else {
								chk = 0;
								break;
							}
						}
					}
					if (chk == 1) {
						ofs = ofs2;
						break;
					}
				}
				start = i + 1;
			}
		}
		for (int i = 0; s[i] != '\n'; i++) {
			if (s[i] != ' '&& s[i]!='.') {
				s[i] += ofs;
				if (s[i] > 'z')
					s[i] -= 26;
				if (s[i] < 'a')
					s[i] += 26;
			}
		}
		cout << s;
	}
	return 0;
}

C++: #include <iostream>
#include <string.h>
#include <sstream>
#include <ctype.h>
using namespace std;

string com[3] = {"the", "this", "that"};

string incAlpha (string str, int k) {
    for (int i = 0; i < str.size(); i++) {
        if(isalpha(str[i])) str[i] = ((str[i] + k - 'a') % 26) + 'a'; 
    }
    return str;
}

bool strsrch(string str1, string str2) {
    for (int i = 0; i < str1.size(); i++) {
        if (str1[i] == str2[0]) {
            bool flag = true;
            if (i + str2.size() > str1.size()) flag = false;
            for (int j = 0; j < str2.size() && flag; j++) {
                if (str1[i + j] != str2[j]) flag = false;
            }
            if (flag) return true;
        }
    }

    return false;
}

bool check (string str) {
    for (int i = 0; i < 3; i++) {
        if (strsrch(str, com[i])) return true;
    }
    return false;
}

int main ()
{
    string str;
    while (getline(cin, str)) {
        for (int i = 0; i <= 26; i++) {
            if (check((incAlpha(str, i)))) {
                cout << (incAlpha(str, i)) << endl;
                break;
            }
        }
    }

    return 0;
}

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

bool howMuchWords(string s, string key){
  string::size_type index = s.find(key);
  if(index == string::npos){
    return false;
  }else{
    //???????????£???.
    return true;
  }
}
    

int main(){
  string s;
  int cnt=0;

  while(getline(cin, s)){
    while(true){
      bool flag=false;
      for(int i=0;i<s.length();i++){
	string key1 = s.substr(i,3);
	string key2 = s.substr(i,4);
	if(key1 == "the" || key2 == "this" || key2 == "that"){
	  flag = true;
	  break;
	}
      }
      
      if(flag){
	cout << s << endl;
	continue;
      }
    
      for(int i=0;i<s.length();i++){
	if(s[i] > 'a' && s[i] < 'z'){
	  s[i] -= 'a';
	  s[i] -= 1;
	  if(s[i] < 0){
	    s[i] += 'A' - 'a';
	  }
	  s[i] += 'a';
	}
      }
    }
  }
}

C++: #include "bits/stdc++.h"

using namespace std;

typedef vector<int> vi;
typedef pair<int,int> pii;
typedef long long ll;

#define dump(x)  cerr << #x << " = " << (x) << endl
#define rep(i,n) for(int i=0;i<(n);i++)
#define all(a)  (a).begin(),(a).end()
#define pb push_back

char sub(char ch){
	if(ch=='a')return 'z';
	else return ch-1;
}


bool solve(string s){
	string tmp="";
	rep(i,s.size()){
		if(isalpha(s[i])){
			tmp+=s[i];
		}
		else{

			if( tmp=="the" || tmp=="this" || tmp=="that" )return true;

			tmp="";
		}
	}
	return false;
}

int main(){
	string s;
	getline(cin,s);
	while(1){
		rep(i,s.size()){
			if(isalpha(s[i]))s[i]=sub(s[i]);
		}
		if(solve(s))break;
	}
	cout<<s<<endl;
}

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

using namespace std;

int main()
{
  string temp,mainstr;
  
  while(getline(cin,mainstr)){
    temp = mainstr;
    vector<string> str;
    int i,j,k,judge,gosuu=0;
    
    //入力を単語ごとに分割
    i=0;
    while(1){
      int index;
      index = temp.rfind(" ");
      
      if (index==-1){
	str.push_back(temp.substr(index+1));
	temp = temp.substr(0,temp.size()-str[i].size()-1);
	gosuu++;
	break;
      }else{
	str.push_back(temp.substr(index+1));
	temp = temp.substr(0,temp.size()-str[i].size()-1);
	gosuu++;
	i++;
      } 
    }
    
    //単語からピリオドを取り除く
    for(i=0;i<gosuu;i++){
      if (str[i].find(".")!=-1)
	str[i] = str[i].substr(0,str[i].size()-1);
    }
    
    //単語を変換してチェックしていく
    for(i=0;i<gosuu;i++){
      k=1;
      while(1){
	judge = 1;
	
	//単語を1個ずらしたものに変換、このときtを過ぎてたらもうだめ
	for(j=0;j<str[i].size();j++){
	  str[i][j] -= 1;
	  if (str[i][j] < 'a'){
	    judge = 0;
	    break;
	  }
	}

	if (judge == 0) break;
	
	if ((str[i]=="this")||(str[i]=="that")||(str[i]=="the"))break;
	k++;
	
      }
      if (judge==1) break;
    }
    
    //文章の変換
    
    for(i=0;i<mainstr.size();i++){
      if ((mainstr[i]!=' ')&&(mainstr[i]!='.'))
	mainstr[i] -= k;
    }
    
    //変換した文字の出力
    cout << mainstr <<endl;
    
    /*
    for(i=0;i<str.size();i++){
      cout << str[i] <<endl;
    }*/
    
  }

  return 0;
}