Go: package main

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

var scanner = bufio.NewScanner(os.Stdin)

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

func incrementByte(b byte) byte {
	if b >= 97 && b < 122 {
		return b + 1
	} else if b == 122 {
		return 97
	}
	return b
}

func main() {
	scanner.Split(bufio.ScanLines)

	for {
		line := nextString()
		if len(line) == 0 {
			break
		}
		for i := 0; i <= 26; i++ {
			decoded := []byte{}
			for j := 0; j < len(line); j++ {
				decoded = append(decoded, incrementByte(line[j]))
			}
			line = string(decoded)
			if strings.Contains(line, "the") || strings.Contains(line, "this") || strings.Contains(line, "that") {
				fmt.Println(line)
				break
			}
		}
	}
}

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;
    }
    cout << s << endl;
  }
}

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) {
    const 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);
      puts(decoded);
      for (int i = 0; i < len; ++i) {
        if (isalpha(decoded[i])) { decoded[i] += shift; }
      }
      if (includes_keyword(decoded)) {
        puts(decoded);
        goto FINISH;
      }
    }
  }

FINISH:
  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;
vector<string> res;

int main()
{
  while(cin >> str) res.pb(str);

  bool ok = false;
  rep(k, 26){
    vrep(v, res) rep(i, v->size()) if((*v)[i] >= 'a' && (*v)[i] <= 'z') (*v)[i] = 'a' + ((*v)[i] + 1) % 26;
    vrep(v, res) if(*v == "the" || *v == "this" || *v == "that") ok = true;
    if(ok){
      cout << res << endl;
      break;
    }
  }

  /*
  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<string>
#define num 27
using namespace std;

int main(){
	int i;
	string str;
	getline(cin, str);
	string strcp = str;
	string::iterator si;
	for(i=0;i<num;i++){
		if(  strcp.find("this") != string::npos
		  || strcp.find("that") != string::npos
		  || strcp.find("the" ) != string::npos){
			cout << strcp << endl;
		}
		si = strcp.begin();
		while(si != strcp.end()){
			if('a' <= *si && *si <= 'y'){
				*si = *si + 1;
			}else if(*si == 'z'){
				*si = 'a';
			}
			si++;
		}
	}
	return 0;
}

C++: #include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<set>
#include<queue>
#include<string>
#include<vector>
#include<map>
#include<stack>
#include<list>
using namespace std;
#define inf 0x3f3f3f3f

char d[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
char s[110000];
char t[110000];
int main(){
	
	char c;
	int i=0;
	while(c=getchar()){
		if(c==EOF){
			s[i]='\0';
			break;
		}
		s[i++] = c;
	}
	int l = strlen(s),j,k,m;
	for(i=0;i<=26;i++){
		for(j=0;j<l-1;j++){
			if(s[j]>='a'&&s[j]<='z'){
				t[j] = d[(s[j]-'a'+i)%26];
			}
			else t[j] =s[j];
		}
		int a=0,b=0,c=0;
		for(j=0;j<l-3;j++){
			if(t[j]=='t'&&t[j+1]=='h'){
				if(t[j+2]=='e'&&!(t[j+3]>='a' && t[j+3]<='z')){
					a++;
				}
				if(t[j+2]=='i'&&t[j+3]=='s'&&!(t[j+4]>='a'&&t[j+4]<='z')){
					b++;
				}
				if(t[j+2]=='a'&&t[j+3]=='t'&&!(t[j+4]>='a'&&t[j+4]<='z')){
					c++;
				}
			}
		}
		if(a||b||c)break;
	}
	for(j=0;j<l-1;j++){
		if(s[j]>='a'&&s[j]<='z'){
			printf("%c",d[(s[j]-'a'+i)%26]);
		}
		else printf("%c",s[j]);
	}
	puts("");
	return 0;
}