#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <string.h> // strcmp()

#define REP(i, b, e) for (size_t i = b; i < e; ++i)

bool compare_str(const char* s1, const char* s2)
{
	return strcmp(s1, s2) < 0;
}

void make_suffix_array(const std::string& s, std::vector<const char*>& v)
{
	v.resize(s.size());

	REP(i, 0, s.size())
	{
		v[i] = s.c_str() + i;
	}

	std::sort(v.begin(), v.end(), compare_str);
}

typedef std::vector<const char*>::const_iterator Iter;

void skip_empty_string(Iter& beg, Iter end, size_t depth)
{
	while (beg != end && (*beg)[depth] == '\0')
	{
		++beg;
	}
}

void find_range(Iter& beg, Iter& end, size_t depth, char c)
{
	while (beg != end && (*beg)[depth] < c)
	{
		++beg;
	}

	Iter cur = beg;

	while (cur != end && (*cur)[depth] == c)
	{
		++cur;
	}

	end = cur;
}

void traverse(Iter beg1, Iter end1, Iter beg2, Iter end2, size_t depth, size_t& max_depth)
{
	skip_empty_string(beg1, end1, depth);

	skip_empty_string(beg2, end2, depth);

	while (beg1 != end1 && beg2 != end2)
	{
		const char c = (*beg1)[depth];

		Iter the_beg1 = beg1, the_end1 = end1;

		find_range(the_beg1, the_end1, depth, c);

		Iter the_beg2 = beg2, the_end2 = end2;

		find_range(the_beg2, the_end2, depth, c);

		if (the_beg1 != the_end1 && the_beg2 != the_end2)
		{
			max_depth = std::max(max_depth, depth + 1);

			traverse(the_beg1, the_end1, the_beg2, the_end2, depth + 1, max_depth);
		}

		beg1 = the_end1;

		beg2 = the_end2;
	}
}

int main()
{
	std::string s1, s2;

	std::getline(std::cin, s1);

	std::getline(std::cin, s2);

	std::vector<const char*> v1, v2;

	make_suffix_array(s1, v1);

	make_suffix_array(s2, v2);

	size_t max_depth = 0;

	traverse(v1.begin(), v1.end(), v2.begin(), v2.end(), 0, max_depth);

	std::cout << max_depth << std::endl;
}

