<p>Given a string <code>queryIP</code>, return <code>&quot;IPv4&quot;</code> if IP is a valid IPv4 address, <code>&quot;IPv6&quot;</code> if IP is a valid IPv6 address or <code>&quot;Neither&quot;</code> if IP is not a correct IP of any type.</p>

<p><strong>A valid IPv4</strong> address is an IP in the form <code>&quot;x<sub>1</sub>.x<sub>2</sub>.x<sub>3</sub>.x<sub>4</sub>&quot;</code> where <code>0 &lt;= x<sub>i</sub> &lt;= 255</code> and <code>x<sub>i</sub></code> <strong>cannot contain</strong> leading zeros. For example, <code>&quot;192.168.1.1&quot;</code> and <code>&quot;192.168.1.0&quot;</code> are valid IPv4 addresses while <code>&quot;192.168.01.1&quot;</code>, <code>&quot;192.168.1.00&quot;</code>, and <code>&quot;192.168@1.1&quot;</code> are invalid IPv4 addresses.</p>

<p><strong>A valid IPv6</strong> address is an IP in the form <code>&quot;x<sub>1</sub>:x<sub>2</sub>:x<sub>3</sub>:x<sub>4</sub>:x<sub>5</sub>:x<sub>6</sub>:x<sub>7</sub>:x<sub>8</sub>&quot;</code> where:</p>

<ul>
	<li><code>1 &lt;= x<sub>i</sub>.length &lt;= 4</code></li>
	<li><code>x<sub>i</sub></code> is a <strong>hexadecimal string</strong> which may contain digits, lowercase English letter (<code>&#39;a&#39;</code> to <code>&#39;f&#39;</code>) and upper-case English letters (<code>&#39;A&#39;</code> to <code>&#39;F&#39;</code>).</li>
	<li>Leading zeros are allowed in <code>x<sub>i</sub></code>.</li>
</ul>

<p>For example, &quot;<code>2001:0db8:85a3:0000:0000:8a2e:0370:7334&quot;</code> and &quot;<code>2001:db8:85a3:0:0:8A2E:0370:7334&quot;</code> are valid IPv6 addresses, while &quot;<code>2001:0db8:85a3::8A2E:037j:7334&quot;</code> and &quot;<code>02001:0db8:85a3:0000:0000:8a2e:0370:7334&quot;</code> are invalid IPv6 addresses.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> queryIP = &quot;172.16.254.1&quot;
<strong>Output:</strong> &quot;IPv4&quot;
<strong>Explanation:</strong> This is a valid IPv4 address, return &quot;IPv4&quot;.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> queryIP = &quot;2001:0db8:85a3:0:0:8A2E:0370:7334&quot;
<strong>Output:</strong> &quot;IPv6&quot;
<strong>Explanation:</strong> This is a valid IPv6 address, return &quot;IPv6&quot;.
</pre>

<p><strong class="example">Example 3:</strong></p>

<pre>
<strong>Input:</strong> queryIP = &quot;256.256.256.256&quot;
<strong>Output:</strong> &quot;Neither&quot;
<strong>Explanation:</strong> This is neither a IPv4 address nor a IPv6 address.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>queryIP</code> consists only of English letters, digits and the characters <code>&#39;.&#39;</code> and <code>&#39;:&#39;</code>.</li>
</ul>

class Solution {
public:
    bool isNumeric(string &str) {
        for (char c : str) {
            if (c < '0' || c > '9') {
                return false;
            }
        }
        return true;
    }

    bool ipv4(string queryIP) {
        vector<string> v;
        int n = queryIP.size();
        string temp = "";

        for (int i = 0; i < n; i++) {
            if (queryIP[i] == '.') {
                // Handle case where there's a trailing dot or multiple dots in a row
                if (temp.empty() || temp.size()>4) return false;
                v.push_back(temp);
                temp = "";
            } 
            else if (queryIP[i] >= '0' && queryIP[i] <= '9') {
                temp += queryIP[i];
            } 
            else return false;  // Invalid character
        }

        // Handle last segment
        if (temp.empty()) return false;
        v.push_back(temp);

        // Check for exactly 4 segments
        if (v.size() != 4) return false;

        for (auto segment : v) {
            // Check for valid segment length and range
            if (segment.size() > 1 && segment[0] == '0') return false;  // No leading zeros allowed
            
            if (!isNumeric(segment)) return false;  // Must be numeric
            int num = stoi(segment);
            if (num < 0 || num > 255) return false;  // Must be in the range [0, 255]
        }

        return true;
    }

    bool ipv6(string queryIP) {
        vector<string> v;
        int n = queryIP.size();
        string temp = "";

        for (int i = 0; i < n; i++) {
            if (queryIP[i] == '.') return false;

            if (queryIP[i] == ':' || i == n - 1) {
                if (i == n - 1 && queryIP[i] == ':') return false;
                
                if (i == n - 1 && queryIP[i] != ':') {
                    temp += queryIP[i];
                }
                if (temp.empty()) return false;  // Empty segment (e.g., "::" without collapse)
                v.push_back(temp);
                temp = "";
            } else {
                temp += queryIP[i];
            }
        }

        if (v.size() != 8) return false;

        for (const string& segment : v) {
            if (segment.size() > 4 || segment.size() == 0) return false;
            
            for (char j : segment) {
                if (!isdigit(j) && !(j >= 'A' && j <= 'F') && !(j >= 'a' && j <= 'f')) {
                    return false;
                }
            }
        }

        return true;
    }

    string validIPAddress(string queryIP) {
        int n=queryIP.size();
        for(auto i:queryIP){
            if(i=='.'){
                bool f=ipv4(queryIP);
                if(f) return "IPv4";
                return "Neither";
            }
            if(i==':'){
                bool f=ipv6(queryIP);
                if(f) return "IPv6";
                return "Neither";

            }
        }
        return "Neither";
    }
};

8000