#define _CRT_SECURE_NO_WARNINGS
#define ll long long
#define vi vector<int>
#define LLMAX 4000000000000000000LL
#include <bits/stdc++.h>
#include <unordered_set>
using namespace std;
struct edge
{
	int t, f, w;
	bool operator < (const edge& e) const
	{
		return w > e.w;
	}
	edge(int from, int to, int weight)
	{
		t = to;
		f = from;
		w = weight;
	}
};
#define pll pair<ll,ll>
#define ii pair<int,int>
#define vii vector<ii>
#define vvi vector<vi>
const double EPS = (1e-9);
/*typedef complex<double> Point;
//#define X real() 
//#define Y imag() 
#define angle(a)                (atan2((a).imag(), (a).real()))
#define vec(a,b)                ((b)-(a))
#define same(p0,p1)             (dp(vec(p0,p1),vec(p0,p1)) < EPS)
#define dp(a,b)                 ( (conj(a)*(b)).real() )	// a*b cos(T), if zero -> prep
#define cp(a,b)                 ( (conj(a)*(b)).imag() )	// a*b sin(T), if zero -> parllel
#define length(a)               (hypot((a).imag(), (a).real()))
#define normalize(a)            (a)/length(a)
#define polar(r,ang)            ((r)*exp(point(0,ang)))
#define rotateO(p,ang)          ((p)*exp(point(0,ang)))
#define rotateA(p,ang,about)  	(rotateO(vec(about,p),ang)+about)
//#define x first
//#define y second
typedef complex<double> point;
int dcmp(double a, double b) { return fabs(a - b) <= EPS ? 0 : a < b ? -1 : 1; }
// Constant PI for providing angles in radians
struct Double {
	double d;
	Double() { d = 0.0; };
	Double(double d) : d(d) {}
	bool operator < (const Double& D) const {
		return dcmp(d, D.d) < 0;
	}
	bool operator > (const Double& D) const {
		return dcmp(d, D.d) > 0;
	}
	bool operator == (const Double& D) const {
		return dcmp(d, D.d) == 0;
	}
};
bool intersectSegments(point a, point b, point c, point d, point& intersect) {
	double d1 = cp(a - b, d - c), d2 = cp(a - c, d - c), d3 = cp(a - b, a - c);
	if (fabs(d1) < EPS)
		return false;  // Parllel || identical

	double t1 = d2 / d1, t2 = d3 / d1;
	intersect = a + (b - a) * t1;

	if (t1 < -EPS || t2 < -EPS || t2 > 1 + EPS)
		return false;  //e.g ab is ray, cd is segment ... change to whatever
	return true;
}*/
class UnionFind {                                              // OOP style
public:
	vi p, rank, setSize;                       // remember: vi is vector<int>
	int numSets;
	UnionFind(int N) {
		setSize.assign(N, 1); numSets = N; rank.assign(N, 0);
		p.assign(N, 0); for (int i = 0; i < N; i++) p[i] = i;
	}
	int findSet(int i) { return (p[i] == i) ? i : (p[i] = findSet(p[i])); }
	bool isSameSet(int i, int j) { return findSet(i) == findSet(j); }
	void unionSet(int i, int j) {
		if (!isSameSet(i, j)) {
			numSets--;
			int x = findSet(i), y = findSet(j);
			// rank is used to keep the tree short
			if (rank[x] > rank[y]) { p[y] = x; setSize[x] += setSize[y]; }
			else {
				p[x] = y; setSize[y] += setSize[x];
				if (rank[x] == rank[y]) rank[y]++;
			}
		}
	}
	int numDisjointSets() { return numSets; }
	int sizeOfSet(int i) { return setSize[findSet(i)]; }
};
ll root(ll x) {
	ll l = 0, r = 1e9 + 1;
	while (l < r - 1) {
		ll m = (l + r) / 2;
		if (m * m > x)
			r = m;
		else
			l = m;
	}
	return l;
}
struct line {
	double a, b, c;
};
bool areParallel(line l1, line l2) { // check coefficients a & b
	return (fabs(l1.a - l2.a) < EPS) && (fabs(l1.b - l2.b) < EPS);
}
bool areSame(line l1, line l2) { // also check coefficient c
	return areParallel(l1, l2) && (fabs(l1.c - l2.c) < EPS);
}
struct point {
	double x, y;
	point() { x = y = 0.0; }
	point(double _x, double _y) : x(_x), y(_y) {}
	bool operator < (point other) const { // override less than operator
		if (fabs(x - other.x) > EPS) // useful for sorting
			return x < other.x; // first criteria , by x-coordinate
		return y < other.y;
	}
};
void pointsToLine(point p1, point p2, line& l) {
	if (fabs(p1.x - p2.x) < EPS) { // vertical line is fine
		l.a = 1.0; l.b = 0.0; l.c = -p1.x; // default values
	}
	else {
		l.a = -(double)(p1.y - p2.y) / (p1.x - p2.x);
		l.b = 1.0; // IMPORTANT: we fix the value of b to 1.0
		l.c = -(double)(l.a * p1.x) - p1.y;
	}
}
bool areIntersect(line l1, line l2, point& p) {
	if (areParallel(l1, l2)) return false; // no intersection
	// solve system of 2 linear algebraic equations with 2 unknowns
	p.x = (l2.b * l1.c - l1.b * l2.c) / (l2.a * l1.b - l1.a * l2.b);
	// special case: test for vertical line to avoid division by zero
	if (fabs(l1.b) > EPS) p.y = -(l1.a * p.x + l1.c);
	else p.y = -(l2.a * p.x + l2.c);
	return true;
}
long long binpowmod(long long a, long long b, long long m){a %= m;long long res = 1;while (b > 0){if (b & 1)res = res * a % m;a = a * a % m;b >>= 1;}return res;}
long long binpow(long long a, long long b){long long res = 1;while (b > 0){if (b & 1)res = res * a;a = a * a;b >>= 1;}return res;}
int findXOR(int n){switch (n % 4){case 0:return n;case 1:return 1;case 2:return n + 1;case 3:return 0;}}
int rangeXOR(int l, int r){return (findXOR(l - 1) ^ findXOR(r));}
int getbit(int mask, int bit){return (mask & (1 << bit));}void setbit(int& mask, int bit, int val){if (val)mask |= (1 << bit);else mask &= ~(1 << bit);}
//ll gcd(ll a, ll b){return b == 0 ? a : gcd(b, a % b);}
//ll lcm(ll a, ll b){return a * (b / gcd(a, b));}
#define sz(a) int(a.size())
//#pragma GCC target ("sse4.2")
const int N = 1e5 + 10;
const int M = 500+10;
const ll INF = 1e7 + 100;
#define PI acos(-1)
#define pb push_back
#define all(s) s.begin(),s.end()
#define rall(s) s.rbegin(),s.rend()
typedef double long dl;
#define MOD1 1e8
#define MOD int(1e9) + 7
//#ifdef _MSC_VER
//#  include <intrin.h>
//#  define __builtin_popcount __popcnt
//#endif
/*vector<ll> seg;
vector<ll> a;
vector<ll> lazy;
ll build(int s, int e, int p = 1)
{
	if (s == e)
		return seg[p] = a[s];
	int m = (s + e) >> 1;
	int np = (p << 1);
	return seg[p] = build(s, m, np) + build(m + 1, e, np + 1);
}
ll update(int ind, int val, int s, int e, int p = 1)
{
	if (s == e)
		return seg[p] = val;
	int m = (s + e) >> 1;
	int np = (p << 1);
	if (ind <= m)
		return seg[p] = update(ind, val, s, m, np) + seg[np + 1];
	else
		return seg[p] = update(ind, val, m + 1, e, np + 1) + seg[np];

}
ll query(int l, int r, int s, int e, int p = 1)
{
	int m = (s + e) >> 1;
	int np = (p << 1);
	if (lazy[p] != 0)
	{
		seg[p] = (e - s + 1ll) * lazy[p];
		if (s != e)
		{
			lazy[np] += lazy[p];
			lazy[np + 1] += lazy[p];
		}
		lazy[p] = 0;
	}
	if (l <= s && e <= r)
		return seg[p];
	if (r <= m)
		return query(l, r, s, m, np);
	if (l > m)
		return query(l, r, m + 1, e, np + 1);
	ll a = query(l, r, s, m, np);
	ll b = query(l, r, m + 1, e, np + 1);
	return a + b;
}
void updateRange(int st, int en, int s, int e, int p = 1)
{
	int m = (s + e) >> 1;
	int np = (p << 1);
	if (lazy[p] != 0)
	{
		seg[p] = (e - s + 1ll) * lazy[p];
		if (s != e)
		{
			lazy[np] += lazy[p];
			lazy[np + 1] += lazy[p];
		}
		lazy[p] = 0;
	}
	if (st < s && en < s || st > e&& en > e)
		return;
	if (s >= st  && e <= en)
	{
		seg[p] += (e - s + 1ll);
		if (s != e)
		{
			lazy[np] += 1;
			lazy[np + 1] += 1;
		}
		return;
	}
	updateRange(st, en, s, m, np);
	updateRange(st, en, m + 1, e, np + 1);
	seg[p] = seg[np] + seg[np + 1];
}
void radixsort(vector<pair<ii, int>>& a)
{
	int n = sz(a);
	{
		vi cnt(n);
		for (auto x : a)
			cnt[x.first.second]++;
		vector<pair<ii, int>> a_new(n);
		vi pos(n);
		pos[0] = 0;
		for (int i = 1; i < n; ++i)
			pos[i] = pos[i - 1] + cnt[i - 1];
		for (auto x : a)
		{
			int i = x.first.second;
			a_new[pos[i]] = x;
			pos[i]++;
		}
		a = a_new;
	}
	{
		vi cnt(n);
		for (auto x : a)
			cnt[x.first.first]++;
		vector<pair<ii, int>> a_new(n);
		vi pos(n);
		pos[0] = 0;
		for (int i = 1; i < n; ++i)
			pos[i] = pos[i - 1] + cnt[i - 1];
		for (auto x : a)
		{
			int i = x.first.first;
			a_new[pos[i]] = x;
			pos[i]++;
		}
		a = a_new;
	}
}
void count_sort(vi& p, vi& c, int k)
{
	int n = sz(p);
	vi cnt(n);
	for (auto x : c)
		cnt[x]++;
	vi p_new(n);
	vi pos(n);
	pos[0] = 0;
	for (int i = 1; i < n; ++i)
		pos[i] = pos[i - 1] + cnt[i - 1];
	for (auto x : p)
	{
		x = (x - (1 << k) + n) % n;
		int i = c[x];
		p_new[pos[i]] = x;
		pos[i]++;
	}
	p = p_new;
}*/
bool isGood(char x)
{
	string t = "ACGT";
	for (int i = 0; i < 4; ++i)
		if (x == t[i])
			return true;
	return false;
}
void solve()
{
	string s;
	cin >> s;
	string t = "ACGT";
	int n = sz(s);
	int mx = 0;
	for (int i = 0; i < n; ++i)
	{
		int c = 0;
		while (i < n && isGood(s[i]))
		{
			c++;
			i++;
		}
		mx = max(mx, c);
	}
	cout << mx << '\n';
}
int main(void)
{
	//sieve();
	//freopen("jumping.in", "r", stdin);
	//freopen("output.txt", "w", stdout);
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	int tc = 1;
	//cin >> tc;
	//scanf("%d", &tc);
	while (tc--)
	{
		solve();
		//if (tc)
			//cout << '\n';
	}
}

Measured memory_bytes: 3596